"""Professional PDF generation for agent applications — receipts & certificates.

All timestamps are rendered in Bangladesh Standard Time (UTC+6).
"""
import io
from typing import Optional
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image,
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT
from reportlab.pdfgen import canvas

from bd_time import fmt_bd, fmt_bd_long, now_bd_str

# ── Brand palette (kept consistent with site)
EMERALD = colors.HexColor("#10B981")
EMERALD_DARK = colors.HexColor("#059669")
NAVY = colors.HexColor("#0A1119")
NAVY_LIGHT = colors.HexColor("#111C2A")
SLATE_50 = colors.HexColor("#F8FAFC")
SLATE_100 = colors.HexColor("#F1F5F9")
SLATE_200 = colors.HexColor("#E2E8F0")
SLATE_300 = colors.HexColor("#CBD5E1")
SLATE_400 = colors.HexColor("#94A3B8")
SLATE_500 = colors.HexColor("#64748B")
SLATE_600 = colors.HexColor("#475569")
SLATE_900 = colors.HexColor("#0F172A")
RED = colors.HexColor("#EF4444")
RED_BG = colors.HexColor("#FEF2F2")
AMBER = colors.HexColor("#F59E0B")
AMBER_BG = colors.HexColor("#FEF3C7")
EMERALD_BG = colors.HexColor("#ECFDF5")
BLUE = colors.HexColor("#3B82F6")
BLUE_BG = colors.HexColor("#EFF6FF")

STATUS_THEME = {
    "approved":        {"color": EMERALD, "bg": EMERALD_BG, "label": "APPROVED",         "stamp": "VERIFIED AGENT"},
    "paid":            {"color": BLUE,    "bg": BLUE_BG,    "label": "PAID · IN REVIEW", "stamp": "UNDER REVIEW"},
    "rejected":        {"color": RED,     "bg": RED_BG,     "label": "REJECTED",         "stamp": "NOT APPROVED"},
    "pending_payment": {"color": AMBER,   "bg": AMBER_BG,   "label": "PENDING PAYMENT",  "stamp": "AWAITING PAYMENT"},
}


def _network_label(pc: Optional[str]) -> str:
    return {
        "usdtbsc":   "USDT · BEP-20 (Binance Smart Chain)",
        "usdttrc20": "USDT · TRC-20 (Tron)",
    }.get((pc or "").lower(), (pc or "—").upper())


def _on_page(site_name: str, status_label: str):
    """Page draw callback — adds subtle watermark + footer page number."""
    def draw(canv: canvas.Canvas, doc):
        canv.saveState()
        # Diagonal watermark — only first page is enough but reportlab calls every page
        canv.setFont("Helvetica-Bold", 80)
        canv.setFillColor(SLATE_100)
        canv.translate(105 * mm, 150 * mm)
        canv.rotate(35)
        canv.drawCentredString(0, 0, status_label)
        canv.restoreState()

        # Footer bar
        canv.saveState()
        canv.setFillColor(SLATE_400)
        canv.setFont("Helvetica", 7.5)
        canv.drawString(15 * mm, 8 * mm, f"{site_name}  ·  Official Application Document")
        canv.drawRightString(
            195 * mm, 8 * mm,
            f"Page {canv.getPageNumber()}  ·  Generated {now_bd_str('%d %b %Y, %I:%M %p')}",
        )
        canv.setStrokeColor(EMERALD)
        canv.setLineWidth(1.2)
        canv.line(15 * mm, 11 * mm, 195 * mm, 11 * mm)
        canv.restoreState()

    return draw


