//! HTML rendering for the printable invoice.
//!
//! Renders a self-contained, print-friendly HTML document. The
//! frontend uses this for the in-browser invoice view, and the same
//! HTML is what would be saved as a PDF.

use crate::{Invoice, InvoiceTotals, LineItem};
use chrono::{DateTime, Utc};

pub fn render_html(
    invoice: &Invoice,
    lines: &[LineItem],
    totals: &InvoiceTotals,
) -> String {
    let mut out = String::with_capacity(4096);

    out.push_str(r#"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Invoice "#);
    out.push_str(&escape_html(&invoice.invoice_number));
    out.push_str(r#"</title>
<style>
  * { box-sizing: border-box; }
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #0F172A; margin: 0; padding: 32px; background: #fff; }
  .invoice { max-width: 800px; margin: 0 auto; }
  h1 { font-size: 28px; margin: 0; }
  .muted { color: #64748B; }
  .row { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
  .card { border: 1px solid #E2E8F0; border-radius: 8px; padding: 16px; }
  .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  table { width: 100%; border-collapse: collapse; margin-top: 16px; font-size: 14px; }
  th { text-align: left; background: #F1F5F9; padding: 8px 12px; }
  td { padding: 8px 12px; border-top: 1px solid #E2E8F0; }
  .num { text-align: right; font-variant-numeric: tabular-nums; }
  .totals { margin-top: 16px; }
  .totals .row { padding: 4px 0; }
  .totals .grand { font-size: 18px; font-weight: 700; border-top: 2px solid #0F172A; padding-top: 8px; margin-top: 8px; }
  .badge { display: inline-block; padding: 4px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; }
  .badge.PAID { background: #DCFCE7; color: #166534; }
  .badge.ISSUED { background: #DBEAFE; color: #1E40AF; }
  .badge.VOID { background: #FEE2E2; color: #991B1B; }
  .badge.REFUNDED { background: #F1F5F9; color: #475569; }
  .badge.DRAFT { background: #FEF3C7; color: #92400E; }
  @media print {
    body { padding: 0; }
    .card { border: none; }
  }
</style>
</head>
<body>
<div class="invoice">
  <div class="row" style="margin-bottom: 24px;">
    <div>
      <h1>Tax Invoice</h1>
      <p class="muted" style="margin: 4px 0 0; font-family: monospace;">"#);
    out.push_str(&escape_html(&invoice.invoice_number));
    out.push_str("</p>\n    </div>\n    <div style=\"text-align: right;\">\n      <span class=\"badge ");
    out.push_str(&escape_html(&invoice.status));
    out.push_str("\">");
    out.push_str(&escape_html(&invoice.status));
    out.push_str(r#"</span>
      <p class="muted" style="margin: 8px 0 0;">Issued "#);
    out.push_str(&invoice.issued_at.format("%d %b %Y").to_string());
    out.push_str("</p>\n    </div>\n  </div>\n\n  <div class=\"grid-2\" style=\"margin-bottom: 16px;\">\n    <div class=\"card\">\n      <p class=\"muted\" style=\"margin: 0 0 8px; font-size: 12px; text-transform: uppercase;\">From</p>\n      <p style=\"margin: 0; font-weight: 600;\">");
    out.push_str(&escape_html(&invoice.seller_name));
    out.push_str("</p>\n      <p style=\"margin: 4px 0; white-space: pre-line;\">");
    out.push_str(&escape_html(&invoice.seller_address));
    out.push_str("</p>\n      <p style=\"margin: 4px 0; font-size: 13px;\">");
    if let Some(gstin) = &invoice.seller_gstin {
        out.push_str(&format!("GSTIN: {}<br>", escape_html(gstin)));
    }
    if let Some(pan) = &invoice.seller_pan {
        out.push_str(&format!("PAN: {}", escape_html(pan)));
    }
    out.push_str("</p>\n    </div>\n    <div class=\"card\">\n      <p class=\"muted\" style=\"margin: 0 0 8px; font-size: 12px; text-transform: uppercase;\">Bill To</p>\n      <p style=\"margin: 0; font-weight: 600;\">");
    out.push_str(&escape_html(invoice.customer_name.as_deref().unwrap_or("N/A")));
    out.push_str("</p>\n      <p style=\"margin: 4px 0; white-space: pre-line;\">");
    out.push_str(&escape_html(
        invoice.customer_billing_address.as_deref().unwrap_or("N/A"),
    ));
    out.push_str("</p>\n      <p style=\"margin: 4px 0; font-size: 13px;\">");
    if let Some(gstin) = &invoice.customer_gstin {
        out.push_str(&format!("GSTIN: {}<br>", escape_html(gstin)));
    }
    if let Some(state) = &invoice.place_of_supply_state {
        out.push_str(&format!("Place of Supply: {}", escape_html(state)));
    }
    out.push_str("</p>\n    </div>\n  </div>\n\n  <table>\n    <thead>\n      <tr>\n        <th style=\"width: 4%;\">#</th>\n        <th>Description</th>\n        <th>HSN/SAC</th>\n        <th class=\"num\">Qty</th>\n        <th class=\"num\">Rate</th>\n        <th class=\"num\">Amount</th>\n      </tr>\n    </thead>\n    <tbody>\n");

    for line in lines {
        out.push_str(&format!(
            "      <tr>\n        <td>{}</td>\n        <td>{}</td>\n        <td>{}</td>\n        <td class=\"num\">{}</td>\n        <td class=\"num\">{}</td>\n        <td class=\"num\">{}</td>\n      </tr>\n",
            line.line_number,
            escape_html(&line.description),
            escape_html(line.hsn_sac_code.as_deref().unwrap_or("")),
            format_qty(line.quantity),
            format_inr(line.unit_price_paise),
            format_inr(line.subtotal_paise()),
        ));
    }

    out.push_str("    </tbody>\n  </table>\n\n  <div class=\"totals\">\n    <div class=\"row\"><span>Subtotal</span><span class=\"num\">");
    out.push_str(&format_inr(totals.subtotal));
    out.push_str("</span></div>\n");
    if totals.discount > 0 {
        out.push_str(&format!(
            "    <div class=\"row\"><span>Discount</span><span class=\"num\">-{}</span></div>\n",
            format_inr(totals.discount),
        ));
    }
    out.push_str(&format!(
        "    <div class=\"row\"><span>Taxable value</span><span class=\"num\">{}</span></div>\n",
        format_inr(totals.taxable_value),
    ));
    if totals.cgst > 0 {
        out.push_str(&format!(
            "    <div class=\"row\"><span>CGST</span><span class=\"num\">{}</span></div>\n",
            format_inr(totals.cgst),
        ));
        out.push_str(&format!(
            "    <div class=\"row\"><span>SGST</span><span class=\"num\">{}</span></div>\n",
            format_inr(totals.sgst),
        ));
    }
    if totals.igst > 0 {
        out.push_str(&format!(
            "    <div class=\"row\"><span>IGST</span><span class=\"num\">{}</span></div>\n",
            format_inr(totals.igst),
        ));
    }
    out.push_str(&format!(
        "    <div class=\"row grand\"><span>Total ({})</span><span class=\"num\">{}</span></div>\n",
        invoice.currency,
        format_inr(totals.total),
    ));
    out.push_str("  </div>\n\n  <p class=\"muted\" style=\"margin-top: 32px; font-size: 12px;\">\n    This is a computer-generated invoice. No signature is required.\n  </p>\n</div>\n</body>\n</html>\n");
    out
}

fn escape_html(s: &str) -> String {
    s.replace('&', "&amp;")
        .replace('<', "&lt;")
        .replace('>', "&gt;")
        .replace('"', "&quot;")
        .replace('\'', "&#39;")
}

fn format_inr(paise: i64) -> String {
    let sign = if paise < 0 { "-" } else { "" };
    let abs = paise.unsigned_abs();
    let rupees = abs / 100;
    let paise = abs % 100;
    let rupees_str = {
        let s = rupees.to_string();
        let mut out = String::new();
        for (i, c) in s.chars().rev().enumerate() {
            if i != 0 && i % 3 == 0 {
                out.insert(0, ',');
            }
            out.insert(0, c);
        }
        out
    };
    format!("{}₹{}.{:02}", sign, rupees_str, paise)
}

fn format_qty(q: f64) -> String {
    if (q.fract() - 0.0).abs() < 0.001 {
        format!("{}", q.trunc() as i64)
    } else {
        format!("{:.3}", q)
    }
}

#[allow(dead_code)]
fn _today_anchor() -> DateTime<Utc> {
    Utc::now()
}
