#!/usr/bin/env python3
"""
Invoice Generator — Python Freelancer Toolkit
Generates professional PDF invoices from client data.
Usage: python3 09_invoice_generator.py --config invoice_config.json
"""

import json
import argparse
import os
from datetime import datetime, timedelta
from pathlib import Path

# Optional: pip install reportlab (falls back to HTML if not installed)
try:
    from reportlab.lib.pagesizes import A4
    from reportlab.lib import colors
    from reportlab.lib.units import mm
    from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.lib.enums import TA_RIGHT, TA_CENTER
    PDF_AVAILABLE = True
except ImportError:
    PDF_AVAILABLE = False

SAMPLE_CONFIG = {
    "invoice_number": "INV-2024-001",
    "issue_date": datetime.now().strftime("%Y-%m-%d"),
    "due_date": (datetime.now() + timedelta(days=14)).strftime("%Y-%m-%d"),
    "currency": "EUR",
    "vat_rate": 0.20,
    "freelancer": {
        "name": "Your Name",
        "email": "you@email.com",
        "address": "Your Address, City, Country",
        "phone": "+1 234 567 8900",
        "bank": "IBAN: XX00 0000 0000 0000 0000 0000",
        "tax_id": "TAX-12345"
    },
    "client": {
        "name": "Client Company Name",
        "contact": "Client Contact Person",
        "email": "client@company.com",
        "address": "Client Address, City, Country",
        "vat_number": "VAT-67890"
    },
    "items": [
        {
            "description": "Web Development - Homepage Redesign",
            "quantity": 1,
            "unit": "project",
            "unit_price": 1500.00
        },
        {
            "description": "Consulting Sessions",
            "quantity": 4,
            "unit": "hours",
            "unit_price": 150.00
        }
    ],
    "notes": "Payment due within 14 days. Late payments subject to 2% monthly interest.",
    "payment_terms": "Bank transfer only. Reference invoice number in payment."
}


def calculate_totals(items, vat_rate, currency="EUR"):
    """Calculate invoice totals."""
    subtotal = sum(item["quantity"] * item["unit_price"] for item in items)
    vat_amount = subtotal * vat_rate
    total = subtotal + vat_amount
    return {
        "subtotal": subtotal,
        "vat_amount": vat_amount,
        "total": total,
        "currency": currency
    }


def format_currency(amount, currency="EUR"):
    """Format amount as currency string."""
    symbols = {"EUR": "€", "USD": "$", "GBP": "£", "CHF": "CHF "}
    symbol = symbols.get(currency, currency + " ")
    return f"{symbol}{amount:,.2f}"


