using System.Text.Json;
using Inspectron.Epson.PrintServer.Printers.Utils;
using Inspectron.Epson.Queue;
using FinalReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.FinalReceipt;
using InvoiceReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.InvoiceReceipt;
using KitchenReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt.KitchenReceipt;
using OrderItemsReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.OrderItems.OrderItemsReceipt;

namespace Inspectron.Epson.PrintServer.Hooks;

public delegate Task PrintJobArrivedHandler(PrintJobArrivedContext ctx, CancellationToken cancellationToken);

public sealed class PrintJobArrivedContext
{
    private KitchenReceiptModel? _kitchen;
    private FinalReceiptModel? _final;
    private InvoiceReceiptModel? _invoice;
    private OrderItemsReceiptModel? _orderItems;
    private bool _kitchenParsed, _finalParsed, _invoiceParsed, _orderItemsParsed;

    public PrintJob Job { get; }
    public int ReceiptTypeId => Job.Document.ReceiptType;
    public ReceiptConverterFactory.EReceiptType ReceiptType => (ReceiptConverterFactory.EReceiptType)Job.Document.ReceiptType;
    public string ContentJson => Job.Document.Content;

    public PrintJobArrivedContext(PrintJob job)
    {
        Job = job;
    }

    public KitchenReceiptModel? AsKitchen()
    {
        if (_kitchenParsed) return _kitchen;
        _kitchenParsed = true;
        if (ReceiptType is ReceiptConverterFactory.EReceiptType.WorkareaTicket
                        or ReceiptConverterFactory.EReceiptType.NextCourse)
        {
            _kitchen = JsonSerializer.Deserialize<KitchenReceiptModel>(ContentJson);
        }
        return _kitchen;
    }

    public FinalReceiptModel? AsFinal()
    {
        if (_finalParsed) return _final;
        _finalParsed = true;
        if (ReceiptType == ReceiptConverterFactory.EReceiptType.Receipt)
        {
            _final = JsonSerializer.Deserialize<FinalReceiptModel>(ContentJson);
        }
        return _final;
    }

    public InvoiceReceiptModel? AsInvoice()
    {
        if (_invoiceParsed) return _invoice;
        _invoiceParsed = true;
        if (ReceiptType == ReceiptConverterFactory.EReceiptType.Invoice)
        {
            _invoice = JsonSerializer.Deserialize<InvoiceReceiptModel>(ContentJson);
        }
        return _invoice;
    }

    public OrderItemsReceiptModel? AsOrderItems()
    {
        if (_orderItemsParsed) return _orderItems;
        _orderItemsParsed = true;
        if (ReceiptType == ReceiptConverterFactory.EReceiptType.OrdersOverview)
        {
            _orderItems = JsonSerializer.Deserialize<OrderItemsReceiptModel>(ContentJson);
        }
        return _orderItems;
    }
}
