/**
 * Cliente API — Módulo Tarifario (tarifarios, rutas, import Excel, costeo).
 */
import { api } from '$lib/api';

export type RateMode = 'aereo' | 'maritimo_fcl' | 'maritimo_lcl' | 'terrestre';

export interface RateBreak { from_qty: number; rate: number; }
export interface RateLane {
	id: number; rate_sheet_id: number;
	origin: string | null; destination: string | null; region: string | null;
	equipment_type: string | null; rate_unit: string | null;
	min_charge: number | null; flat_rate: number | null; transit_days: number | null; notes: string | null;
	breaks: RateBreak[];
}
export interface RateSheet {
	id: number; supplier_id: number | null; mode: RateMode; name: string;
	currency: string | null; valid_from: string | null; valid_to: string | null;
	default_origin: string | null; status: string; notes: string | null;
	source_file: string | null; created_by: string | null; updated_by: string | null;
	created_at: string; updated_at: string; lane_count: number | null;
}
export type RateSheetInput = Partial<Omit<RateSheet, 'id' | 'created_at' | 'updated_at' | 'lane_count' | 'source_file' | 'created_by' | 'updated_by'>> & {
	mode: RateMode; name: string;
};

export interface RateCharge {
	id: number; rate_sheet_id: number | null; rate_lane_id: number | null;
	concept: string; charge_type: string; value: number | null; condition: string | null;
}
export interface RateChargeInput { concept: string; charge_type: string; value?: number | null; condition?: string | null; rate_lane_id?: number | null; }

export interface ImportPreviewRow { row: number; data: Record<string, unknown>; ok: boolean; warnings: string[]; errors: string[]; }
export interface ImportPreview { mode: RateMode; total: number; valid: number; rows: ImportPreviewRow[]; columns: string[]; }

export interface CostRequest {
	mode: RateMode; origin?: string | null; destination?: string | null; on_date?: string | null;
	gross_weight_kg?: number | null; volume_m3?: number | null;
	length_cm?: number | null; width_cm?: number | null; height_cm?: number | null;
	equipment_type?: string | null; quantity?: number; dangerous?: boolean;
}
export interface CostChargeLine { concept: string; amount: number; }
export interface CostOption {
	rate_sheet_id: number; rate_sheet_name: string; supplier_id: number | null; currency: string | null;
	chargeable: number | null; base_cost: number; charges: CostChargeLine[]; total_cost: number;
	transit_days: number | null; detail: string | null;
}
export interface CostResult { request: CostRequest; options: CostOption[]; }

function qp(companyId: number, extra?: Record<string, string | number | undefined>) {
	const qs = new URLSearchParams({ company_id: String(companyId) });
	for (const [k, v] of Object.entries(extra ?? {})) if (v !== undefined && v !== '') qs.set(k, String(v));
	return qs.toString();
}
async function unwrap<T>(p: Promise<{ data?: T; error?: string }>): Promise<T> {
	const res = await p;
	if (res.error) throw new Error(res.error);
	return res.data as T;
}

export const rateSheetsAPI = {
	list: (companyId: number, params?: { mode?: string; supplier_id?: number }) =>
		unwrap<RateSheet[]>(api.get(`/v1/crm/rate-sheets?${qp(companyId, params)}`)),
	get: (id: number, companyId: number) => unwrap<RateSheet>(api.get(`/v1/crm/rate-sheets/${id}?${qp(companyId)}`)),
	create: (data: RateSheetInput, companyId: number) => unwrap<RateSheet>(api.post(`/v1/crm/rate-sheets?${qp(companyId)}`, data)),
	update: (id: number, data: Partial<RateSheetInput>, companyId: number) => unwrap<RateSheet>(api.patch(`/v1/crm/rate-sheets/${id}?${qp(companyId)}`, data)),
	remove: (id: number, companyId: number) => unwrap(api.delete(`/v1/crm/rate-sheets/${id}?${qp(companyId)}`)),
	lanes: (id: number, companyId: number) => unwrap<RateLane[]>(api.get(`/v1/crm/rate-sheets/${id}/lanes?${qp(companyId)}`)),
	addLane: (id: number, data: Partial<RateLane>, companyId: number) => unwrap<RateLane>(api.post(`/v1/crm/rate-sheets/${id}/lanes?${qp(companyId)}`, data)),
	removeLane: (id: number, laneId: number, companyId: number) => unwrap(api.delete(`/v1/crm/rate-sheets/${id}/lanes/${laneId}?${qp(companyId)}`)),
	charges: (id: number, companyId: number) => unwrap<RateCharge[]>(api.get(`/v1/crm/rate-sheets/${id}/charges?${qp(companyId)}`)),
	addCharge: (id: number, data: RateChargeInput, companyId: number) => unwrap<RateCharge>(api.post(`/v1/crm/rate-sheets/${id}/charges?${qp(companyId)}`, data)),
	removeCharge: (id: number, chargeId: number, companyId: number) => unwrap(api.delete(`/v1/crm/rate-sheets/${id}/charges/${chargeId}?${qp(companyId)}`)),

	/** Descarga la plantilla Excel del modo. */
	async downloadTemplate(mode: RateMode, companyId: number): Promise<void> {
		const blob = await api.getBlob(`/v1/crm/rate-sheets/template?${qp(companyId, { mode })}`);
		const url = URL.createObjectURL(blob);
		const a = document.createElement('a');
		a.href = url; a.download = `plantilla_tarifario_${mode}.xlsx`;
		document.body.appendChild(a); a.click(); a.remove();
		URL.revokeObjectURL(url);
	},

	async importPreview(mode: RateMode, file: File, companyId: number): Promise<ImportPreview> {
		const fd = new FormData();
		fd.append('mode', mode); fd.append('file', file);
		const res = await (api as any).request(`/v1/crm/rate-sheets/import/preview?${qp(companyId)}`, { method: 'POST', body: fd });
		if (res.error) throw new Error(res.error);
		return res.data as ImportPreview;
	},

	async importSheet(companyId: number, header: { mode: RateMode; name: string; supplier_id?: number | null; currency?: string; valid_from?: string | null; valid_to?: string | null; default_origin?: string | null }, file: File): Promise<RateSheet> {
		const fd = new FormData();
		fd.append('mode', header.mode); fd.append('name', header.name);
		if (header.supplier_id != null) fd.append('supplier_id', String(header.supplier_id));
		if (header.currency) fd.append('currency', header.currency);
		if (header.valid_from) fd.append('valid_from', header.valid_from);
		if (header.valid_to) fd.append('valid_to', header.valid_to);
		if (header.default_origin) fd.append('default_origin', header.default_origin);
		fd.append('file', file);
		const res = await (api as any).request(`/v1/crm/rate-sheets/import?${qp(companyId)}`, { method: 'POST', body: fd });
		if (res.error) throw new Error(res.error);
		return res.data as RateSheet;
	},

	quote: (req: CostRequest, companyId: number) => unwrap<CostResult>(api.post(`/v1/crm/rate-quote?${qp(companyId)}`, req)),

	/** Orígenes/destinos que existen en los tarifarios activos (para alinear el cotizador con las rutas cotizables). */
	locations: (companyId: number, mode: RateMode) =>
		unwrap<{ origins: string[]; destinations: string[] }>(api.get(`/v1/crm/rate-locations?${qp(companyId, { mode })}`))
};