def generate_html_invoice(config):
    """Generate a professional HTML invoice."""
    items = config["items"]
    totals = calculate_totals(items, config.get("vat_rate", 0), config.get("currency", "EUR"))
    currency = config.get("currency", "EUR")

    items_html = ""
    for item in items:
        line_total = item["quantity"] * item["unit_price"]
        items_html += f"""
        <tr>
            <td class="description">{item['description']}</td>
            <td class="center">{item['quantity']} {item.get('unit', '')}</td>
            <td class="right">{format_currency(item['unit_price'], currency)}</td>
            <td class="right amount">{format_currency(line_total, currency)}</td>
        </tr>"""

    vat_rate_pct = config.get("vat_rate", 0) * 100
    freelancer = config["freelancer"]
    client = config["client"]

    html = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Invoice {config['invoice_number']}</title>
    <style>
        * {{ margin: 0; padding: 0; box-sizing: border-box; }}
        body {{ font-family: 'Helvetica Neue', Arial, sans-serif; font-size: 14px; color: #333; background: #f5f5f5; }}
        .invoice-wrapper {{ max-width: 800px; margin: 40px auto; background: white; padding: 60px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); }}
        .header {{ display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 50px; }}
        .company-name {{ font-size: 28px; font-weight: 700; color: #1a1a2e; }}
        .invoice-title {{ font-size: 36px; font-weight: 300; color: #666; text-align: right; }}
        .invoice-number {{ font-size: 16px; color: #333; font-weight: 600; margin-top: 5px; }}
        .parties {{ display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-bottom: 40px; padding-bottom: 40px; border-bottom: 2px solid #f0f0f0; }}
        .party-label {{ font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #999; margin-bottom: 10px; }}
        .party-name {{ font-size: 16px; font-weight: 700; margin-bottom: 5px; }}
        .party-detail {{ color: #666; line-height: 1.6; font-size: 13px; }}
        .dates {{ display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; margin-bottom: 40px; padding: 20px; background: #f9f9f9; border-radius: 8px; }}
        .date-item label {{ font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #999; display: block; margin-bottom: 5px; }}
        .date-item span {{ font-weight: 600; font-size: 15px; }}
        .due {{ color: #e74c3c; }}
        table {{ width: 100%; border-collapse: collapse; margin-bottom: 30px; }}
        thead th {{ background: #1a1a2e; color: white; padding: 12px 15px; text-align: left; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }}
        thead th.right, thead th.center {{ text-align: right; }}
        thead th.center {{ text-align: center; }}
        tbody tr {{ border-bottom: 1px solid #f0f0f0; }}
        tbody tr:hover {{ background: #fafafa; }}
        tbody td {{ padding: 14px 15px; }}
        td.center {{ text-align: center; color: #666; }}
        td.right {{ text-align: right; }}
        td.amount {{ font-weight: 600; }}
        .totals {{ display: flex; justify-content: flex-end; }}
        .totals-box {{ width: 300px; }}
        .totals-row {{ display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f0f0f0; }}
        .totals-row.total {{ font-weight: 700; font-size: 18px; padding-top: 15px; color: #1a1a2e; border-bottom: none; }}
        .notes {{ margin-top: 40px; padding: 20px; background: #f9f9f9; border-left: 4px solid #1a1a2e; border-radius: 0 8px 8px 0; }}
        .notes label {{ font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #999; display: block; margin-bottom: 10px; }}
        .footer {{ margin-top: 50px; text-align: center; color: #999; font-size: 12px; border-top: 1px solid #f0f0f0; padding-top: 20px; }}
    </style>
</head>
<body>
    <div class="invoice-wrapper">
        <div class="header">
            <div>
                <div class="company-name">{freelancer['name']}</div>
                <div class="party-detail" style="margin-top: 5px;">{freelancer['email']}<br>{freelancer.get('phone', '')}</div>
            </div>
            <div style="text-align: right;">
                <div class="invoice-title">INVOICE</div>
                <div class="invoice-number">#{config['invoice_number']}</div>
            </div>
        </div>
        <div class="parties">
            <div>
                <div class="party-label">From</div>
                <div class="party-name">{freelancer['name']}</div>
                <div class="party-detail">
                    {freelancer.get('address', '')}<br>
                    {freelancer.get('tax_id', '')}<br>
                    {freelancer.get('bank', '')}
                </div>
            </div>
            <div>
                <div class="party-label">Bill To</div>
                <div class="party-name">{client['name']}</div>
                <div class="party-detail">
                    {client.get('contact', '')}<br>
                    {client.get('address', '')}<br>
                    {client.get('vat_number', '')}
                </div>
            </div>
        </div>
        <div class="dates">
            <div class="date-item">
                <label>Invoice Date</label>
                <span>{config['issue_date']}</span>
            </div>
            <div class="date-item">
                <label>Due Date</label>
                <span class="due">{config['due_date']}</span>
            </div>
            <div class="date-item">
                <label>Invoice #</label>
                <span>{config['invoice_number']}</span>
            </div>
        </div>
        <table>
            <thead>
                <tr>
                    <th>Description</th>
                    <th class="center">Qty</th>
                    <th class="right">Unit Price</th>
                    <th class="right">Amount</th>
                </tr>
            </thead>
            <tbody>
                {items_html}
            </tbody>
        </table>
        <div class="totals">
            <div class="totals-box">
                <div class="totals-row">
                    <span>Subtotal</span>
                    <span>{format_currency(totals['subtotal'], currency)}</span>
                </div>
                <div class="totals-row">
                    <span>VAT ({vat_rate_pct:.0f}%)</span>
                    <span>{format_currency(totals['vat_amount'], currency)}</span>
                </div>
                <div class="totals-row total">
                    <span>TOTAL DUE</span>
                    <span>{format_currency(totals['total'], currency)}</span>
                </div>
            </div>
        </div>
        <div class="notes">
            <label>Notes & Payment Terms</label>
            <p>{config.get('notes', '')}</p>
            <p style="margin-top: 8px;">{config.get('payment_terms', '')}</p>
        </div>
        <div class="footer">
            Thank you for your business! • {freelancer['email']}
        </div>
    </div>
</body>
</html>"""
    return html


def generate_invoice(config_path=None, output_dir="."):
    """Main function to generate invoice."""
    if config_path and os.path.exists(config_path):
        with open(config_path) as f:
            config = json.load(f)
    else:
        config = SAMPLE_CONFIG
        print("No config provided. Using sample data.")
        # Save sample config for reference
        with open("invoice_sample_config.json", "w") as f:
            json.dump(SAMPLE_CONFIG, f, indent=2)
        print("Sample config saved to: invoice_sample_config.json")

    # Generate HTML
    html_content = generate_html_invoice(config)
    invoice_num = config.get("invoice_number", "invoice").replace("/", "-")
    html_path = os.path.join(output_dir, f"{invoice_num}.html")

    with open(html_path, "w") as f:
        f.write(html_content)
    print(f"✓ HTML invoice saved: {html_path}")

    # Summary
    items = config["items"]
    totals = calculate_totals(items, config.get("vat_rate", 0), config.get("currency", "EUR"))
    currency = config.get("currency", "EUR")

    print(f"\n--- Invoice Summary ---")
    print(f"Invoice #:  {config['invoice_number']}")
    print(f"Client:     {config['client']['name']}")
    print(f"Due:        {config['due_date']}")
    print(f"Subtotal:   {format_currency(totals['subtotal'], currency)}")
    print(f"VAT:        {format_currency(totals['vat_amount'], currency)}")
    print(f"TOTAL:      {format_currency(totals['total'], currency)}")

    return html_path


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Generate professional invoices")
    parser.add_argument("--config", help="Path to JSON config file")
    parser.add_argument("--output", default=".", help="Output directory")
    args = parser.parse_args()

    generate_invoice(args.config, args.output)
