/**
 * API Client para Facturas (Invoices)
 * Gestiona las operaciones CRUD para facturas y sus relaciones
 */
import { api } from '$lib/api';

export type OperationType = 'imp' | 'exp';
export type TransportType = 'none' | 'transport' | 'box' | 'licence plates' | 'truck' | 'vessel' | 'rail barge' | 'container' | 'airplane' | 'gondola' | 'flatbed';

// --- Interfaces ---

export interface InvoiceComplianceMx {
	invoice_id?: number;
	pedimento_id?: number | null;
	pedimento_r1?: number | null;
	pedimento_k1?: number | null;
	remesa?: number | null;
	// Pedimento relationship data (when joined)
	pedimento?: {
		pedimento_number?: string;
		pedimento_code?: string;
		customs_office?: string;
		license?: string;
		year?: string;
	} | null;
	aduana?: string | null;
	port_of_entry?: string | null;
	destination?: string | null;
	manifest_number?: string | null;
	provider_header?: string | null;
	provider_id?: number | null;
	sold_to_header?: string | null;
	sold_to_id?: number | null;
	shipped_to_header?: string | null;
	shipped_to_id?: number | null;
	shipped_by_header?: string | null;
	shipped_by_id?: number | null;
	customs_broker_id?: number | null;
	customs_broker_us_id?: number | null;
	broker_invoice_num?: string | null;
	broker_invoice_date?: string | null;
	is_mixed?: boolean | null;
	waste_type?: string | null;
	scrap_type?: string | null;
	appendix_17?: number | null;
	is_regime_change?: boolean | null;
	which_exchange_rate?: string | null;
	value_method?: string | null;
	act_value?: string | null;
	is_pedimento_pending?: boolean | null;
	is_owner_of_goods?: string | null;
	generate_balances?: string | null;
	was_reviewed_by_company?: boolean | null;
	edocument?: string | null;
	code_signature?: string | null;
	electronic_signature?: string | null;
	certificate_number?: string | null;
	niu_number?: string | null;
	bill_of_lading_count?: string | null;
	addendum_vu?: string | null;
	origin_destination_cove?: string | null;
	vucem_operation_num?: string | null;
	customs_person_line?: number | null;
	contingency_mode?: boolean | null;
	enclosure?: string | null;
	guide_type_to_identify?: string | null;
	location?: string | null;
	dot_code?: string | null;
	subdivision?: string | null;
	acts_as?: string | null;
	movement_type?: string | null;
	office_document?: string | null;
	reason_export?: string | null;
	signature_key?: string | null;
	sem_id?: number | null;
	rule_3121_parties_ii?: boolean | null;
}

export interface InvoiceFinancials {
	id?: number;
	invoice_id?: number;
	currency?: string | null;
	currency_type?: string | null;
	exchange_rate?: number | null;
	exchange_rate_mm?: number | null;
	value_mn?: number | null;
	value_me?: number | null;
	value_mc?: number | null;
	customs_value_mn?: number | null;
	customs_value_me?: number | null;
	raw_material_value_mn?: number | null;
	raw_material_value_me?: number | null;
	aggregate_value_mn?: number | null;
	aggregate_value_me?: number | null;
	aggregate_value_mc?: number | null;
	mexican_value_mn?: number | null;
	mexican_value_me?: number | null;
	mexican_value_mc?: number | null;
	national_packaging_mn?: number | null;
	national_packaging_me?: number | null;
	national_packaging_mc?: number | null;
	freight?: number | null;
	insurance?: number | null;
	insurance_value?: number | null;
	packaging?: number | null;
	other_increments?: number | null;
	other_deductibles?: number | null;
	total_increments_mn?: number | null;
	total_increments_me?: number | null;
	iva_mn?: number | null;
	iva_me?: number | null;
	iva_mc?: number | null;
	iva_factor?: number | null;
	tax_value_me?: number | null;
	seal_value_2500?: boolean | null;
	total_quantity?: number | null;
	gross_weight?: number | null;
	net_weight?: number | null;
	bundle_count?: number | null;
	weight_factor?: number | null;
}

