using Meezi.API.Models.Orders;
using Meezi.Core.Enums;

namespace Meezi.API.Services.Printing;

public record ReceiptPrintContext(
    OrderDto Order,
    string CafeName,
    string BranchName,
    string? ReceiptHeader,
    string? ReceiptFooter,
    string? WifiPassword,
    int PaperWidthMm,
    bool AutoCutEnabled,
    string? StationName = null);

public static class ReceiptPrintFormatting
{
    public static int LineWidth(int paperWidthMm) => paperWidthMm == 58 ? 32 : 48;

    public static string FormatCurrency(decimal amount) =>
        $"{amount:N0} ت";

    public static string ToShamsi(DateTime dt)
    {
        var pc = new System.Globalization.PersianCalendar();
        return $"{pc.GetYear(dt)}/{pc.GetMonth(dt):D2}/{pc.GetDayOfMonth(dt):D2} {dt:HH:mm}";
    }

    public static string OrderNumberLabel(int displayNumber) =>
        displayNumber > 0 ? displayNumber.ToString() : "0";

    public static string OrderNumberLabel(string orderId) =>
        OrderNumberLabel(StableDisplayNumberFromId(orderId));

    public static int StableDisplayNumberFromId(string orderId)
    {
        if (string.IsNullOrWhiteSpace(orderId)) return 0;
        var hex = orderId.Replace("-", "", StringComparison.Ordinal);
        if (hex.Length == 32
            && ulong.TryParse(hex.AsSpan(0, 16), System.Globalization.NumberStyles.HexNumber, null, out var hi)
            && ulong.TryParse(hex.AsSpan(16, 16), System.Globalization.NumberStyles.HexNumber, null, out var lo))
        {
            return (int)((hi ^ lo) % 9_999_999) + 1;
        }

        var digits = new string(orderId.Where(char.IsDigit).ToArray());
        if (digits.Length > 0 && int.TryParse(digits.Length > 9 ? digits[^9..] : digits, out var parsed))
            return parsed;

        return (int)((uint)Math.Abs(StringComparer.Ordinal.GetHashCode(hex)) % 999_999) + 1;
    }

    public static string PaymentMethodLabel(PaymentMethod method) => method switch
    {
        PaymentMethod.Cash => "نقد",
        PaymentMethod.Card => "کارت",
        PaymentMethod.Credit => "اعتبار",
        _ => method.ToString()
    };
}
