import os
import json
from datetime import datetime, timedelta
from typing import List, Optional

from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

# ReportLab imports
from reportlab.lib.pagesizes import A4
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, HRFlowable, Table, TableStyle, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

app = FastAPI()

# Root route to serve index.html from public folder
@app.get("/")
async def read_root():
    index_path = os.path.join("public", "index.html")
    if os.path.exists(index_path):
        return FileResponse(index_path)
    return {"message": "index.html not found in public/ folder"}

# Allow CORS for wheel.bytwok.com and local development
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://wheel.bytwok.com",
        "http://wheel.bytwok.com",
        "http://localhost:3000",
        "*"
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Ensure generated directory exists inside public/static for direct web serving
PDF_DIR = os.path.join("public", "static")
os.makedirs(PDF_DIR, exist_ok=True)
app.mount("/static", StaticFiles(directory=PDF_DIR), name="static")

CUSTOMERS_FILE = "customers.json"
PI_COUNTER_FILE = "counter_pi.json"
CONTRACT_COUNTER_FILE = "counter_contract.json"

# Font Registration (Windows & Linux Support for cPanel)
FONT_NAME = "Helvetica"
possible_font_paths = [
    "C:/Windows/Fonts/msyh.ttc",                      # Windows Microsoft YaHei
    "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", # Common Linux
    "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"     # Linux Fallback
]

for font_path in possible_font_paths:
    if os.path.exists(font_path):
        try:
            pdfmetrics.registerFont(TTFont('ChineseFont', font_path, subfontIndex=0))
            FONT_NAME = 'ChineseFont'
            break
        except Exception as e:
            print(f"Font loading warning ({font_path}): {e}")


def save_customer_profile(data: dict):
    key = data.get("company_reg_no") or data.get("company_name")
    if not key:
        return
    
    customers = {}
    if os.path.exists(CUSTOMERS_FILE):
        with open(CUSTOMERS_FILE, "r", encoding="utf-8") as f:
            try:
                customers = json.load(f)
            except Exception:
                customers = {}

    customers[key] = data
    with open(CUSTOMERS_FILE, "w", encoding="utf-8") as f:
        json.dump(customers, f, ensure_ascii=False, indent=2)

@app.get("/api/customers")
def get_saved_customers():
    if os.path.exists(CUSTOMERS_FILE):
        with open(CUSTOMERS_FILE, "r", encoding="utf-8") as f:
            try:
                return json.load(f)
            except Exception:
                return {}
    return {}


def get_next_pi_number():
    counter = 1
    if os.path.exists(PI_COUNTER_FILE):
        with open(PI_COUNTER_FILE, "r") as f:
            try:
                counter = json.load(f).get("last_number", 0) + 1
            except Exception:
                counter = 1
    with open(PI_COUNTER_FILE, "w") as f:
        json.dump({"last_number": counter}, f)
    return f"By26-{counter:04d}"

def get_next_contract_number():
    date_str = datetime.now().strftime("%Y%m%d")
    counter = 1
    if os.path.exists(CONTRACT_COUNTER_FILE):
        with open(CONTRACT_COUNTER_FILE, "r") as f:
            try:
                counter = json.load(f).get("last_number", 0) + 1
            except Exception:
                counter = 1
    with open(CONTRACT_COUNTER_FILE, "w") as f:
        json.dump({"last_number": counter}, f)
    return f"ZS-LS-{date_str}-{counter:04d}"


class CartItem(BaseModel):
    model: str
    size: str
    unit_price: float
    quantity: int

class CustomerDetails(BaseModel):
    company_name: str
    company_reg_no: Optional[str] = ""
    tax_id: Optional[str] = ""
    address: str
    tel: Optional[str] = ""
    mobile_whatsapp: Optional[str] = ""
    email: str
    website: Optional[str] = ""
    pic_name: str
    pic_whatsapp: Optional[str] = ""
    pic_email: Optional[str] = ""

class OrderPayload(BaseModel):
    customer: CustomerDetails
    items: List[CartItem]
    doc_type: str


@app.post("/api/create-doc")
async def create_document(order: OrderPayload):
    save_customer_profile(order.customer.model_dump())
    total_amount = sum(item.unit_price * item.quantity for item in order.items)

    if order.doc_type == "quotation":
        doc_no = get_next_pi_number()
        pdf_filename = f"{doc_no}.pdf"
        pdf_path = os.path.join(PDF_DIR, pdf_filename)
        generate_pi_pdf(pdf_path, doc_no, order, total_amount)
    else:
        doc_no = get_next_contract_number()
        pdf_filename = f"{doc_no}.pdf"
        pdf_path = os.path.join(PDF_DIR, pdf_filename)
        generate_contract_pdf(pdf_path, doc_no, order, total_amount)

    return {
        "status": "success",
        "doc_no": doc_no,
        "total_amount": round(total_amount, 2),
        "pdf_url": f"https://wheel.bytwok.com/static/{pdf_filename}"
    }