export interface InvoiceLogistics {
	id?: number;
	invoice_id?: number;
	carrier_id?: string | null;
	carrier_int_id?: number | null;
	transport_id?: string | null;
	transport_int_id?: number | null;
	transport_us_id?: string | null;
	transport_type?: TransportType | null;
	transport_num?: string | null;
	transport_mode?: string | null;
	driver_name?: string | null;
	is_rail?: string | null;
	rail_id?: string | null;
	vehicle_num?: string | null;
	license_plate?: string | null;
	license_plate_complete?: string | null;
	trailer_num?: string | null;
	trailer_int_id?: number | null;
	seal_number?: string | null;
	guide_number?: string | null;
	bill_number?: string | null;
	reference_number?: string | null;
	shipment_number?: string | null;
	incoterm?: string | null;
	identifier_1?: string | null;
	complement_1?: string | null;
	identifier_2?: string | null;
	complement_2?: string | null;
	weight_type?: string | null;
	container_types?: string | null;
	vehicle_data?: string | null;
	origin_location?: string | null;
	destination_location?: string | null;
	transport_itinerary?: string | null;
	destination_goods?: string | null;
	entry_exit_date?: string | null;
	delivery_date?: string | null;
	delivered_status?: string | null;
	received_by?: string | null;
	payment_date?: string | null;
	payment_receipt_num?: string | null;
	is_ctm_process?: string | null;
	is_subdivision?: boolean | null;
	acts_as_cd?: boolean | null;
	equipment_reviewed?: boolean | null;
	pedimento_arrived?: boolean | null;
	green_light_mx?: boolean | null;
	green_light_us?: boolean | null;
	red_light_mx?: boolean | null;
	red_light_us?: boolean | null;
}

export interface InvoiceSalesDetails {
	id?: number;
	invoice_id?: number;
	line_number: number;
	sales_order?: string | null;
	colors_description?: string | null;
	square_color_code?: string | null;
	line_bundles?: number | null;
}

export interface InvoiceCollections {
	id?: number;
	invoice_id?: number;
	concept?: string | null;
	is_collected?: number | null;
	collection_date?: string | null;
	amount?: number | null;
	collector_user?: string | null;
}

export interface Invoice {
	id: number;
	tenant_id: number;
	company_id: number;
	system?: string | null;
	operation_type?: OperationType | null;
	invoice_type?: string | null;
	document_type?: string | null;
	invoice_number?: string | null;
	project_number?: string | null;
	purchase_order?: string | null;
	related_doc_id?: number | null;
	alternate_invoice?: string | null;
	invoice_ref?: string | null;
	proforma_number?: string | null;
	invoice_date?: string | null;
	capture_date: string;
	emission_date?: string | null;
	status?: "pending" | "processed" | "reversed" | boolean | null;
	processed_date?: string | null;
	who_processed?: string | null;
	capture_user?: string | null;
	traffic_light_status?: string | null;
	process_log?: string | null;
	status_rec?: number | null;
	status_rep?: string | null;
	observation_es?: string | null;
	observation_en?: string | null;
	comments_status?: string | null;
	vu_observations?: string | null;
	cfdi_uuid?: string | null;
	path_pdf?: string | null;
	path_xml?: string | null;
	subcompany?: string | null;
	party_count?: number | null;
	generate_id?: boolean | null;
	generate_desc_parties?: string | null;
	apply_manual_discount?: boolean | null;
	is_bulk?: boolean | null;
	download_substance?: boolean | null;
	download_class?: boolean | null;
	download_def?: boolean | null;
	total_items?: number | null;
	payment_terms?: string | null;
	handling_fees?: number | null;
	option_iv18?: string | null;
	enajenation_goods?: boolean | null;
	compliance_mx?: InvoiceComplianceMx | null;
	financials?: InvoiceFinancials | null;
	logistics?: InvoiceLogistics | null;
	details?: InvoiceSalesDetails[];
	collections?: InvoiceCollections[];
	// Client-side only properties
	is_selected?: boolean;
}

export interface InvoiceListResponse {
	items: Invoice[];
	total: number;
	page: number;
	page_size: number;
}

export interface CreateInvoiceData {
	system: string;
	operation_type: OperationType;
	invoice_type: string;
	document_type: string;
	invoice_number: string;
	project_number?: string | null;
	purchase_order?: string | null;
	related_doc_id?: number | null;
	alternate_invoice?: string | null;
	invoice_ref?: string | null;
	proforma_number?: string | null;
	invoice_date?: string | null;
	emission_date?: string | null;
	status?: "pending" | "processed" | "reversed" | boolean | null;
	processed_date?: string | null;
	who_processed?: string | null;
	capture_user?: string | null;
	traffic_light_status?: string | null;
	process_log?: string | null;
	status_rec?: number | null;
	status_rep?: string | null;
	observation_es?: string | null;
	observation_en?: string | null;
	comments_status?: string | null;
	vu_observations?: string | null;
	cfdi_uuid?: string | null;
	path_pdf?: string | null;
	path_xml?: string | null;
	subcompany?: string | null;
	party_count?: number | null;
	generate_id?: boolean | null;
	generate_desc_parties?: string | null;
	apply_manual_discount?: boolean | null;
	is_bulk?: boolean | null;
	download_substance?: boolean | null;
	download_class?: boolean | null;
	download_def?: boolean | null;
	payment_terms?: string | null;
	handling_fees?: number | null;
	option_iv18?: string | null;
	enajenation_goods?: boolean | null;
	compliance_mx?: Omit<InvoiceComplianceMx, 'invoice_id'> | null;
	financials?: Omit<InvoiceFinancials, 'id' | 'invoice_id'> | null;
	logistics?: Omit<InvoiceLogistics, 'id' | 'invoice_id'> | null;
	details?: Omit<InvoiceSalesDetails, 'id' | 'invoice_id'>[] | null;
	collections?: Omit<InvoiceCollections, 'id' | 'invoice_id'>[] | null;
}

