import { api, type ApiResponse } from '$lib/api';

export interface ExpedienteArchivo {
	id: number;
	e_document?: string | null;
	num_operacion?: string | null;
	tipo_documento?: string | null;
	archivo_digitalizado_en?: string | null;
	fecha_digitalizacion?: string | null;
	agente_aduanal?: string | null;
	pedimento?: string | null;
	rfc_consulta?: string | null;
	nombre_archivo?: string | null;
	status?: string | null;
	task_id?: string | null;
	external_task_id?: string | null;
	acuse_pdf_path?: string | null;
	envio_xml_path?: string | null;
	respuesta_xml_path?: string | null;
	consulta_envio_xml_path?: string | null;
	consulta_respuesta_xml_path?: string | null;
	company_id: number;
	tenant_id: number;
}

export interface ExpedienteArchivoListResponse {
	items: ExpedienteArchivo[];
	total: number;
	page: number;
	page_size: number;
}

export interface ExpedienteArchivoCreateDTO {
	e_document?: string | null;
	num_operacion?: string | null;
	tipo_documento?: string | null;
	archivo_digitalizado_en?: string | null;
	fecha_digitalizacion?: string | null;
	agente_aduanal?: string | null;
	pedimento?: string | null;
	rfc_consulta?: string | null;
	nombre_archivo?: string | null;
}

export interface DigitalizarRequest {
	rfc_consulta?: string | null;
	clave_documento?: string | null;
	nombre_archivo?: string | null;
	archivo_base64?: string | null;
}

export interface DigitalizarResponse {
	task_id: string;
	message: string;
	status: string;
}

export interface ExpedienteArchivoUploadResponse {
	message: string;
	record_id: number;
	path: string;
	nombre_archivo?: string | null;
}

export interface DigitalizacionResult {
	status?: string | null;
	message?: string | null;
	request_id?: string | null;
	response_code?: number | null;
	e_document?: string | null;
	numero_operacion?: string | null;
	nombre_archivo?: string | null;
	timestamp?: string | null;
	acuese_digitalizacion_pdf_base64?: string | null;
	envio_xml_base64?: string | null;
	respuesta_xml_base64?: string | null;
	consulta_envio_xml_base64?: string | null;
	consulta_respuesta_xml_base64?: string | null;
}

export interface DigitalizacionErrorDetail {
	codigo?: string | null;
	descripcion?: string | null;
	paso?: string | null;
	sugerencias?: string[] | null;
}

export interface DigitalizacionTaskDetailResponse {
	task_id: string;
	external_task_id?: string | null;
	state: string;
	status?: string | null;
	current_step?: string | null;
	progress?: number | null;
	total_steps?: number | null;
	request_id?: string | null;
	result?: DigitalizacionResult | null;
	error?: string | null;
	error_type?: string | null;
	error_detail?: DigitalizacionErrorDetail | null;
	info?: Record<string, unknown> | null;
}

class ExpedienteArchivosApi {
	private baseUrl = '/v1/a76/expediente-archivos';

	async list(
		companyId: string | number,
		params?: {
			page?: number;
			page_size?: number;
			search?: string;
			status?: string;
			rfc_consulta?: string;
			e_document?: string;
		}
	): Promise<ApiResponse<ExpedienteArchivoListResponse>> {
		const queryParams = new URLSearchParams({ company_id: companyId.toString() });
		if (params) {
			for (const [k, v] of Object.entries(params)) {
				if (v != null && v !== '') queryParams.set(k, String(v));
			}
		}
		return api.get<ExpedienteArchivoListResponse>(`${this.baseUrl}?${queryParams}`);
	}

	async get(id: number, companyId: string | number): Promise<ApiResponse<ExpedienteArchivo>> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		return api.get<ExpedienteArchivo>(`${this.baseUrl}/${id}?${q}`);
	}

	async create(
		data: ExpedienteArchivoCreateDTO,
		companyId: string | number
	): Promise<ApiResponse<ExpedienteArchivo>> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		return api.post<ExpedienteArchivo>(`${this.baseUrl}?${q}`, data);
	}

	async update(
		id: number,
		data: ExpedienteArchivoCreateDTO,
		companyId: string | number
	): Promise<ApiResponse<ExpedienteArchivo>> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		return api.put<ExpedienteArchivo>(`${this.baseUrl}/${id}?${q}`, data);
	}

	async delete(id: number, companyId: string | number): Promise<ApiResponse<void>> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		return api.delete<void>(`${this.baseUrl}/${id}?${q}`);
	}

	async uploadFile(
		id: number,
		file: File,
		companyId: string | number
	): Promise<ApiResponse<ExpedienteArchivoUploadResponse>> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		const formData = new FormData();
		formData.append('file', file);
		return api.request<ExpedienteArchivoUploadResponse>(`${this.baseUrl}/${id}/upload?${q}`, {
			method: 'POST',
			body: formData
		});
	}

	async digitalizar(
		id: number,
		body: DigitalizarRequest,
		companyId: string | number
	): Promise<ApiResponse<DigitalizarResponse>> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		return api.post<DigitalizarResponse>(`${this.baseUrl}/digitalizar/${id}?${q}`, body);
	}

	async getStatusTask(taskId: string): Promise<ApiResponse<DigitalizacionTaskDetailResponse>> {
		return api.get<DigitalizacionTaskDetailResponse>(
			`${this.baseUrl}/status-digitalizacion-task/${taskId}`
		);
	}

	async downloadArtifact(
		id: number,
		artifactType: 'acuse' | 'envio-xml' | 'respuesta-xml' | 'consulta-envio-xml' | 'consulta-respuesta-xml',
		companyId: string | number,
		filename?: string
	): Promise<void> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		const endpoint = `${this.baseUrl}/${id}/artifacts/${artifactType}?${q}`;
		const blob = await api.getBlob(endpoint);
		const url = URL.createObjectURL(blob);
		const a = document.createElement('a');
		a.href = url;
		a.download = filename || `artifact_${id}`;
		a.style.display = 'none';
		document.body.appendChild(a);
		a.click();
		document.body.removeChild(a);
		URL.revokeObjectURL(url);
	}

	async downloadAllArtifactsZip(id: number, companyId: string | number, baseName?: string): Promise<void> {
		const q = new URLSearchParams({ company_id: companyId.toString() });
		const endpoint = `${this.baseUrl}/${id}/artifacts-zip?${q}`;
		const blob = await api.getBlob(endpoint);
		const url = URL.createObjectURL(blob);
		const a = document.createElement('a');
		a.href = url;
		a.download = `expediente_${baseName || id}.zip`;
		a.style.display = 'none';
		document.body.appendChild(a);
		a.click();
		document.body.removeChild(a);
		URL.revokeObjectURL(url);
	}
}

export const expedienteArchivosApi = new ExpedienteArchivosApi();
