using Meezi.API.Models.Orders;

namespace Meezi.API.Services.Printing;

public class ReceiptBuilder
{
    public byte[] BuildReceipt(ReceiptPrintContext ctx)
    {
        var order = ctx.Order;
        var width = ReceiptPrintFormatting.LineWidth(ctx.PaperWidthMm);
        var b = new EscPosBuilder();

        b.Initialize().SetEncoding();

        b.AlignCenter()
            .Bold(true)
            .DoubleHeight(true)
            .Line(ctx.CafeName)
            .DoubleHeight(false)
            .Bold(false)
            .Line(ctx.BranchName);

        if (!string.IsNullOrWhiteSpace(ctx.ReceiptHeader))
            b.Line(ctx.ReceiptHeader.Trim());

        var orderNo = ReceiptPrintFormatting.OrderNumberLabel(order.DisplayNumber);
        b.AlignRight()
            .Line($"شماره سفارش: {orderNo}")
            .Line($"تاریخ: {ReceiptPrintFormatting.ToShamsi(order.CreatedAt)}")
            .Line($"میز: {order.TableNumber ?? "—"}");

        if (!string.IsNullOrWhiteSpace(order.GuestName))
            b.Line($"مهمان: {order.GuestName}");
        else if (!string.IsNullOrWhiteSpace(order.CustomerName))
            b.Line($"مشتری: {order.CustomerName}");

        b.Separator(width).AlignRight();

        foreach (var item in order.Items.Where(i => !i.IsVoided))
        {
            var itemTotal = ReceiptPrintFormatting.FormatCurrency(item.UnitPrice * item.Quantity);
            var itemLine = $"{item.MenuItemName} × {item.Quantity}";
            b.TwoColumns(itemLine, itemTotal, width);
        }

        b.Separator(width);

        if (order.DiscountAmount > 0)
            b.TwoColumns("تخفیف", ReceiptPrintFormatting.FormatCurrency(order.DiscountAmount), width);

        if (order.TaxTotal > 0)
            b.TwoColumns("مالیات", ReceiptPrintFormatting.FormatCurrency(order.TaxTotal), width);

        b.Bold(true)
            .TwoColumns("مجموع کل", ReceiptPrintFormatting.FormatCurrency(order.Total), width)
            .Bold(false);

        foreach (var payment in order.Payments)
        {
            var label = ReceiptPrintFormatting.PaymentMethodLabel(payment.Method);
            b.TwoColumns(label, ReceiptPrintFormatting.FormatCurrency(payment.Amount), width);
        }

        b.Separator(width).AlignCenter();

        if (!string.IsNullOrWhiteSpace(ctx.WifiPassword))
            b.Line($"WiFi: {ctx.WifiPassword.Trim()}");

        if (!string.IsNullOrWhiteSpace(ctx.ReceiptFooter))
            b.Line(ctx.ReceiptFooter.Trim());

        b.Line("ممنون از انتخاب شما");

        b.Feed(3);
        if (ctx.AutoCutEnabled)
            b.Cut();

        return b.Build();
    }

    public byte[] BuildKitchenTicket(ReceiptPrintContext ctx, IReadOnlyList<OrderItemDto>? itemsOnly = null)
    {
        var order = ctx.Order;
        var items = itemsOnly ?? order.Items.Where(i => !i.IsVoided).ToList();
        var width = ReceiptPrintFormatting.LineWidth(ctx.PaperWidthMm);
        var b = new EscPosBuilder();

        b.Initialize()
            .SetEncoding()
            .AlignCenter()
            .Bold(true)
            .DoubleHeight(true)
            .Line(string.IsNullOrWhiteSpace(ctx.StationName) ? "آشپزخانه" : ctx.StationName!)
            .DoubleHeight(false)
            .Bold(false)
            .AlignRight()
            .Line($"میز: {order.TableNumber ?? "—"} | #{ReceiptPrintFormatting.OrderNumberLabel(order.DisplayNumber)}")
            .Line($"{DateTime.Now:HH:mm}")
            .Separator(width);

        foreach (var item in items)
        {
            b.Bold(true)
                .Line($"× {item.Quantity}  {item.MenuItemName}")
                .Bold(false);

            if (!string.IsNullOrWhiteSpace(item.Notes))
                b.Line($"  ← {item.Notes}");
        }

        b.Feed(4);
        if (ctx.AutoCutEnabled)
            b.Cut();

        return b.Build();
    }

    public byte[] BuildTestPage()
    {
        var b = new EscPosBuilder();
        b.Initialize()
            .SetEncoding()
            .AlignCenter()
            .Bold(true)
            .Line("Meezi Test Print ✓")
            .Bold(false)
            .Line(ReceiptPrintFormatting.ToShamsi(DateTime.Now))
            .Feed(3)
            .Cut();
        return b.Build();
    }
}
