/**
 * Cliente API — Operaciones (Embarques y documentos de transporte).
 */
import { api } from '$lib/api';

export type ShipmentStatus =
	| 'abierta' | 'booking' | 'en_transito' | 'arribado' | 'entregada' | 'cerrada' | 'cancelada';

export interface Shipment {
	id: number;
	reference: string | null;
	quote_id: number | null;
	service_request_id: number | null;
	account_id: number | null;
	operation_type: string | null;
	transport_mode: string | null;
	service_type: string | null;
	incoterm: string | null;
	origin: string | null;
	destination: string | null;
	status: ShipmentStatus;
	booking_number: string | null;
	carrier_supplier_id: number | null;
	ground_carrier_supplier_id: number | null;
	customs_agent_id: number | null;
	destination_agent_id: number | null;
	cutoff_date: string | null;
	pickup_at: string | null;
	etd: string | null;
	previous_etd: string | null;
	eta: string | null;
	vessel_flight: string | null;
	container_number: string | null;
	notes: string | null;
	actual_cost_total: number | null;
	cost_currency: string | null;
	closed_at: string | null;
	closed_by: string | null;
	owner_user_id: string | null;
	created_by: string | null;
	updated_by: string | null;
	tenant_id: number;
	company_id: number;
	created_at: string;
	updated_at: string;
}
export type ShipmentInput = Partial<Omit<Shipment, 'id' | 'tenant_id' | 'company_id' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by'>>;

export interface ShipmentEvent {
	id: number;
	shipment_id: number;
	event_type: string | null;
	title: string;
	kind: string; // hito | decision
	status: string; // pendiente | completado | omitido | rechazado | en_correccion
	outcome: string | null; // autorizado | rechazado
	parent_event_id: number | null;
	attempt: number;
	position: number;
	planned_date: string | null;
	actual_date: string | null;
	notes: string | null;
	tenant_id: number;
	company_id: number;
	created_at: string;
	updated_at: string;
}
export type ShipmentEventInput = Partial<Omit<ShipmentEvent, 'id' | 'tenant_id' | 'company_id' | 'created_at' | 'updated_at'>> & {
	shipment_id: number;
	title: string;
};

export interface ShipmentDocument {
	id: number;
	shipment_id: number;
	doc_kind: string;
	doc_type: string;
	number: string | null;
	issue_date: string | null;
	file_url: string | null;
	file_key: string | null;
	notes: string | null;
	tenant_id: number;
	company_id: number;
	created_at: string;
	updated_at: string;
}
export type ShipmentDocumentInput = Partial<Omit<ShipmentDocument, 'id' | 'tenant_id' | 'company_id' | 'created_at' | 'updated_at'>> & {
	shipment_id: number;
	doc_type: string;
};

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 shipmentsAPI = {
	list: (companyId: number, params?: { search?: string; status?: string; account_id?: number }) =>
		unwrap<Shipment[]>(api.get(`/v1/ops/shipments?${qp(companyId, params)}`)),
	get: (id: number, companyId: number) => unwrap<Shipment>(api.get(`/v1/ops/shipments/${id}?${qp(companyId)}`)),
	create: (data: ShipmentInput, companyId: number) => unwrap<Shipment>(api.post(`/v1/ops/shipments?${qp(companyId)}`, data)),
	createFromQuote: (quoteId: number, companyId: number, operationType?: string) =>
		unwrap<Shipment>(api.post(`/v1/ops/shipments/from-quote?${qp(companyId, { quote_id: quoteId, operation_type: operationType })}`, {})),
	update: (id: number, data: Partial<ShipmentInput>, companyId: number) => unwrap<Shipment>(api.patch(`/v1/ops/shipments/${id}?${qp(companyId)}`, data)),
	reschedule: (id: number, data: { etd?: string | null; cutoff_date?: string | null; reason?: string | null }, companyId: number) =>
		unwrap<Shipment>(api.post(`/v1/ops/shipments/${id}/reschedule?${qp(companyId)}`, data)),
	close: (id: number, data: { actual_cost_total: number; cost_currency?: string; notes?: string | null }, companyId: number) =>
		unwrap<Shipment>(api.post(`/v1/ops/shipments/${id}/close?${qp(companyId)}`, data)),
	remove: (id: number, companyId: number) => unwrap(api.delete(`/v1/ops/shipments/${id}?${qp(companyId)}`)),
	documents: (shipmentId: number, companyId: number) =>
		unwrap<ShipmentDocument[]>(api.get(`/v1/ops/shipments/${shipmentId}/documents?${qp(companyId)}`)),
	events: (shipmentId: number, companyId: number) =>
		unwrap<ShipmentEvent[]>(api.get(`/v1/ops/shipments/${shipmentId}/events?${qp(companyId)}`)),
	seedEvents: (shipmentId: number, companyId: number) =>
		unwrap<ShipmentEvent[]>(api.post(`/v1/ops/shipments/${shipmentId}/events/seed?${qp(companyId)}`, {}))
};

export const shipmentEventsAPI = {
	create: (data: ShipmentEventInput, companyId: number) => unwrap<ShipmentEvent>(api.post(`/v1/ops/shipment-events?${qp(companyId)}`, data)),
	update: (id: number, data: Partial<ShipmentEventInput>, companyId: number) => unwrap<ShipmentEvent>(api.patch(`/v1/ops/shipment-events/${id}?${qp(companyId)}`, data)),
	complete: (id: number, companyId: number) => unwrap<ShipmentEvent>(api.patch(`/v1/ops/shipment-events/${id}/complete?${qp(companyId)}`, {})),
	decide: (id: number, outcome: 'autorizado' | 'rechazado', companyId: number, notes?: string | null) =>
		unwrap<ShipmentEvent>(api.patch(`/v1/ops/shipment-events/${id}/decision?${qp(companyId)}`, { outcome, notes })),
	remove: (id: number, companyId: number) => unwrap(api.delete(`/v1/ops/shipment-events/${id}?${qp(companyId)}`))
};

export const shipmentDocumentsAPI = {
	create: (data: ShipmentDocumentInput, companyId: number) => unwrap<ShipmentDocument>(api.post(`/v1/ops/shipment-documents?${qp(companyId)}`, data)),
	update: (id: number, data: Partial<ShipmentDocumentInput>, companyId: number) => unwrap<ShipmentDocument>(api.patch(`/v1/ops/shipment-documents/${id}?${qp(companyId)}`, data)),
	remove: (id: number, companyId: number) => unwrap(api.delete(`/v1/ops/shipment-documents/${id}?${qp(companyId)}`))
};
