using System.Globalization;
using System.Net;
using System.Text;
using DateTimeConverterCL;

namespace BackOffice.Common.Utilities;

/// <summary>ساخت HTML فاکتور برای چاپ مرورگر (jsHtmlToPdf).</summary>
public static class OrderInvoicePrint
{
    public sealed class InvoiceModel
    {
        public string ShopTitle { get; set; } = "فروشگاه";
        public string OrderId { get; set; } = "";
        public string? CustomerName { get; set; }
        public string? CustomerMobile { get; set; }
        public string? CustomerNationalCode { get; set; }
        public string? Address { get; set; }
        public string? PostalCode { get; set; }
        public string? PaymentStatus { get; set; }
        public string? PaymentMethod { get; set; }
        public string? TransactionId { get; set; }
        public string? TrackingCode { get; set; }
        public DateTime? Created { get; set; }
        public DateTime? PaymentDate { get; set; }
        public long Subtotal { get; set; }
        public long DiscountTotal { get; set; }
        public long CreditUsed { get; set; }
        public long GatewayAmount { get; set; }
        public long VatAmount { get; set; }
        public long TotalAmount { get; set; }
        public List<InvoiceLine> Lines { get; set; } = new();
    }

    public sealed class InvoiceLine
    {
        public string Title { get; set; } = "";
        public int Quantity { get; set; }
        public long UnitPrice { get; set; }
        public long Discount { get; set; }
        public long LineTotal { get; set; }
    }

