import { apiFetch } from './api';
import type { APIDeviceReading } from '../devices/types';

/** Populated disease details from the diseases collection */
export interface APIDisease {
    _id: string;
    icdCode: string;
    name: string;
    bodyRegion: string;
    description: string;
    symptoms: string;
    commonTreatments: string;
}

/** Populated prescription with medication, returned inside a diagnosis */
export interface APIRelatedPrescription {
    _id: string;
    prescriptionId: string;
    dosage: string;
    frequency: string;
    startDate?: string;
    endDate?: string;
    medication?: {
        _id: string;
        genericName: string;
        brandName: string;
        pharmClass: string;
        adverseReactions: string;
    };
}

/** Raw diagnosis from the backend API */
export interface APIDiagnosis {
    _id: string;
    patientId: string;
    practitioner: string;
    icdCode: string;
    isPrediagnosis: boolean;
    hospital: string;
    diagnosisDate: string;
    diagnosisClinic?: string | null;
    notes?: string | null;
    severity?: 'mild' | 'moderate' | 'severe';
    created_at?: string;
    updated_at?: string;

    // Populated fields
    disease?: APIDisease;
    relatedPrescriptions?: APIRelatedPrescription[];

}

export interface APIPopulatedDiagnosis {
    _id: string;
    icdCode: string;
    diseaseName?: string;
    bodyRegion?: string;
    notes?: string;
    practitioner?: string;
    diagnosisClinic?: string;
    severity?: string;
    isPrediagnosis?: boolean;
}

export interface APIPopulatedPrescription {
    _id: string;
    medicationName?: string;
    dosage: string;
    frequency: string;
}

export interface APIHospitalVisit {
    _id: string;
    patientId: string;
    hospital: string;
    visitDate: string;
    admissionDate?: string;
    dischargeDate?: string;
    doctorName?: string;
    department?: string;
    dischargeSummary?: string;
    diagnoses: string[];
    created_at?: string;
    updated_at?: string;

    // Populated fields
    populatedDiagnoses?: APIPopulatedDiagnosis[];
    populatedPrescriptions?: APIPopulatedPrescription[];
}

export interface APIMedication {
    _id: string;
    genericName: string;
    brandName: string;
    route: string;
    pharmClass: string;
    indications: string;
    dosageAndAdministration: string;
    adverseReactions: string;
    warnings: string;
    contraindications: string;
    drugInteractions: string;
}

export interface APIPrescription {
    _id: string;
    prescriptionId: string;
    medicationId: string;
    medication?: APIMedication;
    dosage: string;
    frequency: string;
    startDate: string;
    endDate: string;
    patientId: string;
    diagnosisId?: string;
    created_at?: string;
    updated_at?: string;

    // Optional/virtual fields returned from population
    prescribedDate: string;
    doctorName: string;
    instructions: string;
}

/** Raw test from the backend API */
export interface APISubTest {
    name: string;
    value?: number | null;
    unit?: string | null;
    refMin?: number | null;
    refMax?: number | null;
    status: string;
}

export interface APITest {
    _id: string;
    testId: string;
    sutCode: string;
    name: string;
    date: string;
    testDescription?: string | null;
    subtests: APISubTest[];
    patientId: string;
    testType: string;
    created_at?: string;
    updated_at?: string;

    //Not in our models but included in the frontend for some reason
    practitioner?: string | null;
}

export interface APIGraphPresetDateRange {
    startDate?: string;
    endDate?: string;
}

export interface APIGraphDatasetOrigin {
    dateFilterMode: 'preset' | 'custom';
    selectedPreset?: 'all' | '1m' | '3m' | '6m' | '12m';
    appliedDateRange: APIGraphPresetDateRange;
}

export interface APIGraphCreationContext {
    datasetIds: string[];
    datasetNames: string[];
    dateFilterMode?: 'preset' | 'custom';
    selectedPreset?: 'all' | '1m' | '3m' | '6m' | '12m';
    appliedDateRange?: APIGraphPresetDateRange;
    datasetOrigins: Record<string, APIGraphDatasetOrigin>;
    searchQuery?: string;
}

