using Books.Api.EventFlow.ReadModels;
using GraphQL.Types;

namespace Books.Api.GraphQL.Types;

public class OrderGraphType : ObjectGraphType<OrderReadModelDto>
{
    public OrderGraphType()
    {
        Name = "Order";
        Description = "An order for a customer (Ordre)";

        Field(x => x.Id).Description("Unique identifier");
        Field(x => x.CompanyId).Description("Company this order belongs to");
        Field(x => x.FiscalYearId).Description("Fiscal year for this order");
        Field(x => x.CustomerId).Description("Customer ID");
        Field(x => x.CustomerName).Description("Customer name at time of order creation");
        Field(x => x.CustomerNumber).Description("Customer number (Kundenummer)");
        Field(x => x.OrderNumber).Description("Order number (Ordrenummer)");

        Field<DateOnlyGraphType>("orderDate")
            .Description("Order date (Ordredato)")
            .Resolve(ctx => ctx.Source.OrderDate.HasValue
                ? DateOnly.FromDateTime(ctx.Source.OrderDate.Value)
                : null);

        Field<DateOnlyGraphType>("expectedDeliveryDate")
            .Description("Expected delivery date (Forventet leveringsdato)")
            .Resolve(ctx => ctx.Source.ExpectedDeliveryDate.HasValue
                ? DateOnly.FromDateTime(ctx.Source.ExpectedDeliveryDate.Value)
                : null);

        Field(x => x.Status).Description("Status: draft, confirmed, partially_invoiced, fully_invoiced, cancelled");
        Field(x => x.AmountExVat).Description("Total amount excluding VAT (Beløb eks. moms)");
        Field(x => x.AmountVat).Description("Total VAT amount (Momsbeløb)");
        Field(x => x.AmountTotal).Description("Total amount including VAT (Beløb inkl. moms)");
        Field(x => x.Currency).Description("Currency code (default: DKK)");

        Field<ListGraphType<OrderLineGraphType>>("lines")
            .Description("Order lines (Ordrelinjer)")
            .Resolve(ctx => ctx.Source.GetLines());

        Field<ListGraphType<OrderLineGraphType>>("uninvoicedLines")
            .Description("Order lines not yet invoiced (Ikke-fakturerede ordrelinjer)")
            .Resolve(ctx => ctx.Source.GetUninvoicedLines());

        Field<IntGraphType>("uninvoicedLineCount")
            .Description("Count of lines not yet invoiced")
            .Resolve(ctx => ctx.Source.UninvoicedLineCount);

        Field<DecimalGraphType>("uninvoicedAmount")
            .Description("Total amount of uninvoiced lines")
            .Resolve(ctx => ctx.Source.UninvoicedAmount);

        Field(x => x.InvoiceId, nullable: true).Description("Most recent invoice ID (when converted)");
        Field(x => x.InvoiceNumber, nullable: true).Description("Most recent invoice number (when converted)");
        Field(x => x.Notes, nullable: true).Description("Internal notes (Interne noter)");
        Field(x => x.Reference, nullable: true).Description("Customer reference (Kundens reference)");

        Field(x => x.ConfirmedAt, nullable: true).Description("When the order was confirmed");
        Field(x => x.ConfirmedBy, nullable: true).Description("User who confirmed the order");
        Field(x => x.InvoicedAt, nullable: true).Description("When the order was last invoiced");
        Field(x => x.InvoicedBy, nullable: true).Description("User who last invoiced the order");
        Field(x => x.CancelledAt, nullable: true).Description("When the order was cancelled");
        Field(x => x.CancelledBy, nullable: true).Description("User who cancelled the order");
        Field(x => x.CancelledReason, nullable: true).Description("Reason for cancellation");

        Field(x => x.CreatedBy).Description("User who created the order");
        Field(x => x.UpdatedBy, nullable: true).Description("User who last updated the order");
        Field(x => x.CreatedAt).Description("When the order was created");
        Field(x => x.UpdatedAt).Description("When the order was last updated");
    }
}

public class OrderLineGraphType : ObjectGraphType<OrderLineDto>
{
    public OrderLineGraphType()
    {
        Name = "OrderLine";
        Description = "A line on an order (Ordrelinje)";

        Field(x => x.LineNumber).Description("Line number (1-based)");
        Field(x => x.ProductId, nullable: true).Description("Product ID if linked to a product");
        Field(x => x.Description).Description("Description of product/service (Beskrivelse)");
        Field(x => x.Quantity).Description("Quantity (Antal)");
        Field(x => x.Unit, nullable: true).Description("Unit of measurement (Enhed)");
        Field(x => x.UnitPrice).Description("Price per unit excluding VAT (Stykpris)");
        Field(x => x.DiscountPercent).Description("Discount percentage (Rabat %)");
        Field(x => x.VatCode).Description("VAT code (e.g., U25, UEU, UEXP)");
        Field(x => x.AccountId, nullable: true).Description("Revenue account ID");
        Field(x => x.AmountExVat).Description("Line amount excluding VAT");
        Field(x => x.AmountVat).Description("Line VAT amount");
        Field(x => x.AmountTotal).Description("Line total including VAT");
        Field(x => x.IsInvoiced).Description("Whether this line has been invoiced");
        Field(x => x.InvoiceId, nullable: true).Description("Invoice ID where this line was invoiced");
        Field(x => x.InvoicedAt, nullable: true).Description("When this line was invoiced");
    }
}

public class OrderStatusEnumType : EnumerationGraphType
{
    public OrderStatusEnumType()
    {
        Name = "OrderStatus";
        Description = "Status of an order (Ordrestatus)";

        Add("DRAFT", "draft", "Order is being prepared (Kladde)");
        Add("CONFIRMED", "confirmed", "Order has been confirmed and ready for invoicing (Bekræftet)");
        Add("PARTIALLY_INVOICED", "partially_invoiced", "Some lines have been invoiced (Delvist faktureret)");
        Add("FULLY_INVOICED", "fully_invoiced", "All lines have been invoiced (Fuldt faktureret)");
        Add("CANCELLED", "cancelled", "Order has been cancelled (Annulleret)");
    }
}