def build_application_pdf(app: dict, site_name: str = "Maxlife88 Agent Portal") -> bytes:
    """Generate a polished PDF receipt / certificate for an application."""
    buf = io.BytesIO()
    doc = SimpleDocTemplate(
        buf,
        pagesize=A4,
        leftMargin=15 * mm,
        rightMargin=15 * mm,
        topMargin=15 * mm,
        bottomMargin=20 * mm,
        title=f"{site_name} — Application {app.get('id','')[:8]}",
        author=site_name,
    )

    styles = getSampleStyleSheet()
    h1 = ParagraphStyle("h1", parent=styles["Heading1"], fontSize=24, textColor=SLATE_900,
                        spaceAfter=2, leading=28, fontName="Helvetica-Bold")
    h2 = ParagraphStyle("h2", parent=styles["Heading2"], fontSize=11, textColor=EMERALD_DARK,
                        spaceBefore=18, spaceAfter=10, alignment=TA_LEFT,
                        fontName="Helvetica-Bold")
    body = ParagraphStyle("body", parent=styles["Normal"], fontSize=10, textColor=SLATE_600, leading=14)
    sub = ParagraphStyle("sub", parent=styles["Normal"], fontSize=9, textColor=SLATE_400, spaceAfter=12)

    status = (app.get("status") or "pending_payment").lower()
    theme = STATUS_THEME.get(status, STATUS_THEME["pending_payment"])

    story = []

    # ════════════ HERO BAND ════════════
    hero_left = Paragraph(
        f'<para alignment="left">'
        f'<font color="{EMERALD.hexval()}" size="18"><b>● {site_name}</b></font><br/>'
        f'<font color="{SLATE_400.hexval()}" size="9">'
        f'Official Agent Application Document  ·  এজেন্ট আবেদনের অফিসিয়াল ডকুমেন্ট</font>'
        f'</para>',
        body,
    )
    hero_right = Paragraph(
        f'<para alignment="right">'
        f'<font color="{theme["color"].hexval()}" size="10"><b>{theme["label"]}</b></font><br/>'
        f'<font color="{SLATE_400.hexval()}" size="8">Issued {now_bd_str("%d %b %Y, %I:%M %p")}</font>'
        f'</para>',
        body,
    )
    hero = Table([[hero_left, hero_right]], colWidths=[105 * mm, 75 * mm])
    hero.setStyle(TableStyle([
        ("TOPPADDING", (0, 0), (-1, -1), 14),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 14),
        ("LEFTPADDING", (0, 0), (-1, -1), 0),
        ("RIGHTPADDING", (0, 0), (-1, -1), 0),
        ("LINEBELOW", (0, 0), (-1, -1), 2.5, EMERALD),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
    ]))
    story.append(hero)
    story.append(Spacer(1, 18))

    # ════════════ TITLE + STATUS PILL ════════════
    short_id = (app.get("id", "") or "")[:8].upper()
    story.append(Paragraph(
        f"Agent Application <font color=\"{SLATE_300.hexval()}\">·</font> "
        f"<font color=\"{SLATE_900.hexval()}\">#{short_id}</font>", h1
    ))
    story.append(Paragraph(
        f"Full Reference ID: <font face=\"Courier\" color=\"{SLATE_500.hexval()}\">{app.get('id','')}</font>",
        sub,
    ))

    # Big status pill
    pill = Table(
        [[Paragraph(
            f'<para alignment="center">'
            f'<font color="{theme["color"].hexval()}" size="11"><b>● {theme["label"]}</b></font>'
            f'</para>',
            body,
        )]],
        colWidths=[180 * mm],
    )
    pill.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), theme["bg"]),
        ("BOX", (0, 0), (-1, -1), 0.8, theme["color"]),
        ("TOPPADDING", (0, 0), (-1, -1), 9),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 9),
        ("ROUNDEDCORNERS", [4, 4, 4, 4]),
    ]))
    story.append(pill)
    story.append(Spacer(1, 4))

    # ════════════ APPLICANT DETAILS ════════════
    story.append(Paragraph("APPLICANT DETAILS  ·  আবেদনকারীর বিবরণ", h2))
    applicant_rows = [
        ["Full Name", app.get("full_name", "—") or "—"],
        ["Email", app.get("email", "—") or "—"],
        ["Phone", app.get("phone", "—") or "—"],
        ["Username", app.get("username", "—") or "—"],
        ["City / Division", f"{app.get('city') or '—'}, {app.get('state') or '—'}"],
        ["Telegram", f"@{app.get('telegram_username') or '—'}"],
        ["Submitted", fmt_bd_long(app.get("created_at"))],
    ]
    applicant_tbl = Table(applicant_rows, colWidths=[48 * mm, 132 * mm])
    applicant_tbl.setStyle(_kv_table_style())
    story.append(applicant_tbl)

    # ════════════ PAYMENT DETAILS ════════════
    if app.get("payment_id") or app.get("price_amount"):
        story.append(Paragraph("PAYMENT DETAILS  ·  পেমেন্ট বিবরণ", h2))

        price = float(app.get("price_amount") or 0)
        discount = float(app.get("discount_amount") or 0)
        base = float(app.get("base_amount") or (price + discount))

        # Premium price card — dark with emerald accent
        price_card = Table(
            [[
                Paragraph(
                    f'<para alignment="left">'
                    f'<font color="{SLATE_300.hexval()}" size="8" face="Helvetica-Bold"><b>AMOUNT PAID</b></font><br/>'
                    f'<font color="{SLATE_400.hexval()}" size="8">পরিশোধিত পরিমাণ</font>'
                    f'</para>',
                    body,
                ),
                Paragraph(
                    f'<para alignment="right">'
                    f'<font color="{EMERALD.hexval()}" size="30"><b>${price:.2f}</b></font><br/>'
                    f'<font color="{SLATE_400.hexval()}" size="9">{(app.get("pay_currency") or "USDT").upper()}</font>'
                    f'</para>',
                    body,
                ),
            ]],
            colWidths=[80 * mm, 100 * mm],
        )
        price_card.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, -1), NAVY),
            ("TOPPADDING", (0, 0), (-1, -1), 18),
            ("BOTTOMPADDING", (0, 0), (-1, -1), 18),
            ("LEFTPADDING", (0, 0), (-1, -1), 18),
            ("RIGHTPADDING", (0, 0), (-1, -1), 18),
            ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
            ("LINEBELOW", (0, 0), (-1, -1), 3, EMERALD),
        ]))
        story.append(price_card)
        story.append(Spacer(1, 10))

        pay_rows = [["Base Amount", f"${base:.2f} USD"]]
        if discount > 0:
            pay_rows.append([
                "Discount Applied",
                f"−${discount:.2f}  ·  Coupon: {app.get('coupon_code') or '—'}",
            ])
        pay_rows.extend([
            ["Network", _network_label(app.get("pay_currency"))],
            ["Pay Address", app.get("pay_address") or "—"],
            ["Payment ID", app.get("payment_id") or "—"],
            ["Payment Status", (app.get("payment_status") or "—").upper()],
            ["Paid At", fmt_bd_long(app.get("paid_at"))],
        ])
        pay_tbl = Table(pay_rows, colWidths=[48 * mm, 132 * mm])
        pay_tbl.setStyle(_kv_table_style())
        story.append(pay_tbl)

    # ════════════ DECISION ════════════
    if app.get("decided_at") or app.get("rejection_reason") or status in ("approved", "rejected"):
        story.append(Paragraph("REVIEW DECISION  ·  পর্যালোচনার সিদ্ধান্ত", h2))
        decision_rows = [
            ["Outcome", theme["label"]],
            ["Decided At", fmt_bd_long(app.get("decided_at"))],
        ]
        if app.get("rejection_reason"):
            decision_rows.append(["Reason", app.get("rejection_reason")])
        if app.get("admin_notes"):
            notes = app.get("admin_notes") or ""
            decision_rows.append(["Admin Notes", notes[:300] + ("…" if len(notes) > 300 else "")])
        dec_tbl = Table(decision_rows, colWidths=[48 * mm, 132 * mm])
        dec_tbl.setStyle(_kv_table_style(highlight_first_value=theme["color"]))
        story.append(dec_tbl)

    # ════════════ CONGRATULATIONS / NEXT STEPS PANEL ════════════
    if status == "approved":
        story.append(Spacer(1, 16))
        congrats = Table(
            [[Paragraph(
                f'<para alignment="center">'
                f'<font color="{EMERALD_DARK.hexval()}" size="14"><b>✓ Welcome to the Maxlife88 Agent Network</b></font><br/><br/>'
                f'<font color="{SLATE_600.hexval()}" size="10">Your KYC has been verified and your agent account is now active. '
                f'Our manager will reach out via Telegram with your credentials and onboarding details.</font><br/>'
                f'<font color="{SLATE_400.hexval()}" size="9">Maxlife88 এজেন্ট নেটওয়ার্কে স্বাগতম। আপনার KYC যাচাই সম্পন্ন।</font>'
                f'</para>',
                body,
            )]],
            colWidths=[180 * mm],
        )
        congrats.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, -1), EMERALD_BG),
            ("BOX", (0, 0), (-1, -1), 1, EMERALD),
            ("TOPPADDING", (0, 0), (-1, -1), 18),
            ("BOTTOMPADDING", (0, 0), (-1, -1), 18),
            ("LEFTPADDING", (0, 0), (-1, -1), 18),
            ("RIGHTPADDING", (0, 0), (-1, -1), 18),
        ]))
        story.append(congrats)

    # ════════════ AUTHENTICITY FOOTER NOTE ════════════
    story.append(Spacer(1, 22))
    notice = Paragraph(
        f'<para alignment="center">'
        f'<font color="{SLATE_400.hexval()}" size="8">'
        f'This is a system-generated document from <b>{site_name}</b>. '
        f'Verify authenticity using the Application ID at the support portal.<br/>'
        f'এটি একটি স্বয়ংক্রিয় ডকুমেন্ট। সাপোর্ট পোর্টালে Application ID দিয়ে সত্যতা যাচাই করুন।'
        f'</font></para>',
        body,
    )
    story.append(notice)

    doc.build(
        story,
        onFirstPage=_on_page(site_name, theme["stamp"]),
        onLaterPages=_on_page(site_name, theme["stamp"]),
    )
    pdf_bytes = buf.getvalue()
    buf.close()
    return pdf_bytes