export interface APIGraphDatasetConfig {
    id: string;
    name: string;
    type: 'medication' | 'line';
    unit: string;
    color: string;
    lineStyle?: 'solid' | 'dashed' | 'dotted';
    pointStyle?: 'circle' | 'square' | 'none';
    dateFilterMode: 'preset' | 'custom';
    selectedPreset?: 'all' | '1m' | '3m' | '6m' | '12m';
    appliedDateRange: APIGraphPresetDateRange;
}

export interface APIGraphPresetGraph {
    id: string;
    normalizeByReference: boolean;
    datasets: APIGraphDatasetConfig[];
    creation?: APIGraphCreationContext;
}

export interface APIGraphPreset {
    _id: string;
    patientId: string;
    name: string;
    exportedAt: string;
    graphCount: number;
    graphs: APIGraphPresetGraph[];
    created_at?: string;
    updated_at?: string;
}

export interface CreateGraphPresetPayload {
    patientId: string;
    name: string;
    exportedAt: string;
    graphCount: number;
    graphs: APIGraphPresetGraph[];
}

/** Raw vaccination from the backend API */
export interface APIVaccination {
    _id: string;
    vaccineId: string;
    patientId: string;
    name: string;
    administeredDate: string;
    administrationPlace: string;
    created_at?: string;
    updated_at?: string;
}

/** Raw radiology image from the backend API */
export interface APIRadiologyImage {
    _id: string;
    patientId: string;
    hospital: string;
    explanation: string;
    date: string;
    imageUrl?: string;
    created_at?: string;
    updated_at?: string;
}

// ── Fetch functions ──────────────────────────────────────────────────────────

export function fetchDiagnoses(patientId: string): Promise<APIDiagnosis[]> {
    return apiFetch(`/diagnoses?patientId=${patientId}`);
}

export function fetchHospitalVisits(patientId: string): Promise<APIHospitalVisit[]> {
    return apiFetch(`/hospital-visits?patientId=${patientId}`);
}

export function createHospitalVisit(payload: Partial<APIHospitalVisit>): Promise<APIHospitalVisit> {
    return apiFetch(`/hospital-visits`, {
        method: 'POST',
        body: JSON.stringify(payload),
    });
}

export function fetchPrescriptions(patientId: string): Promise<APIPrescription[]> {
    return apiFetch(`/prescriptions?patientId=${patientId}`);
}

export function createPrescription(payload: Partial<APIPrescription>): Promise<APIPrescription> {
    return apiFetch(`/prescriptions`, {
        method: 'POST',
        body: JSON.stringify(payload),
    });
}

export function searchMedications(query: string): Promise<any[]> {
    return apiFetch(`/medications/search?q=${query}`);
}

export function fetchTests(
    patientId: string,
    dateRange?: { startDate?: string; endDate?: string }
): Promise<APITest[]> {
    const params = new URLSearchParams({ patientId });
    if (dateRange?.startDate) params.set('startDate', dateRange.startDate);
    if (dateRange?.endDate) params.set('endDate', dateRange.endDate);

    return apiFetch(`/tests?${params.toString()}`);
}

export function fetchVaccinations(patientId: string): Promise<APIVaccination[]> {
    return apiFetch(`/vaccinations?patientId=${patientId}`);
}

export function fetchDeviceReadings(
    metric: string,
    startDate: string,
    endDate: string,
): Promise<APIDeviceReading[]> {
    const params = new URLSearchParams({
        metric,
        start_date: startDate,
        end_date: endDate,
    });

    return apiFetch(`/devices/data?${params.toString()}`);
}

export function createVaccination(payload: Partial<APIVaccination>): Promise<APIVaccination> {
    return apiFetch(`/vaccinations`, {
        method: 'POST',
        body: JSON.stringify(payload),
    });
}

export function fetchRadiologyImages(patientId: string): Promise<APIRadiologyImage[]> {
    return apiFetch(`/images?patientId=${patientId}`);
}

export function createRadiologyImage(payload: FormData): Promise<APIRadiologyImage> {
    return apiFetch(`/images`, {
        method: 'POST',
        body: payload,
    });
}

export function fetchGraphPresets(patientId: string): Promise<APIGraphPreset[]> {
    return apiFetch(`/graph-presets?patientId=${patientId}`);
}