def generate_pi_pdf(filepath, doc_no, order, total):
    doc = SimpleDocTemplate(filepath, pagesize=A4, rightMargin=36, leftMargin=36, topMargin=36, bottomMargin=36)
    story = []
    styles = getSampleStyleSheet()

    title_style = ParagraphStyle('Title', parent=styles['Heading1'], fontName=FONT_NAME, fontSize=15, textColor=colors.HexColor("#0284c7"))
    normal_style = ParagraphStyle('NormalText', parent=styles['Normal'], fontName=FONT_NAME, fontSize=8.5, leading=12)

    story.append(Paragraph("GENUINE WHEELS CO., LTD.", title_style))
    story.append(Paragraph("123 Industrial Park, Kuala Lumpur | Web: wheel.bytwok.com", normal_style))
    story.append(HRFlowable(width="100%", thickness=1.5, color=colors.HexColor("#0284c7"), spaceAfter=10))

    issue_date = datetime.now()
    valid_until = issue_date + timedelta(days=7)

    story.append(Paragraph("<b>PROFORMA INVOICE / QUOTATION</b>", ParagraphStyle('Sub', parent=styles['Heading2'], fontName=FONT_NAME, fontSize=12)))
    story.append(Paragraph(f"<b>Document No:</b> {doc_no}", normal_style))
    story.append(Paragraph(f"<b>Issue Date:</b> {issue_date.strftime('%Y-%m-%d')} | <b>Valid Until (7 Days):</b> {valid_until.strftime('%Y-%m-%d')}", normal_style))
    story.append(Spacer(1, 8))

    cust = order.customer
    cust_info = f"""
    <b>BUYER DETAILS / 客户详细信息:</b><br/>
    <b>Company Name:</b> {cust.company_name}<br/>
    <b>ROC / Reg No:</b> {cust.company_reg_no or 'N/A'} | <b>Tax ID / TIN:</b> {cust.tax_id or 'N/A'}<br/>
    <b>Address:</b> {cust.address}<br/>
    <b>Tel / Landline:</b> {cust.tel or 'N/A'} | <b>Mobile/WhatsApp:</b> {cust.mobile_whatsapp or 'N/A'}<br/>
    <b>Email:</b> {cust.email} | <b>Website:</b> {cust.website or 'N/A'}<br/>
    <b>Person In Charge (PIC):</b> {cust.pic_name} | <b>PIC WhatsApp:</b> {cust.pic_whatsapp or 'N/A'} | <b>PIC Email:</b> {cust.pic_email or 'N/A'}
    """
    story.append(Paragraph(cust_info, normal_style))
    story.append(Spacer(1, 10))

    table_data = [["Model", "Size", "Unit Price", "Qty", "Total (USD)"]]
    for item in order.items:
        table_data.append([
            str(item.model), str(item.size), f"${item.unit_price:,.2f}", str(item.quantity), f"${(item.unit_price * item.quantity):,.2f}"
        ])
    table_data.append(["", "", "", "Grand Total:", f"${total:,.2f}"])

    item_table = Table(table_data, colWidths=[120, 100, 100, 80, 120])
    item_table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor("#0284c7")),
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
        ('FONTNAME', (0, 0), (-1, -1), FONT_NAME),
        ('FONTSIZE', (0, 0), (-1, -1), 8),
        ('GRID', (0, 0), (-1, -2), 0.5, colors.HexColor("#cbd5e1")),
        ('ALIGN', (2, 0), (-1, -1), 'RIGHT'),
    ]))
    story.append(item_table)
    story.append(Spacer(1, 10))

    disclaimer = """
    <b>TERMS & CONDITIONS / 条款细则:</b><br/>
    1. <b>Validity:</b> This quotation is strictly valid for <b>7 days</b> from the date of issue.<br/>
    2. <b>Price Adjustment Notice:</b> Prices quoted herein are subject to market fluctuations and may be revised or modified <b>with or without prior notice</b> prior to final confirmation and receipt of deposit.
    """
    story.append(Paragraph(disclaimer, normal_style))

    doc.build(story)