    public static string BuildHtml(InvoiceModel model)
    {
        var sb = new StringBuilder();
        sb.Append("<!DOCTYPE html><html lang=\"fa\" dir=\"rtl\"><head><meta charset=\"utf-8\"/>");
        sb.Append("<title>").Append(Esc($"فاکتور {model.OrderId}")).Append("</title>");
        sb.Append("""
<style>
  * { box-sizing: border-box; }
  body { font-family: Tahoma, "Segoe UI", sans-serif; color: #111; margin: 24px; font-size: 13px; }
  h1 { font-size: 20px; margin: 0 0 4px; }
  .muted { color: #555; }
  .header { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 2px solid #222; padding-bottom: 12px; margin-bottom: 16px; }
  .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 24px; margin-bottom: 16px; }
  .label { color: #666; font-size: 11px; }
  .value { font-weight: 600; }
  table { width: 100%; border-collapse: collapse; margin: 12px 0 16px; }
  th, td { border: 1px solid #ccc; padding: 8px; text-align: right; }
  th { background: #f3f3f3; }
  .num { text-align: left; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .totals { width: 320px; margin-right: auto; }
  .totals td { border: none; padding: 4px 0; }
  .totals .grand { font-size: 15px; font-weight: 700; border-top: 2px solid #222; padding-top: 8px; }
  .footer { margin-top: 28px; font-size: 11px; color: #666; border-top: 1px dashed #bbb; padding-top: 8px; }
  @media print {
    body { margin: 0; }
    .no-print { display: none !important; }
  }
</style>
""");
        sb.Append("</head><body>");
        sb.Append("<div class=\"header\"><div>");
        sb.Append("<h1>").Append(Esc(model.ShopTitle)).Append("</h1>");
        sb.Append("<div class=\"muted\">فاکتور فروش</div></div><div>");
        sb.Append("<div><span class=\"label\">شماره فاکتور: </span><span class=\"value\">").Append(Esc(model.OrderId)).Append("</span></div>");
        if (model.Created.HasValue)
            sb.Append("<div><span class=\"label\">تاریخ ثبت: </span>").Append(Esc(FormatDate(model.Created.Value))).Append("</div>");
        if (model.PaymentDate.HasValue)
            sb.Append("<div><span class=\"label\">تاریخ پرداخت: </span>").Append(Esc(FormatDate(model.PaymentDate.Value))).Append("</div>");
        sb.Append("</div></div>");

        sb.Append("<div class=\"grid\">");
        AppendField(sb, "نام مشتری", model.CustomerName);
        AppendField(sb, "موبایل", model.CustomerMobile);
        AppendField(sb, "کد ملی", model.CustomerNationalCode);
        AppendField(sb, "کد پستی", model.PostalCode);
        AppendField(sb, "وضعیت پرداخت", model.PaymentStatus);
        AppendField(sb, "روش پرداخت", model.PaymentMethod);
        AppendField(sb, "کد تراکنش", model.TransactionId);
        AppendField(sb, "کد رهگیری", model.TrackingCode);
        if (!string.IsNullOrWhiteSpace(model.Address))
        {
            sb.Append("<div style=\"grid-column:1/-1\"><div class=\"label\">آدرس</div><div class=\"value\">")
                .Append(Esc(model.Address)).Append("</div></div>");
        }
        sb.Append("</div>");

        sb.Append("<table><thead><tr>");
        sb.Append("<th>#</th><th>کالا</th><th>تعداد</th><th>قیمت واحد</th><th>تخفیف</th><th>مبلغ</th>");
        sb.Append("</tr></thead><tbody>");
        var i = 1;
        foreach (var line in model.Lines)
        {
            sb.Append("<tr>");
            sb.Append("<td class=\"num\">").Append(i++).Append("</td>");
            sb.Append("<td>").Append(Esc(line.Title)).Append("</td>");
            sb.Append("<td class=\"num\">").Append(line.Quantity).Append("</td>");
            sb.Append("<td class=\"num\">").Append(Money(line.UnitPrice)).Append("</td>");
            sb.Append("<td class=\"num\">").Append(Money(line.Discount)).Append("</td>");
            sb.Append("<td class=\"num\">").Append(Money(line.LineTotal)).Append("</td>");
            sb.Append("</tr>");
        }
        if (model.Lines.Count == 0)
            sb.Append("<tr><td colspan=\"6\" class=\"muted\">آیتمی ثبت نشده است</td></tr>");
        sb.Append("</tbody></table>");

        sb.Append("<table class=\"totals\"><tbody>");
        if (model.Subtotal > 0)
            AppendTotalRow(sb, "جمع اقلام", model.Subtotal);
        if (model.DiscountTotal > 0)
            AppendTotalRow(sb, "تخفیف", model.DiscountTotal);
        if (model.VatAmount > 0)
            AppendTotalRow(sb, "مالیات بر ارزش افزوده", model.VatAmount);
        if (model.CreditUsed > 0)
            AppendTotalRow(sb, "پرداخت از کیف اعتباری", model.CreditUsed);
        if (model.GatewayAmount > 0)
            AppendTotalRow(sb, "پرداخت درگاه / نقدی", model.GatewayAmount);
        sb.Append("<tr class=\"grand\"><td>مبلغ قابل پرداخت</td><td class=\"num\">")
            .Append(Money(model.TotalAmount)).Append(" تومان</td></tr>");
        sb.Append("</tbody></table>");

        sb.Append("<div class=\"footer\">چاپ‌شده از پنل ادمین — ").Append(Esc(FormatDate(DateTime.Now))).Append("</div>");
        sb.Append("</body></html>");
        return sb.ToString();
    }

    private static void AppendField(StringBuilder sb, string label, string? value)
    {
        if (string.IsNullOrWhiteSpace(value)) return;
        sb.Append("<div><div class=\"label\">").Append(Esc(label)).Append("</div><div class=\"value\">")
            .Append(Esc(value)).Append("</div></div>");
    }

    private static void AppendTotalRow(StringBuilder sb, string label, long amount)
    {
        sb.Append("<tr><td>").Append(Esc(label)).Append("</td><td class=\"num\">")
            .Append(Money(amount)).Append(" تومان</td></tr>");
    }

    private static string Money(long amount) => amount.ToString("N0", CultureInfo.InvariantCulture);

    private static string FormatDate(DateTime dt)
    {
        try { return dt.ToLocalTime().MiladiToJalaliWithTime(); }
        catch { return dt.ToLocalTime().ToString("yyyy/MM/dd HH:mm"); }
    }

    private static string Esc(string? s) => WebUtility.HtmlEncode(s ?? "");
}
