using GraphQL.Types;

namespace Books.Api.GraphQL.InputTypes;

public class CreateInvoiceInputType : InputObjectGraphType<CreateInvoiceInput>
{
    public CreateInvoiceInputType()
    {
        Name = "CreateInvoiceInput";
        Description = "Input for creating a new invoice";

        Field(x => x.CompanyId).Description("Company ID (required)");
        Field(x => x.FiscalYearId).Description("Fiscal year ID (required)");
        Field(x => x.CustomerId).Description("Customer ID (required)");
        Field(x => x.InvoiceDate, nullable: true).Description("Invoice date (defaults to today)");
        Field(x => x.DueDate, nullable: true).Description("Due date (defaults based on payment terms)");
        Field(x => x.VatCode, nullable: true).Description("Default VAT code (defaults to U25)");
        Field(x => x.Notes, nullable: true).Description("Internal notes");
        Field(x => x.Reference, nullable: true).Description("Customer reference");
    }
}

public class CreateInvoiceInput
{
    public string CompanyId { get; set; } = string.Empty;
    public string FiscalYearId { get; set; } = string.Empty;
    public string CustomerId { get; set; } = string.Empty;
    public DateTime? InvoiceDate { get; set; }
    public DateTime? DueDate { get; set; }
    public string? VatCode { get; set; }
    public string? Notes { get; set; }
    public string? Reference { get; set; }
}

public class AddInvoiceLineInputType : InputObjectGraphType<AddInvoiceLineInput>
{
    public AddInvoiceLineInputType()
    {
        Name = "AddInvoiceLineInput";
        Description = "Input for adding a line to an invoice";

        Field(x => x.InvoiceId).Description("Invoice ID (required)");
        Field(x => x.Description).Description("Description of product/service (required)");
        Field(x => x.Quantity).Description("Quantity (required, must be positive)");
        Field(x => x.UnitPrice).Description("Unit price excluding VAT (required)");
        Field(x => x.VatCode, nullable: true).Description("VAT code (defaults to invoice VAT code or U25)");
        Field(x => x.AccountId, nullable: true).Description("Revenue account ID (defaults to customer's default)");
        Field(x => x.Unit, nullable: true).Description("Unit of measurement (e.g., stk, timer)");
        Field(x => x.DiscountPercent, nullable: true).Description("Discount percentage (0-100)");
    }
}

public class AddInvoiceLineInput
{
    public string InvoiceId { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public decimal Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public string? VatCode { get; set; }
    public string? AccountId { get; set; }
    public string? Unit { get; set; }
    public decimal? DiscountPercent { get; set; }
}

public class UpdateInvoiceLineInputType : InputObjectGraphType<UpdateInvoiceLineInput>
{
    public UpdateInvoiceLineInputType()
    {
        Name = "UpdateInvoiceLineInput";
        Description = "Input for updating a line on an invoice";

        Field(x => x.InvoiceId).Description("Invoice ID (required)");
        Field(x => x.LineNumber).Description("Line number to update (required)");
        Field(x => x.Description).Description("Description of product/service (required)");
        Field(x => x.Quantity).Description("Quantity (required)");
        Field(x => x.UnitPrice).Description("Unit price excluding VAT (required)");
        Field(x => x.VatCode, nullable: true).Description("VAT code");
        Field(x => x.AccountId, nullable: true).Description("Revenue account ID");
        Field(x => x.Unit, nullable: true).Description("Unit of measurement");
        Field(x => x.DiscountPercent, nullable: true).Description("Discount percentage (0-100)");
    }
}

public class UpdateInvoiceLineInput
{
    public string InvoiceId { get; set; } = string.Empty;
    public int LineNumber { get; set; }
    public string Description { get; set; } = string.Empty;
    public decimal Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public string? VatCode { get; set; }
    public string? AccountId { get; set; }
    public string? Unit { get; set; }
    public decimal? DiscountPercent { get; set; }
}

public class ReceivePaymentInputType : InputObjectGraphType<ReceivePaymentInput>
{
    public ReceivePaymentInputType()
    {
        Name = "ReceivePaymentInput";
        Description = "Input for recording a payment received";

        Field(x => x.InvoiceId).Description("Invoice ID (required)");
        Field(x => x.Amount).Description("Payment amount (required)");
        Field(x => x.BankAccountId).Description("Bank account ID for the payment (required)");
        Field(x => x.PaymentDate, nullable: true).Description("Payment date (defaults to today)");
        Field(x => x.BankTransactionId, nullable: true).Description("Bank transaction ID if matched");
        Field(x => x.PaymentReference, nullable: true).Description("Payment reference");
    }
}

public class ReceivePaymentInput
{
    public string InvoiceId { get; set; } = string.Empty;
    public decimal Amount { get; set; }
    public string BankAccountId { get; set; } = string.Empty;
    public DateTime? PaymentDate { get; set; }
    public string? BankTransactionId { get; set; }
    public string? PaymentReference { get; set; }
}

public class VoidInvoiceInputType : InputObjectGraphType<VoidInvoiceInput>
{
    public VoidInvoiceInputType()
    {
        Name = "VoidInvoiceInput";
        Description = "Input for voiding an invoice";

        Field(x => x.InvoiceId).Description("Invoice ID (required)");
        Field(x => x.Reason).Description("Reason for voiding (required)");
    }
}

public class VoidInvoiceInput
{
    public string InvoiceId { get; set; } = string.Empty;
    public string Reason { get; set; } = string.Empty;
}

// =====================================================
// CREDIT NOTE INPUT TYPES
// =====================================================

public class CreateCreditNoteInputType : InputObjectGraphType<CreateCreditNoteInput>
{
    public CreateCreditNoteInputType()
    {
        Name = "CreateCreditNoteInput";
        Description = "Input for creating a new credit note";

        Field(x => x.CompanyId).Description("Company ID (required)");
        Field(x => x.FiscalYearId).Description("Fiscal year ID (required)");
        Field(x => x.CustomerId).Description("Customer ID (required)");
        Field(x => x.CreditNoteDate, nullable: true).Description("Credit note date (defaults to today)");
        Field(x => x.OriginalInvoiceId, nullable: true).Description("Original invoice ID being credited");
        Field(x => x.CreditReason, nullable: true).Description("Reason for the credit");
        Field(x => x.VatCode, nullable: true).Description("Default VAT code (defaults to U25)");
        Field(x => x.Notes, nullable: true).Description("Internal notes");
        Field(x => x.Reference, nullable: true).Description("Customer reference");
    }
}

public class CreateCreditNoteInput
{
    public string CompanyId { get; set; } = string.Empty;
    public string FiscalYearId { get; set; } = string.Empty;
    public string CustomerId { get; set; } = string.Empty;
    public DateTime? CreditNoteDate { get; set; }
    public string? OriginalInvoiceId { get; set; }
    public string? CreditReason { get; set; }
    public string? VatCode { get; set; }
    public string? Notes { get; set; }
    public string? Reference { get; set; }
}

public class ApplyCreditNoteInputType : InputObjectGraphType<ApplyCreditNoteInput>
{
    public ApplyCreditNoteInputType()
    {
        Name = "ApplyCreditNoteInput";
        Description = "Input for applying a credit note to an invoice";

        Field(x => x.CreditNoteId).Description("Credit note ID (required)");
        Field(x => x.InvoiceId).Description("Target invoice ID (required)");
        Field(x => x.Amount).Description("Amount to apply (required)");
    }
}

public class ApplyCreditNoteInput
{
    public string CreditNoteId { get; set; } = string.Empty;
    public string InvoiceId { get; set; } = string.Empty;
    public decimal Amount { get; set; }
}
