import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"

export const VEHICLE_ROUTES = {
    INDEX: "/api/vehicles",
    BY_ID: "/api/vehicles/{id}",
    EXPORT: "/api/vehicles/export",
    IMPORT: "/api/vehicles/import",
    IMPORT_SAMPLE: "/api/vehicles/import/sample",
    GET_OWNERS: "/api/get-vehicle-owners",
    LINK_CUSTOMER: "/api/link-customer-to-vehicle",
    UNLINK_CUSTOMER: "/api/unlink-customer-from-vehicle",
} as const satisfies Record<string, ApiPath>

function buildVehicleFormData(payload: Record<string, any>): FormData {
    const fd = new FormData()
    for (const [key, value] of Object.entries(payload)) {
        if (value == null) continue
        if (value instanceof File) {
            fd.append(key, value)
        } else if (typeof value === "boolean") {
            // Laravel's `boolean` rule rejects the strings "true"/"false";
            // serialize as "1"/"0" so multipart payloads validate correctly.
            fd.append(key, value ? "1" : "0")
        } else {
            fd.append(key, String(value))
        }
    }
    return fd
}

export class VehiclesClient extends CrudClient<
    typeof VEHICLE_ROUTES.INDEX,
    typeof VEHICLE_ROUTES.BY_ID
> {
    constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
        super(
            baseUrl,
            defaultOptions,
            VEHICLE_ROUTES.INDEX,
            VEHICLE_ROUTES.BY_ID,
            VEHICLE_ROUTES.IMPORT,
            VEHICLE_ROUTES.EXPORT,
            "GET",
        )
    }


    async getById(id: string) {
        return this.get(VEHICLE_ROUTES.BY_ID, { params: { id } })
    }

    async create(payload: ApiRequestBody<typeof VEHICLE_ROUTES.INDEX, "post">) {
        const fd = buildVehicleFormData(payload)
        return this.postFormData(VEHICLE_ROUTES.INDEX, fd)
    }



    async update(id: string, payload: ApiRequestBody<typeof VEHICLE_ROUTES.BY_ID, "put">) {
        const fd = buildVehicleFormData(payload)
        fd.append("_method", "PUT")
        const url = VEHICLE_ROUTES.BY_ID.replace("{id}", id)
        return this.postFormData(url, fd)
    }

    async downloadImportSample() {
        return this.fetchBlob(VEHICLE_ROUTES.IMPORT_SAMPLE, { method: "GET" })
    }

    async getOwners(vehicleId: string | number, query?: ApiListQueryParams) {
        return this.get(VEHICLE_ROUTES.GET_OWNERS, { query: { vehicle_id: vehicleId, ...query } } as never)
    }

    async linkCustomer(payload: ApiRequestBody<typeof VEHICLE_ROUTES.LINK_CUSTOMER, "post">) {
        return this.post(VEHICLE_ROUTES.LINK_CUSTOMER, payload)
    }

    async unlinkCustomer(payload: ApiRequestBody<typeof VEHICLE_ROUTES.UNLINK_CUSTOMER, "post">) {
        return this.post(VEHICLE_ROUTES.UNLINK_CUSTOMER, payload)
    }
}

export type VehicleListResponse = NonNullable<Awaited<ReturnType<VehiclesClient["list"]>>['data']>[number]