def _kv_table_style(highlight_first_value=None) -> TableStyle:
    """Shared key-value table style used across applicant / payment / decision sections."""
    style = TableStyle([
        ("BACKGROUND", (0, 0), (0, -1), SLATE_50),
        ("TEXTCOLOR", (0, 0), (0, -1), SLATE_500),
        ("TEXTCOLOR", (1, 0), (1, -1), SLATE_900),
        ("FONTNAME", (0, 0), (0, -1), "Helvetica-Bold"),
        ("FONTNAME", (1, 0), (1, -1), "Helvetica"),
        ("FONTSIZE", (0, 0), (-1, -1), 9.5),
        ("LEFTPADDING", (0, 0), (-1, -1), 12),
        ("RIGHTPADDING", (0, 0), (-1, -1), 12),
        ("TOPPADDING", (0, 0), (-1, -1), 9),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 9),
        ("LINEBELOW", (0, 0), (-1, -1), 0.4, SLATE_200),
        ("BOX", (0, 0), (-1, -1), 0.4, SLATE_200),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
    ])
    if highlight_first_value is not None:
        style.add("TEXTCOLOR", (1, 0), (1, 0), highlight_first_value)
        style.add("FONTNAME", (1, 0), (1, 0), "Helvetica-Bold")
    return style