export interface UpdateInvoiceData {
	id: number;  // Required by backend
	operation_type?: OperationType | null;
	invoice_type?: string | null;
	document_type?: string | null;
	invoice_number?: string | null;
	project_number?: string | null;
	purchase_order?: string | null;
	related_doc_id?: number | null;
	invoice_date?: string | null;
	traffic_light_status?: string | null;
	process_log?: string | null;
	observation_es?: string | null;
	observation_en?: string | null;
	comments_status?: string | null;
	cfdi_uuid?: string | null;
	path_pdf?: string | null;
	path_xml?: string | null;
	status?: "pending" | "processed" | "reversed" | boolean | null;
	compliance_mx?: Partial<InvoiceComplianceMx> | null;
	financials?: Partial<InvoiceFinancials> | null;
	logistics?: Partial<InvoiceLogistics>[] | null;
	details?: Partial<InvoiceSalesDetails>[] | null;
	collections?: Partial<InvoiceCollections>[] | null;
}

/**
 * API para Facturas
 */
export const invoicesApi = {
	/**
	 * Lista todas las facturas con paginación
	 */
	list: (companyId: number, page = 1, pageSize = 50, filters?: Record<string, any>) => {
		const params = new URLSearchParams({
			company_id: companyId.toString(),
			page: page.toString(),
			page_size: pageSize.toString()
		});

		// Agregar filtros si existen
		if (filters) {
			Object.entries(filters).forEach(([key, value]) => {
				if (value !== null && value !== undefined && value !== '') {
					params.append(key, String(value));
				}
			});
		}

		return api.get<InvoiceListResponse>(`/v1/a76/invoices/?${params.toString()}`);
	},

	/**
	 * Obtiene una factura por ID
	 */
	get: (invoiceId: number, companyId: number) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.get<Invoice>(`/v1/a76/invoices/${invoiceId}?${params.toString()}`);
	},

	/**
	 * Crea una nueva factura
	 */
	create: (companyId: number, data: CreateInvoiceData) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.post<Invoice>(`/v1/a76/invoices/?${params.toString()}`, data);
	},

	/**
	 * Actualiza una factura existente
	 */
	update: (invoiceId: number, companyId: number, data: UpdateInvoiceData) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.put<Invoice>(`/v1/a76/invoices/${invoiceId}?${params.toString()}`, data);
	},

	/**
	 * Elimina una factura
	 */
	delete: (invoiceId: number, companyId: number) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.delete(`/v1/a76/invoices/${invoiceId}?${params.toString()}`);
	},

	/**
	 * Obtiene datos para la creación de una factura (catálogos consolidados)
	 */
	getCreationData: (companyId: number, operationType: string, invoiceType?: string | null) => {
		const params = new URLSearchParams({
			company_id: companyId.toString(),
			operation_type: operationType
		});
		if (invoiceType) {
			params.set('invoice_type', invoiceType);
		}
		return api.get<any>(`/v1/a76/invoices/creation-data?${params.toString()}`);
	},

	/**
	 * Obtiene datos para la edición de una factura (catálogos consolidados + factura)
	 */
	getEditionData: (invoiceId: number, companyId: number) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.get<any>(`/v1/a76/invoices/${invoiceId}/edition-data?${params.toString()}`);
	},

	// --- Nested Resources ---

	/**
	 * Logística de factura
	 */
	logistics: {
		list: (invoiceId: number, companyId: number) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.get<InvoiceLogistics[]>(`/v1/a76/invoices/${invoiceId}/logistics/?${params.toString()}`);
		},

		create: (invoiceId: number, companyId: number, data: Omit<InvoiceLogistics, 'id' | 'invoice_id'>) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.post<InvoiceLogistics>(`/v1/a76/invoices/${invoiceId}/logistics/?${params.toString()}`, data);
		},

		delete: (invoiceId: number, logisticsId: number, companyId: number) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.delete(`/v1/a76/invoices/${invoiceId}/logistics/${logisticsId}/?${params.toString()}`);
		}
	},

	/**
	 * Detalles de venta de factura
	 */
	details: {
		list: (invoiceId: number, companyId: number) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.get<InvoiceSalesDetails[]>(`/v1/a76/invoices/${invoiceId}/details/?${params.toString()}`);
		},

		create: (invoiceId: number, companyId: number, data: Omit<InvoiceSalesDetails, 'id' | 'invoice_id'>) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.post<InvoiceSalesDetails>(`/v1/a76/invoices/${invoiceId}/details/?${params.toString()}`, data);
		},

		delete: (invoiceId: number, detailId: number, companyId: number) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.delete(`/v1/a76/invoices/${invoiceId}/details/${detailId}/?${params.toString()}`);
		}
	},

	/**
	 * Cobranzas de factura
	 */
	collections: {
		list: (invoiceId: number, companyId: number) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.get<InvoiceCollections[]>(`/v1/a76/invoices/${invoiceId}/collections/?${params.toString()}`);
		},

		create: (invoiceId: number, companyId: number, data: Omit<InvoiceCollections, 'id' | 'invoice_id'>) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.post<InvoiceCollections>(`/v1/a76/invoices/${invoiceId}/collections/?${params.toString()}`, data);
		},

		delete: (invoiceId: number, collectionId: number, companyId: number) => {
			const params = new URLSearchParams({
				company_id: companyId.toString()
			});
			return api.delete(`/v1/a76/invoices/${invoiceId}/collections/${collectionId}/?${params.toString()}`);
		}
	},

	processInvoice: (invoiceId: number, companyId: number) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.post<{ task_id: string }>(
			`/v1/a76/invoices/${invoiceId}/process?${params.toString()}`,
			{}
		);
	},

	getProcessStatus: (taskId: string) => {
		return api.get<{
			state: 'PROCESSING' | 'SUCCESS' | 'FAILURE';
			info?: { current: number; status: string };
			result?: {
				status: 'success' | 'validation_error' | 'error';
				invoice_id?: number;
				message?: string;
				errors?: Array<{ field: string; message: string; code?: string; solution?: string[] }>;
				sql_errors?: Array<{ consecutive: number; error: string }>;
			};
		}>(`/v1/a76/invoices/process/${taskId}/status`);
	},

	revertInvoice: (invoiceId: number, companyId: number) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.post<{ task_id: string }>(
			`/v1/a76/invoices/${invoiceId}/revert?${params.toString()}`,
			{}
		);
	},

	getRevertStatus: (taskId: string) => {
		return api.get<{
			state: 'PROCESSING' | 'SUCCESS' | 'FAILURE';
			info?: { current: number; status: string };
			result?: {
				status: 'success' | 'validation_error' | 'error';
				invoice_id?: number;
				message?: string;
				errors?: Array<{ field: string; message: string; code?: string; solution?: string[] }>;
				sql_errors?: Array<{ consecutive: number; error: string }>;
			};
		}>(`/v1/a76/invoices/revert/${taskId}/status`);
	},

	generateCove: (invoiceId: number, companyId: number, recipientEmail?: string | null) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		const body: Record<string, unknown> = {
			company_id: companyId
		};
		if (recipientEmail) {
			body.recipient_email = recipientEmail;
		}
		return api.post<{ task_id: string }>(
			`/v1/a76/factura-cove/invoices/${invoiceId}/cove?${params.toString()}`,
			body
		);
	},

	getCoveStatus: (taskId: string) => {
		return api.get<{
			state: 'PROCESSING' | 'SUCCESS' | 'FAILURE';
			info?: { current: number; status: string };
			result?: {
				status: 'success' | 'validation_error' | 'error';
				invoice_id?: number;
				cove_number?: string;
				vucem_operation_num?: string;
				message?: string;
				errors?: Array<{ field: string; message: string; code?: string; solution?: string[] }>;
			};
		}>(`/v1/a76/factura-cove/invoices/cove/${taskId}/status`);
	},

	checkCoveEligibility: (invoiceId: number, companyId: number) => {
		const params = new URLSearchParams({
			company_id: companyId.toString()
		});
		return api.get<{
			can_generate: boolean;
			reasons: Array<{ field: string; message: string }>;
		}>(`/v1/a76/factura-cove/invoices/${invoiceId}/cove/eligibility?${params.toString()}`);
	},

	getCoveReceipt: (invoiceId: number, companyId: number, forceRefresh = false): Promise<Blob> => {
		const params = new URLSearchParams({ company_id: companyId.toString() });
		if (forceRefresh) params.set('force_refresh', 'true');
		return api.getBlob(
			`/v1/a76/factura-cove/invoices/${invoiceId}/cove/acuse?${params.toString()}`
		);
	}
};
