import { z } from "zod"
import { PaymentFor } from "@garage/api"

const relationFieldSchema = z
    .object({ value: z.string(), label: z.string() })
    .nullable()

const requiredRelationFieldSchema = relationFieldSchema.superRefine((value, ctx) => {
    if (!value?.value) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: "This field is required",
        })
    }
})

const optionalStringMax255Schema = z.preprocess(
    (value) => (value === "" || value == null ? undefined : value),
    z.string().max(255, "Must be at most 255 characters").optional(),
)

const detailsItemSchema = z.object({
    bill_id: z.union([z.string(), z.number()]).optional().nullable(),
    expense_id: z.union([z.string(), z.number()]).optional().nullable(),
    amount_paid: z.coerce.number().min(0).optional(),
})

const paymentMadeFormSchema = z.object({
    // ── Relations ──
    bill: relationFieldSchema,
    vendor: relationFieldSchema,
    employee: relationFieldSchema,
    payment_mode: requiredRelationFieldSchema,

    // ── Payment info ──
    amount: z.coerce.number().min(0, "Amount must be 0 or more"),
    payment_for: z.enum(PaymentFor),
    payment_number: optionalStringMax255Schema,
    payment_reference: optionalStringMax255Schema,
    payment_date: z.string().min(1, "Payment date is required").date("Enter a valid date"),
    paid_through: optionalStringMax255Schema,
    notes: z.string().optional(),
    details: z.array(detailsItemSchema).min(1, "At least one payment detail is required"),
}).superRefine((values, ctx) => {
    const hasBill = Boolean(values.bill?.value)
    const hasVendor = Boolean(values.vendor?.value)
    const hasEmployee = Boolean(values.employee?.value)

    if (values.payment_for === "bill" && !hasBill) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            path: ["bill"],
            message: "Bill is required",
        })
    }

    if (!hasVendor && !hasEmployee) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            path: ["vendor"],
            message: "Vendor or employee is required",
        })
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            path: ["employee"],
            message: "Vendor or employee is required",
        })
    }
})

type PaymentMadeFormValues = z.infer<typeof paymentMadeFormSchema>

export { paymentMadeFormSchema, relationFieldSchema }
export type { PaymentMadeFormValues }
