import { z } from "zod"
import {
    JobCardStatus,
    EstimateTo,
    TaxInclusive,
    DiscountType,
    DiscountAt,
    FuelLevel,
} from "@garage/api"

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

const optionalStringMax255 = z.string().max(255).optional()
const optionalTimeString = z.string().max(50).optional()

const documentSchema = z.object({
    document_type_id: z.coerce.number({ error: "Document type is required" }).int(),
    customer_id: z.coerce.number().int().optional(),
    vehicle_id: z.coerce.number().int().optional(),
    document_number: z.string().optional(),
    show_in_invoice: z.boolean().optional(),
    show_in_estimate: z.boolean().optional(),
    show_in_statement: z.boolean().optional(),
})

// ── Job Card Statuses ──

export const JOB_CARD_STATUS_OPTIONS = JobCardStatus.map((v) => ({
    value: v,
    label: v
        .replace(/_/g, " ")
        .replace(/\b\w/g, (c) => c.toUpperCase()),
}))

const ESTIMATE_TO_OPTIONS = EstimateTo.map((v) => ({ value: v, label: v }))

const TAX_INCLUSIVE_OPTIONS = TaxInclusive.map((v) => ({ value: v, label: v }))

const DISCOUNT_TYPE_OPTIONS = DiscountType.map((v) => ({
    value: v,
    label: v
        .replace(/_/g, " ")
        .replace(/\b\w/g, (c) => c.toUpperCase()),
}))

const DISCOUNT_AT_OPTIONS = DiscountAt.map((v) => ({
    value: v,
    label: v
        .replace(/_/g, " ")
        .replace(/\b\w/g, (c) => c.toUpperCase()),
}))

const FUEL_LEVEL_OPTIONS = FuelLevel.map((v) => ({
    value: v,
    label: v
        .replace(/_/g, " ")
        .replace(/\b\w/g, (c) => c.toUpperCase()),
}))

const jobCardFormSchema = z.object({
    // ── Required fields ──
    title: z.string().min(1, "Title is required").max(255, "Title must be at most 255 characters"),

    // ── Relations ──
    customer: relationFieldSchema,
    vehicle: relationFieldSchema,
    estimate: relationFieldSchema.optional(),
    department: relationFieldSchema,
    service_writer: relationFieldSchema,
    primary_technician: relationFieldSchema,
    sales_person: relationFieldSchema,
    insurance_type: relationFieldSchema,
    insurer: relationFieldSchema,
    tax: relationFieldSchema,

    // ── Numbers & identifiers ──
    order_number: optionalStringMax255,
    estimate_number: optionalStringMax255,

    // ── Status & settings ──
    status: z.enum(JobCardStatus).optional(),
    estimate_to: z.enum(EstimateTo).optional(),
    tax_inclusive: z.enum(TaxInclusive).optional(),
    discount_type: z.enum(DiscountType).optional(),
    discount_amount: z.coerce.number().min(0).optional(),
    discount_at: z.enum(DiscountAt).optional(),

    // ── Dates & times ──
    order_date: z.string().optional(),
    check_in_date: z.string().optional(),
    check_in_time: optionalTimeString,
    start_date: z.string().optional(),
    start_time: optionalTimeString,
    delivery_date: z.string().optional(),
    delivery_time: optionalTimeString,

    // ── Vehicle state ──
    km_in: z.union([z.string(), z.number()]).optional(),
    fuel_level: optionalTimeString,

    // ── Boolean options ──
    has_insurance: z.boolean().optional(),
    enable_parts_issuing: z.boolean().optional(),
    enable_digital_authorisation: z.boolean().optional(),

    // ── Notes ──
    footer: z.string().optional(),
    attachments: z.string().optional(),

    // ── Customer Remarks ──
    customer_remarks: z.array(z.string()).optional(),
    documents: z.array(documentSchema).optional(),
    attachment_files: z.array(z.unknown()).max(20, "Attachment files cannot exceed 20 files").optional(),

    // ── Labels ──
    labels: z
        .array(
            z.object({
                id: z.number(),
                title: z.string(),
                color_code: z.string(),
            }),
        )
        .optional(),
    label_ids: z.array(z.coerce.number().int()).optional(),
}).superRefine((values, ctx) => {
    if (!values.customer) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            path: ["customer"],
            message: "Customer is required",
        })
    }

    if (!values.vehicle) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            path: ["vehicle"],
            message: "Vehicle is required",
        })
    }
})

type JobCardFormValues = z.infer<typeof jobCardFormSchema>

export {
    jobCardFormSchema,
    relationFieldSchema,
    TAX_INCLUSIVE_OPTIONS,
    DISCOUNT_TYPE_OPTIONS,
    DISCOUNT_AT_OPTIONS,
    ESTIMATE_TO_OPTIONS,
    FUEL_LEVEL_OPTIONS,
}
// Backward-compat alias used by job-card-status-stepper
export const JOB_CARD_STATUSES = JOB_CARD_STATUS_OPTIONS
export type { JobCardFormValues }
export type { JobCardStatus } from "@garage/api"