export function parseTestSearchQuery(patientId: string, query: string, signal?: AbortSignal): Promise<unknown> {
    return apiFetch('/tests/search/parse', {
        method: 'POST',
        signal,
        body: JSON.stringify({ patientId, query }),
    });
}

export function createGraphPreset(payload: CreateGraphPresetPayload): Promise<APIGraphPreset> {
    return apiFetch('/graph-presets', {
        method: 'POST',
        body: JSON.stringify(payload),
    });
}

export function updateGraphPreset(presetId: string, payload: Partial<CreateGraphPresetPayload> & { name?: string }): Promise<APIGraphPreset> {
    return apiFetch(`/graph-presets/${presetId}`, {
        method: 'PUT',
        body: JSON.stringify(payload),
    });
}

export function deleteGraphPreset(presetId: string): Promise<{ ok: boolean }> {
    return apiFetch(`/graph-presets/${presetId}`, {
        method: 'DELETE',
    });
}

export function deleteGraphPresetsByPatient(patientId: string): Promise<{ ok: boolean; deletedCount: number }> {
    const params = new URLSearchParams({ patientId });
    return apiFetch(`/graph-presets?${params.toString()}`, {
        method: 'DELETE',
    });
}

export function deleteTestsByPatient(patientId: string): Promise<{ ok: boolean; deletedCount: number }> {
    const params = new URLSearchParams({ patientId });
    return apiFetch(`/tests?${params.toString()}`, {
        method: 'DELETE',
    });
}

export function deleteTestById(testId: string): Promise<{ ok: boolean }> {
    return apiFetch(`/tests/${testId}`, {
        method: 'DELETE',
    });
}

export function updateTestById(testId: string, payload: Partial<APITest>): Promise<APITest> {
    return apiFetch(`/tests/${testId}`, {
        method: 'PATCH',
        body: JSON.stringify(payload),
    });
}


export function createDiagnosis(payload: Partial<APIDiagnosis>): Promise<APIDiagnosis> {
    return apiFetch(`/diagnoses`, {
        method: 'POST',
        body: JSON.stringify(payload),
    });
}

export function updateDiagnosis(diagnosisId: string, payload: Partial<APIDiagnosis>): Promise<APIDiagnosis> {
    return apiFetch(`/diagnoses/${diagnosisId}`, {
        method: 'PATCH',
        body: JSON.stringify(payload),
    });
}

export function deleteDiagnosis(diagnosisId: string): Promise<{ ok: boolean }> {
    return apiFetch(`/diagnoses/${diagnosisId}`, {
        method: 'DELETE',
    });
}

export function updatePrescription(prescriptionId: string, payload: Partial<APIPrescription>): Promise<APIPrescription> {
    return apiFetch(`/prescriptions/${prescriptionId}`, {
        method: 'PATCH',
        body: JSON.stringify(payload),
    });
}

export function deletePrescription(prescriptionId: string): Promise<{ ok: boolean }> {
    return apiFetch(`/prescriptions/${prescriptionId}`, {
        method: 'DELETE',
    });
}

export function updateHospitalVisit(visitId: string, payload: Partial<APIHospitalVisit>): Promise<APIHospitalVisit> {
    return apiFetch(`/hospital-visits/${visitId}`, {
        method: 'PATCH',
        body: JSON.stringify(payload),
    });
}

export function deleteHospitalVisit(visitId: string): Promise<{ ok: boolean }> {
    return apiFetch(`/hospital-visits/${visitId}`, {
        method: 'DELETE',
    });
}

/**
 * Handle multipart/form-data PDF upload to the OCR endpoint.
 */
export async function uploadTestOCR(file: File): Promise<any> {
    const formData = new FormData();
    formData.append('file', file);
    return apiFetch('/tests/ocr', {
        method: 'POST',
        body: formData,
    });
}

/**
 * Submit corrected/verified JSON to the ingest endpoint.
 */
export async function ingestTestJSON(payload: any): Promise<APITest> {
    return apiFetch('/tests/json', {
        method: 'POST',
        body: JSON.stringify(payload),
    });
}
