// composables/useQueueAPI.ts
// Composable untuk API calls terkait antrian pasien

export interface Patient {
  no: number;
  jamPanggil: string;
  barcode: string;
  noAntrian: string;
  shift: string;
  klinik: string;
  fastTrack: string;
  pembayaran: string;
  status: 'waiting' | 'pending' | 'di-loket' | 'di-klinik' | 'selesai' | 'terlambat';
  processStage: 'loket' | 'klinik' | 'penunjang';
  createdAt: string;
  registrationType?: 'online' | 'onsite';
  visitType?: string;
  visitDate?: string;
}

export interface QueueAPIResponse<T = any> {
  success: boolean;
  data?: T;
  message?: string;
  error?: string;
}

export const useQueueAPI = () => {
  const config = useRuntimeConfig();
  const baseURL = config.public.apiBaseUrl || '/api/queue';

  /**
   * Fetch all patients from database
   */
  const fetchAllPatients = async (): Promise<Patient[]> => {
    try {
      const response = await $fetch<QueueAPIResponse<Patient[]>>(`${baseURL}/patients`, {
        method: 'GET',
      });

      if (response.success && response.data) {
        return response.data;
      }
      throw new Error(response.message || 'Failed to fetch patients');
    } catch (error: any) {
      console.error('❌ Error fetching patients:', error);
      throw error;
    }
  };

  /**
   * Fetch single patient by ID or barcode
   */
  const fetchPatient = async (idOrBarcode: string): Promise<Patient | null> => {
    try {
      const response = await $fetch<QueueAPIResponse<Patient>>(`${baseURL}/patients/${idOrBarcode}`, {
        method: 'GET',
      });

      if (response.success && response.data) {
        return response.data;
      }
      return null;
    } catch (error: any) {
      console.error('❌ Error fetching patient:', error);
      return null;
    }
  };

  /**
   * Create new patient (register from Anjungan)
   */
  const createPatient = async (patientData: Partial<Patient>): Promise<Patient> => {
    try {
      const response = await $fetch<QueueAPIResponse<Patient>>(`${baseURL}/patients`, {
        method: 'POST',
        body: patientData,
      });

      if (response.success && response.data) {
        return response.data;
      }
      throw new Error(response.message || 'Failed to create patient');
    } catch (error: any) {
      console.error('❌ Error creating patient:', error);
      throw error;
    }
  };

  /**
   * Update patient status (check-in, process, etc)
   */
  const updatePatient = async (
    idOrBarcode: string,
    updates: Partial<Patient>
  ): Promise<Patient> => {
    try {
      const response = await $fetch<QueueAPIResponse<Patient>>(
        `${baseURL}/patients/${idOrBarcode}`,
        {
          method: 'PATCH',
          body: updates,
        }
      );

      if (response.success && response.data) {
        return response.data;
      }
      throw new Error(response.message || 'Failed to update patient');
    } catch (error: any) {
      console.error('❌ Error updating patient:', error);
      throw error;
    }
  };

  /**
   * Check-in patient (update status to di-loket)
   */
  const checkInPatient = async (idOrBarcode: string): Promise<Patient> => {
    return updatePatient(idOrBarcode, { status: 'di-loket' });
  };

  /**
   * Process patient at loket (update status and processStage)
   */
  const processPatientAtLoket = async (
    idOrBarcode: string,
    updates: { status?: string; processStage?: string }
  ): Promise<Patient> => {
    return updatePatient(idOrBarcode, updates);
  };

  /**
   * Sync local state with database
   */
  const syncWithDatabase = async (localPatients: Patient[]): Promise<Patient[]> => {
    try {
      // Fetch latest from database
      const dbPatients = await fetchAllPatients();
      
      // Merge strategy: prefer database data, but keep local if newer
      const merged = new Map<string, Patient>();
      
      // Add database patients
      dbPatients.forEach(patient => {
        merged.set(patient.barcode, patient);
      });
      
      // Add local patients that don't exist in DB or are newer
      localPatients.forEach(localPatient => {
        const existing = merged.get(localPatient.barcode);
        if (!existing || new Date(localPatient.createdAt) > new Date(existing.createdAt)) {
          merged.set(localPatient.barcode, localPatient);
        }
      });
      
      return Array.from(merged.values());
    } catch (error: any) {
      console.error('❌ Error syncing with database:', error);
      // Return local patients as fallback
      return localPatients;
    }
  };

  /**
   * Batch sync: save multiple patients to database
   */
  const batchSyncPatients = async (patients: Patient[]): Promise<boolean> => {
    try {
      const response = await $fetch<QueueAPIResponse>(`${baseURL}/patients/batch`, {
        method: 'POST',
        body: { patients },
      });

      return response.success || false;
    } catch (error: any) {
      console.error('❌ Error batch syncing patients:', error);
      return false;
    }
  };

  return {
    fetchAllPatients,
    fetchPatient,
    createPatient,
    updatePatient,
    checkInPatient,
    processPatientAtLoket,
    syncWithDatabase,
    batchSyncPatients,
  };
};