def generate_contract_pdf(filepath, contract_no, order, total):
    doc = SimpleDocTemplate(filepath, pagesize=A4, rightMargin=36, leftMargin=36, topMargin=36, bottomMargin=36)
    story = []
    styles = getSampleStyleSheet()

    h1_style = ParagraphStyle('ContractH1', parent=styles['Heading1'], fontName=FONT_NAME, fontSize=13, leading=16, textColor=colors.HexColor("#0f172a"))
    h2_style = ParagraphStyle('ContractH2', parent=styles['Heading2'], fontName=FONT_NAME, fontSize=10, leading=13, textColor=colors.HexColor("#0284c7"), spaceBefore=8, spaceAfter=4)
    body_style = ParagraphStyle('ContractBody', parent=styles['Normal'], fontName=FONT_NAME, fontSize=8, leading=11, textColor=colors.HexColor("#334155"))

    today_str = datetime.now().strftime("%Y年%m月%d日")
    cust = order.customer

    story.append(Paragraph("销售与购买合同 | SALES AND PURCHASE AGREEMENT", h1_style))
    story.append(Paragraph(f"<b>合同编号 (Contract No):</b> {contract_no} &nbsp;&nbsp;|&nbsp;&nbsp; <b>签署日期 (Date):</b> {today_str}", body_style))
    story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor("#0284c7"), spaceAfter=8))

    story.append(Paragraph("1. 签约主体 | THE PARTIES", h2_style))
    parties_text = f"""
    <b>卖方 / SELLER:</b><br/>
    公司名称: Bytwokworld Network Sdn Bhd<br/>
    地址: Plot 8-1-35, Gat Lebuh Macallum, 10300 Penang, Malaysia.<br/>
    Web: wheel.bytwok.com<br/><br/>
    <b>买方 / BUYER:</b><br/>
    公司名称: {cust.company_name}<br/>
    公司注册号 (ROC No): {cust.company_reg_no or 'N/A'} | 税号 (TIN/Tax ID): {cust.tax_id or 'N/A'}<br/>
    地址: {cust.address}<br/>
    电话 / Tel: {cust.tel or 'N/A'} | WhatsApp / 手机: {cust.mobile_whatsapp or 'N/A'} | 邮箱: {cust.email}<br/>
    负责人 (PIC): {cust.pic_name} ({cust.pic_whatsapp or 'N/A'} | {cust.pic_email or 'N/A'})<br/><br/>
    <b>指定收款代理（非签署第三方）/ DESIGNATED PAYMENT AGENT:</b><br/>
    公司名称: Shandong Zhuosheng Metal Products Co., Ltd<br/>
    USCI / 统一社会信用代码: 91440605MACHPDXA87<br/>
    地址: 山东省聊城经济技术开发区星光国际金融中心10号楼
    """
    story.append(Paragraph(parties_text, body_style))

    story.append(Paragraph("2. 交易详情 | TRANSACTION DETAILS", h2_style))
    table_data = [["Item 品名", "Specifications 规格", "Quantity 数量", "Unit Price 单价", "Total Amount 总价"]]
    for item in order.items:
        table_data.append([
            item.model, item.size, str(item.quantity), f"USD {item.unit_price:,.2f}", f"USD {(item.unit_price * item.quantity):,.2f}"
        ])
    table_data.append(["", "", "", "Grand Total:", f"USD {total:,.2f}"])

    tx_table = Table(table_data, colWidths=[120, 110, 70, 100, 120])
    tx_table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor("#f1f5f9")),
        ('FONTNAME', (0, 0), (-1, -1), FONT_NAME),
        ('FONTSIZE', (0, 0), (-1, -1), 8),
        ('GRID', (0, 0), (-1, -2), 0.5, colors.HexColor("#cbd5e1")),
        ('ALIGN', (2, 0), (-1, -1), 'RIGHT'),
    ]))
    story.append(tx_table)

    story.append(Paragraph("3. 强化的第三方收款代理免责条款 | EXTENDED AGENT DISCLAIMER", h2_style))
    story.append(Paragraph("Absolute Immunity: The Agent is strictly a fund facilitator and is NOT liable for product purity, weight, delivery, or any trade breach.", body_style))

    story.append(Paragraph("4. 价格变动与有效期限 | PRICE REVISION & VALIDITY", h2_style))
    story.append(Paragraph("<b>Price Modification:</b> Quoted prices are subject to raw material and exchange rate fluctuations and may change <b>with or without prior notice</b> prior to contract execution and deposit receipt.", body_style))

    story.append(Paragraph("5. 管辖法律 | GOVERNING LAW", h2_style))
    story.append(Paragraph("This Agreement shall be governed by the laws of <b>SINGAPORE</b>. Any disputes shall be submitted to the SIAC.", body_style))
    story.append(Spacer(1, 10))

    sig_data = [
        [
            Paragraph("<b>卖方 (SELLER):</b><br/><br/>______________________<br/>Bytwokworld Network Sdn Bhd", body_style),
            Paragraph(f"<b>买方 (BUYER):</b><br/><br/>______________________<br/>{cust.company_name}", body_style)
        ]
    ]
    sig_table = Table(sig_data, colWidths=[260, 260])
    story.append(KeepTogether([
        Paragraph("6. 签署栏 | SIGNATURES", h2_style),
        sig_table
    ]))

    doc.build(story)