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

export const ESTIMATE_ROUTES = {
    INDEX: "/api/estimates",
    BY_ID: "/api/estimates/{id}",
    SERVICES: "/api/estimate/{id}/services",
    SERVICE_BY_ID: "/api/estimate/{id}/services/{service_id}",
    PARTS: "/api/estimate/{id}/parts",
    PART_BY_ID: "/api/estimate/{id}/parts/{part_id}",
    EXPENSE_ITEMS: "/api/estimate/{id}/expense-items",
    EXPENSE_ITEM_BY_ID: "/api/estimate/{id}/expense-items/{expense_item_id}",
    STORE_AUTHORISATION: "/api/estimates/{id}/store-authorisation",
    CONVERT_TO_JOB_CARD: "/api/estimates/{id}/convert-to-job-card",
} as const satisfies Record<string, ApiPath>

export class EstimatesClient extends CrudClient<
    typeof ESTIMATE_ROUTES.INDEX,
    typeof ESTIMATE_ROUTES.BY_ID
> {
    constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
        super(baseUrl, defaultOptions, ESTIMATE_ROUTES.INDEX, ESTIMATE_ROUTES.BY_ID)
    }

    // ── Estimate Services ──
    async listServices(estimateId: string) {
        return this.get(ESTIMATE_ROUTES.SERVICES, { params: { id: estimateId } } as never)
    }

    async addService(estimateId: string, payload: { service_id?: number; rate_type?: string; quantity?: number; rate?: string; description?: string; labor_rate_id?: number; working_hours?: string | number; labor_hours?: string | number; tax?: string; chart_of_account?: string; department_id?: number }) {
        return this.post(ESTIMATE_ROUTES.SERVICES, payload as never, { params: { id: estimateId } } as never)
    }

    async updateService(estimateId: string, serviceId: string, payload: { rate?: string; quantity?: number }) {
        return this.put(ESTIMATE_ROUTES.SERVICE_BY_ID, payload as never, { params: { id: estimateId, service_id: serviceId } } as never)
    }

    async removeService(estimateId: string, serviceId: string) {
        return this.delete(ESTIMATE_ROUTES.SERVICE_BY_ID, { params: { id: estimateId, service_id: serviceId } } as never)
    }

    // ── Estimate Parts ──
    async listParts(estimateId: string) {
        return this.get(ESTIMATE_ROUTES.PARTS, { params: { id: estimateId } }) as Promise<ApiResponse<typeof ESTIMATE_ROUTES.PARTS, "get">>
    }

    async addPart(estimateId: string, payload: { part_id?: number; quantity?: number; rate?: string; description?: string }) {
        return this.post(ESTIMATE_ROUTES.PARTS, payload as never, { params: { id: estimateId } } as never)
    }

    async updatePart(estimateId: string, partId: string, payload: { quantity?: number }) {
        return this.put(ESTIMATE_ROUTES.PART_BY_ID, payload as never, { params: { id: estimateId, part_id: partId } } as never)
    }

    async removePart(estimateId: string, partId: string) {
        return this.delete(ESTIMATE_ROUTES.PART_BY_ID, { params: { id: estimateId, part_id: partId } } as never)
    }

    // ── Estimate Expense Items ──
    async listExpenseItems(estimateId: string) {
        return this.get(ESTIMATE_ROUTES.EXPENSE_ITEMS, { params: { id: estimateId } } as never)
    }

    async addExpenseItem(estimateId: string, payload: { expense_item_id?: number; quantity?: number; rate?: string; description?: string }) {
        return this.post(ESTIMATE_ROUTES.EXPENSE_ITEMS, payload as never, { params: { id: estimateId } } as never)
    }

    async updateExpenseItem(estimateId: string, expenseItemId: string, payload: { quantity?: number }) {
        return this.put(ESTIMATE_ROUTES.EXPENSE_ITEM_BY_ID, payload as never, { params: { id: estimateId, expense_item_id: expenseItemId } } as never)
    }

    async removeExpenseItem(estimateId: string, expenseItemId: string) {
        return this.delete(ESTIMATE_ROUTES.EXPENSE_ITEM_BY_ID, { params: { id: estimateId, expense_item_id: expenseItemId } } as never)
    }

    // ── Authorisation ──
    async storeAuthorisation(estimateId: string, payload: {
        estimate_services?: { id: number; status: string }[]
        estimate_parts?: { id: number; status: string }[]
        estimate_inspections?: { id: number; status: string }[]
        estimate_expense_items?: { id: number; status: string }[]
        authorisation_method?: string
        employee_id?: number
    }) {
        return this.post(ESTIMATE_ROUTES.STORE_AUTHORISATION, payload as never, { params: { id: estimateId } } as never)
    }

    async convertToJobCard(estimateId: string, payload: ApiRequestBody<typeof ESTIMATE_ROUTES.CONVERT_TO_JOB_CARD, "post">) {
        return this.post(ESTIMATE_ROUTES.CONVERT_TO_JOB_CARD, payload, { params: { id: estimateId } })
    }
}
