#!/usr/bin/env python3
"""
InvoiceEZ PDF Generator
Generates professional quote/invoice PDFs using reportlab.
Called by InvoiceEZ_PDF::generate() with a JSON data file.
"""

import sys
import json
from datetime import datetime

try:
    from reportlab.lib.pagesizes import letter
    from reportlab.lib import colors
    from reportlab.lib.units import inch
    from reportlab.pdfgen import canvas
except ImportError:
    import subprocess
    subprocess.run([sys.executable, '-m', 'pip', 'install', 'reportlab', '--break-system-packages', '-q'])
    from reportlab.lib.pagesizes import letter
    from reportlab.lib import colors
    from reportlab.lib.units import inch
    from reportlab.pdfgen import canvas

def hex_to_color(hex_str):
    return colors.HexColor(hex_str)

def format_currency(amount):
    return '${:,.2f}'.format(float(amount))

def format_date(date_str):
    if not date_str:
        return ''
    try:
        d = datetime.strptime(date_str[:10], '%Y-%m-%d')
        return d.strftime('%B %d, %Y')
    except:
        return date_str

def generate_pdf(data_file):
    with open(data_file, 'r') as f:
        data = json.load(f)

    q        = data['quote']
    items    = data['items']
    s        = data['settings']
    pdf_path = data['pdf_path']

    accent   = hex_to_color(s.get('accent_color', '#0b2559'))
    w, h     = letter
    c        = canvas.Canvas(pdf_path, pagesize=letter)

    # ── Header bar ──
    c.setFillColor(accent)
    c.rect(0, h - 120, w, 120, fill=1, stroke=0)

    # Logo
    logo_path = s.get('logo_path', '')
    if logo_path and __import__('os').path.exists(logo_path):
        try:
            c.drawImage(logo_path, 30, h - 108, width=150, height=82, mask='auto', preserveAspectRatio=True)
        except:
            c.setFillColor(colors.white)
            c.setFont('Helvetica-Bold', 20)
            c.drawString(40, h - 60, s.get('company_name', ''))
    else:
        c.setFillColor(colors.white)
        c.setFont('Helvetica-Bold', 20)
        c.drawString(40, h - 55, s.get('company_name', ''))
        c.setFont('Helvetica', 10)
        c.setFillColor(hex_to_color('#a0b4d6'))
        c.drawString(40, h - 72, s.get('company_website', ''))

    # Company contact top right
    c.setFillColor(colors.white)
    c.setFont('Helvetica', 9)
    contact_lines = [
        s.get('company_email', ''),
        s.get('company_phone', ''),
        s.get('company_address', '').replace('\n', ' | '),
    ]
    cy = h - 38
    for line in contact_lines:
        if line:
            c.drawRightString(w - 30, cy, line)
            cy -= 14

    # ── Document type badge ──
    doc_type  = q['type'].upper()
    badge_col = hex_to_color('#46c12f') if q['type'] == 'quote' else hex_to_color('#2271b1')
    c.setFillColor(badge_col)
    c.rect(30, h - 158, 100, 28, fill=1, stroke=0)
    c.setFillColor(colors.white)
    c.setFont('Helvetica-Bold', 14)
    c.drawString(42, h - 145, doc_type)

    # Doc number / date
    c.setFillColor(hex_to_color('#333333'))
    c.setFont('Helvetica-Bold', 10)
    c.drawString(145, h - 134, 'Number:')
    c.setFont('Helvetica', 10)
    c.drawString(200, h - 134, q['quote_number'])

    c.setFont('Helvetica-Bold', 10)
    c.drawString(145, h - 150, 'Date:')
    c.setFont('Helvetica', 10)
    c.drawString(200, h - 150, format_date(q['created_at']))

    if q.get('event_date'):
        c.setFont('Helvetica-Bold', 10)
        c.drawRightString(w - 30, h - 134, 'Event Date:')
        c.setFont('Helvetica', 10)
        c.drawString(w - 28, h - 134, format_date(q['event_date']))

    if q.get('due_date'):
        c.setFont('Helvetica-Bold', 10)
        c.drawRightString(370, h - 150, 'Due:')
        c.setFont('Helvetica', 10)
        c.drawString(375, h - 150, format_date(q['due_date']))

    # ── Bill To / Title boxes ──
    by = h - 240

    # Bill To
    c.setFillColor(hex_to_color('#f4f7fb'))
    c.rect(30, by - 75, 235, 95, fill=1, stroke=0)
    c.setStrokeColor(hex_to_color('#c2d9ef'))
    c.rect(30, by - 75, 235, 95, fill=0, stroke=1)
    c.setFillColor(accent)
    c.setFont('Helvetica-Bold', 9)
    c.drawString(42, by + 7, 'BILL TO')
    c.setFillColor(hex_to_color('#222222'))
    c.setFont('Helvetica-Bold', 12)
    c.drawString(42, by - 10, q['client_name'])
    c.setFont('Helvetica', 10)
    c.drawString(42, by - 26, q['client_email'])
    if q.get('client_phone'):
        c.drawString(42, by - 40, q['client_phone'])
    if q.get('client_address'):
        c.setFont('Helvetica', 9)
        c.drawString(42, by - 54, q['client_address'][:60])

    # Title/description
    c.setFillColor(hex_to_color('#f4f7fb'))
    c.rect(280, by - 75, 285, 95, fill=1, stroke=0)
    c.setStrokeColor(hex_to_color('#c2d9ef'))
    c.rect(280, by - 75, 285, 95, fill=0, stroke=1)
    c.setFillColor(accent)
    c.setFont('Helvetica-Bold', 9)
    c.drawString(292, by + 7, 'PROJECT / SERVICE')
    c.setFillColor(hex_to_color('#222222'))
    c.setFont('Helvetica-Bold', 11)
    # Wrap title
    title = q.get('title', '')
    if len(title) > 40:
        c.drawString(292, by - 10, title[:40])
        c.setFont('Helvetica', 10)
        c.drawString(292, by - 24, title[40:80])
    else:
        c.drawString(292, by - 10, title)

    # Status badge
    status_colors = {
        'draft': '#888888', 'sent': '#2271b1', 'approved': '#46c12f',
        'denied': '#d63638', 'paid_deposit': '#dba617', 'paid_full': '#46c12f',
        'overdue': '#d63638', 'cancelled': '#888888'
    }
    sc = hex_to_color(status_colors.get(q['status'], '#888888'))
    c.setFillColor(sc)
    status_label = q['status'].replace('_', ' ').upper()
    c.rect(292, by - 60, 120, 18, fill=1, stroke=0)
    c.setFillColor(colors.white)
    c.setFont('Helvetica-Bold', 8)
    c.drawString(296, by - 51, status_label)

    # ── Line items table ──
    ty = by - 115

    # Header
    c.setFillColor(accent)
    c.rect(30, ty, w - 60, 24, fill=1, stroke=0)
    c.setFillColor(colors.white)
    c.setFont('Helvetica-Bold', 9)
    c.drawString(42, ty + 7, 'DESCRIPTION')
    c.drawRightString(370, ty + 7, 'QTY')
    c.drawRightString(460, ty + 7, 'UNIT PRICE')
    c.drawRightString(w - 30, ty + 7, 'AMOUNT')

    ry = ty - 24
    row_cols = [colors.white, hex_to_color('#f8fafc')]

    for i, item in enumerate(items):
        c.setFillColor(row_cols[i % 2])
        c.rect(30, ry - 2, w - 60, 22, fill=1, stroke=0)
        c.setStrokeColor(hex_to_color('#e8edf2'))
        c.line(30, ry - 2, w - 30, ry - 2)
        c.setFillColor(hex_to_color('#333333'))
        c.setFont('Helvetica', 9)
        desc = item['description'][:70]
        c.drawString(42, ry + 6, desc)
        c.drawRightString(370, ry + 6, str(item['quantity']))
        c.drawRightString(460, ry + 6, format_currency(item['unit_price']))
        c.setFont('Helvetica-Bold', 9)
        c.drawRightString(w - 30, ry + 6, format_currency(item['amount']))
        ry -= 24

    # Table bottom border
    c.setStrokeColor(accent)
    c.setLineWidth(1)
    c.line(30, ry + 16, w - 30, ry + 16)

    # ── Totals ──
    total_y = ry - 10

    def draw_total(label, value, bold=False, highlight=False):
        nonlocal total_y
        if highlight:
            c.setFillColor(accent)
            c.rect(350, total_y - 4, w - 380, 22, fill=1, stroke=0)
            c.setFillColor(colors.white)
        else:
            c.setFillColor(hex_to_color('#333333'))
        font = 'Helvetica-Bold' if bold else 'Helvetica'
        size = 10 if highlight else 9
        c.setFont(font, size)
        c.drawRightString(460, total_y + 4, label)
        c.drawRightString(w - 30, total_y + 4, value)
        total_y -= 26

    draw_total('Subtotal:', format_currency(q['subtotal']))
    if float(q['tax_rate']) > 0:
        draw_total(f"Tax ({q['tax_rate']}%):", format_currency(q['tax_amount']))
    c.setStrokeColor(accent)
    c.line(350, total_y + 20, w - 30, total_y + 20)
    draw_total('TOTAL:', format_currency(q['total']), bold=True, highlight=True)

    total_y -= 4
    draw_total(f"Deposit ({int(float(q['deposit_percent']))}%):", format_currency(q['deposit_amount']))
    if float(q['amount_paid']) > 0:
        draw_total('Amount Paid:', format_currency(q['amount_paid']))
    draw_total('Balance Due:', format_currency(q['balance_due']), bold=True)

    # ── Notes and Terms ──
    ny = total_y - 20
    if q.get('notes') or q.get('terms'):
        col_w = (w - 80) / 2
        if q.get('notes'):
            c.setFillColor(hex_to_color('#f4f7fb'))
            c.rect(30, ny - 70, col_w, 80, fill=1, stroke=0)
            c.setStrokeColor(hex_to_color('#c2d9ef'))
            c.rect(30, ny - 70, col_w, 80, fill=0, stroke=1)
            c.setFillColor(accent)
            c.setFont('Helvetica-Bold', 9)
            c.drawString(42, ny + 0, 'NOTES')
            c.setFillColor(hex_to_color('#555555'))
            c.setFont('Helvetica', 8)
            note_lines = q['notes'].split('\n')[:5]
            nly = ny - 14
            for line in note_lines:
                c.drawString(42, nly, line[:75])
                nly -= 11

        if q.get('terms'):
            tx = 30 + col_w + 20
            c.setFillColor(hex_to_color('#f4f7fb'))
            c.rect(tx, ny - 70, col_w, 80, fill=1, stroke=0)
            c.setStrokeColor(hex_to_color('#c2d9ef'))
            c.rect(tx, ny - 70, col_w, 80, fill=0, stroke=1)
            c.setFillColor(accent)
            c.setFont('Helvetica-Bold', 9)
            c.drawString(tx + 12, ny + 0, 'TERMS & CONDITIONS')
            c.setFillColor(hex_to_color('#555555'))
            c.setFont('Helvetica', 8)
            term_lines = q['terms'].split('\n')[:5]
            tly = ny - 14
            for line in term_lines:
                c.drawString(tx + 12, tly, line[:75])
                tly -= 11

    # ── Footer ──
    c.setFillColor(accent)
    c.rect(0, 0, w, 40, fill=1, stroke=0)
    c.setFillColor(colors.white)
    c.setFont('Helvetica', 8)
    c.drawCentredString(w / 2, 24, 'Thank you for your business!')
    c.setFont('Helvetica-Bold', 8)
    footer_info = ' | '.join(filter(None, [
        s.get('company_name', ''),
        s.get('company_email', ''),
        s.get('company_phone', ''),
        s.get('company_website', ''),
    ]))
    c.drawCentredString(w / 2, 12, footer_info[:100])

    c.save()
    print(f"PDF generated: {pdf_path}")

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: generate_pdf.py <data_json_file>")
        sys.exit(1)
    generate_pdf(sys.argv[1])
