#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
主生成脚本：根据订单信息生成销售合同和Proforma Invoice
"""

import os
import sys
import shutil
import re
from datetime import datetime

# 添加脚本目录到路径
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, script_dir)

from parse_order_info import parse_order_info
from match_vehicle import match_vehicle, build_vehicle_description
from number_to_words import format_say_us_only, calculate_payment_split


def get_asset_path(filename: str) -> str:
    """获取assets目录下的文件路径"""
    return os.path.join(script_dir, '..', 'assets', filename)


def generate_contract_no() -> str:
    """生成合同编号: HLXYWPA{年月日}"""
    return f"HLXYWPA{datetime.now().strftime('%Y%m%d')}"


def format_date() -> str:
    """格式化当前日期"""
    return datetime.now().strftime('%Y-%m-%d')


def format_date_for_cell():
    """Excel单元格日期格式（仅日期，无时间）"""
    from datetime import datetime
    now = datetime.now()
    return datetime(now.year, now.month, now.day)


def translate_port(port_cn: str) -> str:
    """将中文港口名翻译为英文"""
    port_map = {
        '广州南沙': 'Guangzhou nansha Port',
        '广州': 'Guangzhou Port',
        '深圳': 'Shenzhen Port',
        '上海': 'Shanghai Port',
        '天津': 'Tianjin Port',
        '青岛': 'Qingdao Port',
        '宁波': 'Ningbo Port',
        '厦门': 'Xiamen Port',
    }
    for cn, en in port_map.items():
        if cn in port_cn:
            return en
    return port_cn


def process_vehicles(vehicles: list, trade_term: str) -> list:
    """
    处理车型列表，匹配价格表或提示用户提供价格
    
    Returns:
        (processed_vehicles, missing_prices)
        processed_vehicles: 包含单价的车型列表
        missing_prices: 未匹配到价格的车型列表（需用户补充）
    """
    processed = []
    missing = []
    
    for v in vehicles:
        model_code = v.get('model_code', '')
        
        # 如果用户已提供单价，直接使用
        if v.get('unit_price_usd') is not None:
            processed.append(v)
            continue
        
        # 从价格表匹配
        match_result = match_vehicle(model_code, trade_term)
        if match_result and match_result.get('unit_price_usd'):
            v['unit_price_usd'] = match_result['unit_price_usd']
            v['config_desc'] = build_vehicle_description(v, match_result)
            v['_match_result'] = match_result
            processed.append(v)
        else:
            # 未匹配到价格
            missing.append(v)
    
    return processed, missing


def calculate_summary(vehicles: list) -> dict:
    """计算汇总信息"""
    total_qty = sum(v['quantity'] for v in vehicles)
    total_amount = sum(v['unit_price_usd'] * v['quantity'] for v in vehicles)
    
    deposit_30, balance_70 = calculate_payment_split(total_amount)
    
    return {
        'total_qty': total_qty,
        'total_amount': round(total_amount, 2),
        'total_amount_int': round(total_amount),
        'deposit_30': deposit_30,
        'balance_70': balance_70,
        'amount_in_words': format_say_us_only(total_amount),
    }


def generate_proforma_invoice(order: dict, vehicles: list, summary: dict, 
                               contract_no: str, output_dir: str) -> str:
    """生成Proforma Invoice"""
    import openpyxl
    from openpyxl.utils import get_column_letter
    
    # 复制模板
    template_path = get_asset_path('proforma-invoice-template.xlsx')
    output_filename = f"{contract_no}-Proforma Invoice.xlsx"
    output_path = os.path.join(output_dir, output_filename)
    shutil.copy(template_path, output_path)
    
    # 打开并修改
    wb = openpyxl.load_workbook(output_path)
    ws = wb['INVOICE']
    
    # 买方信息
    ws['B7'] = f"TO:  {order.get('buyer_en', '')}"
    ws['G7'] = f"Contract NO.: {contract_no}"
    ws['H8'] = format_date_for_cell()
    ws['B8'] = f"ADD: {order.get('address_en', '')}"
    ws['B9'] = f"Tel: {order.get('tel', '')}"
    
    # 港口信息
    departure_port = translate_port(order.get('departure_port', 'Guangzhou nansha Port'))
    trade_term = order.get('trade_term', 'FCA')
    
    # 商品明细 (B17-H22)
    start_row = 17
    for i, v in enumerate(vehicles):
        row = start_row + i
        if row > 22:
            break  # 模板最多支持到22行
        
        desc = v.get('config_desc') or build_vehicle_description(v, v.get('_match_result'))
        if not desc:
            desc = f"Wuling {v['model_code']}, {v['engine_code']}"
        
        ws.cell(row=row, column=2, value=desc)  # B列: DESCRIPTION
        ws.cell(row=row, column=3, value=v['quantity'])  # C列: QTY
        ws.cell(row=row, column=4, value='UNIT')  # D列
        ws.cell(row=row, column=5, value='USD')  # E列
        ws.cell(row=row, column=6, value=v['unit_price_usd'])  # F列: U.PRICE
        ws.cell(row=row, column=7, value='USD')  # G列
        # H列保留公式 =C*F
    
    # 清除未使用的行（如果车辆少于模板默认行数）
    for row in range(start_row + len(vehicles), 23):
        for col in range(2, 9):
            ws.cell(row=row, column=col, value=None)
    
    # 汇总信息
    ws['E23'] = f"  {trade_term}   {departure_port} "
    ws['B24'] = summary['amount_in_words']
    
    # Delivery terms
    ws['B27'] = f"1. Delivery terms:  {trade_term} {departure_port}  "
    
    # Payment terms
    payment_text = (
        f"3. Payment terms:\n"
        f"1. 30% of the Total Amount (USD {summary['deposit_30']:,}) shall be paid to Seller within 5 working days from order confirmation.\n"
        f"2. 70% of the Total Amount (USD {summary['balance_70']:,}) shall be paid to Seller within 10 working days before delivery.     "
    )
    ws['B29'] = payment_text
    
    wb.save(output_path)
    wb.close()
    
    return output_path


def generate_sales_contract(order: dict, vehicles: list, summary: dict,
                            contract_no: str, output_dir: str) -> str:
    """生成销售合同 (Word)"""
    from docx import Document
    from docx.shared import Pt
    
    # 复制模板
    template_path = get_asset_path('vehicle-sales-contract-template.docx')
    output_filename = f"{contract_no}-车辆销售合同.docx"
    output_path = os.path.join(output_dir, output_filename)
    shutil.copy(template_path, output_path)
    
    # 打开并修改
    doc = Document(output_path)
    
    departure_port = translate_port(order.get('departure_port', 'Guangzhou nansha Port'))
    trade_term = order.get('trade_term', 'FCA')
    
    # 1. 替换段落文本
    for para in doc.paragraphs:
        text = para.text
        if not text:
            continue
        
        # 合同编号
        if 'No.:' in text and not re.search(r'No\.:\s*\S', text):
            para.text = text.replace('No.:', f'No.: {contract_no}')
        
        # 签署日期
        if 'Signature Date:' in text and not re.search(r'Signature Date:\s*\d', text):
            para.text = text.replace('Signature Date:', f'Signature Date: {format_date()}')
        
        # 买方英文
        if text.strip() == 'Buyer:':
            para.text = f"Buyer: {order.get('buyer_en', '')}"
        
        # 买方中文
        if text.strip() == '买方：':
            para.text = f"买方：{order.get('buyer_cn', '')}"
        
        # 英文地址 (注意模板中使用 \xa0 不间断空格)
        if re.search(r'ADD\s*[:：]', text) and len(text.strip()) < 10:
            para.text = f"ADD: {order.get('address_en', '')}"
        
        # 中文地址
        if re.search(r'地址\s*[:：]', text) and len(text.strip()) < 10:
            para.text = f"地址：{order.get('address_cn', '')}"
        
        # 电话
        if text.strip() == 'Tel电话:':
            para.text = f"Tel电话: {order.get('tel', '')}"
        
        # 出口目的地
        if 'Export Destination:' in text:
            para.text = f"Export Destination:  {order.get('destination_country', '')}"
        
        # 贸易条款
        if 'Incoterms:' in text:
            para.text = f"Incoterms: {trade_term} {departure_port}"
        
        # 付款条款
        if '30% of the Total Amount' in text and 'shall be paid' in text:
            para.text = (
                f"30% of the Total Amount shall be paid to the Seller by T/T before the production. "
                f"70% of the Total Amount shall be paid to the Seller by the Buyer by means of T/T before the delivery of vehicles."
            )
        
        # 付款条款中文
        if '生产前，买方向卖方通过电汇支付' in text:
            para.text = (
                f"生产前，买方向卖方通过电汇支付本合同项下30% 货款。"
                f"发运前，买方向卖方通过电汇支付本合同项下70% 货款。"
            )
    
    # 2. 替换表格内容
    for table in doc.tables:
        # 判断表格类型：车辆明细表 或 银行账户表
        first_cell_text = table.rows[0].cells[0].text.strip() if table.rows else ''
        
        if 'DESCRIPTION' in first_cell_text or '货物描述' in first_cell_text:
            # 车辆明细表 (Table0)
            _fill_vehicle_table(table, vehicles, summary, trade_term, departure_port)
        
        # 银行账户表保持原样（Table1）
        # 商标表保持原样（Table2）
    
    doc.save(output_path)
    return output_path


def _fill_vehicle_table(table, vehicles, summary, trade_term, departure_port):
    """填充销售合同中的车辆明细表"""
    # 表头行通常是第0行
    # 数据行从第1行开始
    # 汇总行需要找到包含 "Total" 或 "总数量" 的行
    
    data_start_row = 1
    
    # 填充车辆数据
    for i, v in enumerate(vehicles):
        row_idx = data_start_row + i
        if row_idx >= len(table.rows):
            break
        
        row = table.rows[row_idx]
        desc = v.get('config_desc') or build_vehicle_description(v, v.get('_match_result'))
        if not desc:
            desc = f"Wuling {v['model_code']}, {v['engine_code']}"
        
        # 描述单元格 (通常是第0列)
        if len(row.cells) > 0:
            row.cells[0].text = f"Model: {v['model_code']}, {v['engine_code']}\n\nColor: {v.get('color', '1')}"
        
        # 数量 (第1列)
        if len(row.cells) > 1:
            row.cells[1].text = str(v['quantity'])
        
        # 单价 (第2列)
        if len(row.cells) > 2:
            row.cells[2].text = str(v['unit_price_usd'])
        
        # 金额 (第3列)
        if len(row.cells) > 3:
            row.cells[3].text = str(v['unit_price_usd'] * v['quantity'])
    
    # 清空多余的数据行（如果车辆数少于模板默认行数）
    for row_idx in range(data_start_row + len(vehicles), len(table.rows)):
        row = table.rows[row_idx]
        # 检查是否是汇总行
        if any('Total' in cell.text or '总数量' in cell.text or 'SAY USD' in cell.text for cell in row.cells):
            # 填充汇总行
            total_text = (
                f"Total: {summary['total_qty']} units  总数量: {summary['total_qty']} 辆    \n"
                f"Total Amount:  USD {summary['total_amount']:.2f}  总金额: 美元 {summary['total_amount']:.2f}\n"
                f" (Say USD: {summary['amount_in_words'].replace('SAY US ', '').replace(' only', '')}  ONLY)\n"
                f"（合计美元：美元整）\n"
                f"{trade_term}  {departure_port}    {trade_term}  {departure_port}"
            )
            for cell in row.cells:
                cell.text = total_text
            break
        else:
            # 清空非汇总行
            for cell in row.cells:
                cell.text = ''


def generate_contracts(order_text: str, output_dir: str = '.', 
                        user_prices: dict = None) -> dict:
    """
    主函数：根据订单文本生成合同
    
    Args:
        order_text: 订单信息文本
        output_dir: 输出目录
        user_prices: 用户手动提供的价格 {model_code: price}
    
    Returns:
        {
            'pi_path': str,
            'contract_path': str,
            'contract_no': str,
            'summary': dict,
            'missing_prices': list,
        }
    """
    # 1. 解析订单
    order = parse_order_info(order_text)
    
    # 2. 生成合同编号
    contract_no = generate_contract_no()
    
    # 3. 处理车型价格
    vehicles = order.get('vehicles', [])
    trade_term = order.get('trade_term', 'FCA')
    
    # 应用用户提供的价格
    if user_prices:
        for v in vehicles:
            if v['model_code'] in user_prices:
                v['unit_price_usd'] = user_prices[v['model_code']]
    
    processed, missing = process_vehicles(vehicles, trade_term)
    
    # 如果有缺失价格，返回提示信息
    if missing:
        return {
            'success': False,
            'missing_prices': missing,
            'message': f"以下车型在价格表中未找到，请提供单价USD: {[v['model_code'] for v in missing]}",
        }
    
    # 4. 计算汇总
    summary = calculate_summary(processed)
    
    # 5. 生成文件
    os.makedirs(output_dir, exist_ok=True)
    
    pi_path = generate_proforma_invoice(order, processed, summary, contract_no, output_dir)
    contract_path = generate_sales_contract(order, processed, summary, contract_no, output_dir)
    
    return {
        'success': True,
        'contract_no': contract_no,
        'pi_path': pi_path,
        'contract_path': contract_path,
        'summary': summary,
        'missing_prices': [],
    }


if __name__ == '__main__':
    import argparse
    
    parser = argparse.ArgumentParser(description='Generate export contracts from order info')
    parser.add_argument('order_file', help='Path to order info text file')
    parser.add_argument('-o', '--output', default='.', help='Output directory')
    parser.add_argument('-p', '--prices', help='JSON string of manual prices {"LZW1028SPY": 6176}')
    
    args = parser.parse_args()
    
    with open(args.order_file, 'r', encoding='utf-8') as f:
        order_text = f.read()
    
    user_prices = None
    if args.prices:
        import json
        user_prices = json.loads(args.prices)
    
    result = generate_contracts(order_text, args.output, user_prices)
    
    import json as json_mod
    sys.stdout.reconfigure(encoding='utf-8')
    print(json_mod.dumps(result, ensure_ascii=False, indent=2))
