// composables/useQueue.js
import { ref, computed } from "vue";
import { useQueueStore } from "../stores/queueStore";
import { useLoketStore } from "../stores/loketStore";

export const useQueue = (adminType = "loket", specificId = null) => {
  const queueStore = useQueueStore();
  const loketStore = useLoketStore();
  
  // Normalize specificId to a reactive value
  const idValue = computed(() => {
    if (typeof specificId === 'function') return specificId();
    if (specificId && typeof specificId === 'object' && 'value' in specificId) return specificId.value;
    return specificId;
  });

  // Local state
  const snackbar = ref(false);
  const snackbarText = ref("");
  const snackbarColor = ref("success");

  // Dialog states
  const showKlinikDialog = ref(false);
  const showPenunjangDialog = ref(false);
  const showChangeKlinikDialog = ref(false);
  const klinikSearch = ref("");
  const penunjangSearch = ref("");
  const changeKlinikSearch = ref("");
  const selectedPatientForPenunjang = ref(null);

  // FIXED: Get stage patients once, then derive others from it
  const stagePatients = computed(() => {
    // Don't use .value here - getPatientsByStage returns a computed already
    const patients = queueStore.getPatientsByStage(adminType);
    return patients.value;
  });

  // Computed from store - isolated by specificId if provided
  const currentProcessingPatient = computed(() => {
    const key = idValue.value ? `${adminType}-${idValue.value}` : adminType;
    return queueStore.currentProcessingPatient[key];
  });

  // Derive from stagePatients - ADD DEBUG LOGS
  const diLoketPatients = computed(() => {
    const patients = stagePatients.value.diLoket || [];
    console.log('🔍 useQueue - diLoketPatients:', patients.length);
    if (patients.length > 0) {
      console.log('🔍 First diLoket patient:', patients[0]);
      console.log('🔍 First diLoket patient fastTrack:', patients[0].fastTrack);
    }
    return patients;
  });
  
  const terlambatPatients = computed(() => {
    const patients = stagePatients.value.terlambat || [];
    console.log('🔍 useQueue - terlambatPatients:', patients.length);
    return patients;
  });
  
  const pendingPatients = computed(() => {
    const patients = stagePatients.value.pending || [];
    console.log('🔍 useQueue - pendingPatients:', patients.length);
    return patients;
  });
  
  const anjunganPatients = computed(() => stagePatients.value.anjungan || []);
  
  // Pasien yang belum dipanggil (status "menunggu")
  const menungguPatients = computed(() => stagePatients.value.menunggu || []);

  const nextPatient = computed(() => {
    // Prioritaskan pasien menunggu, baru anjungan
    return menungguPatients.value[0] || anjunganPatients.value[0] || null;
  });

  // Total pasien hanya untuk stage admin ini
  const totalPasien = computed(() => {
    const total = queueStore.getTotalPasienByStage(adminType);
    return total.value;
  });

  // Helper to check if a patient is relevant to the current admin view
  const isPatientRelevant = (p) => {
    if (p.processStage !== adminType) return false;
    const targetId = idValue.value;
    if (!targetId) return true; // No specific ID, show all for this stage

    if (adminType === 'loket') {
      const thisLoket = loketStore.getLoketById(parseInt(targetId));
      if (!thisLoket) return String(p.loketId) === String(targetId);

      // Must be assigned to this loket OR unassigned but clinic is served by this loket
      const isAssignedToThis = p.loketId && String(p.loketId) === String(targetId);
      const isServedByThis = !p.loketId && thisLoket.pelayanan && Array.isArray(thisLoket.pelayanan) && thisLoket.pelayanan.includes(p.kodeKlinik);
      
      // User requested "match loket id AND klinik id" logic for calling? 
      // Actually, "match loket and clinic" usually means: 
      // if it has a clinic, it must be in our services.
      // let's be strict: clinic must ALWAYS be in services if loketId is specified
      if (thisLoket.pelayanan && Array.isArray(thisLoket.pelayanan)) {
         if (!thisLoket.pelayanan.includes(p.kodeKlinik)) return false;
      }

      return isAssignedToThis || isServedByThis;
    } 
    
    if (adminType === 'klinik') {
      // Filter by clinic code or clinic name
      return String(p.kodeKlinik) === String(targetId) || String(p.klinik) === String(targetId);
    }

    if (adminType === 'penunjang') {
      // Penunjang usually uses clinic name as the identifier in seeds
      return String(p.klinik) === String(targetId) || String(p.kodeKlinik) === String(targetId);
    }

    return true;
  };

  // 1. Menunggu Count (Backlog ONLY - Strictly status 'menunggu')
  const menungguCount = computed(() => {
    let list = menungguPatients.value || [];
    return list.filter(isPatientRelevant).length;
  });

  // 2. Calculated Quota Used (Dynamic - any ticket NOT 'menunggu' counts as used)
  const calculatedQuotaUsed = computed(() => {
    const list = queueStore.allPatients || [];
    return list.filter(p => {
      if (!isPatientRelevant(p)) return false;
      // Status is NOT 'menunggu' (meaning it's being served or finished)
      return p.status !== 'menunggu';
    }).length;
  });

  const quotaUsed = computed(() => calculatedQuotaUsed.value);

  // Expose dev helper to refresh seed data
  const resetPatients = () => queueStore.resetPatients();

  // Filtered lists
  const filteredKliniks = computed(() => {
    if (!klinikSearch.value) return queueStore.kliniks;
    return queueStore.kliniks.filter((k) =>
      k.name.toLowerCase().includes(klinikSearch.value.toLowerCase())
    );
  });

  const filteredPenunjangs = computed(() => {
    if (!penunjangSearch.value) return queueStore.penunjangs;
    return queueStore.penunjangs.filter((p) =>
      p.name.toLowerCase().includes(penunjangSearch.value.toLowerCase())
    );
  });

  const filteredChangeKliniks = computed(() => {
    if (!changeKlinikSearch.value) return queueStore.kliniks;
    return queueStore.kliniks.filter((k) =>
      k.name.toLowerCase().includes(changeKlinikSearch.value.toLowerCase())
    );
  });

  // Methods
  const showSnackbar = (text, color = "success") => {
    snackbarText.value = text;
    snackbarColor.value = color;
    snackbar.value = true;
  };

  const callNext = (specificIdOverride = null) => {
    const targetId = specificIdOverride || idValue.value;
    const result = queueStore.callNext(adminType, targetId);
    showSnackbar(result.message, result.success ? "success" : "warning");
  };

  const callMultiplePatients = (count, specificIdOverride = null) => {
    const targetId = specificIdOverride || idValue.value;
    const result = queueStore.callMultiplePatients(count, adminType, targetId);
    showSnackbar(result.message, result.success ? "success" : "warning");
  };

  const processPatient = (patient, action) => {
    const result = queueStore.processPatient(patient, action, adminType, idValue.value);

    let color = "success";
    if (action === "terlambat") color = "warning";
    else if (action === "pending") color = "info";

    showSnackbar(result.message, color);
  };

  // Helper function untuk mendapatkan pasien yang sedang diproses dari store
  const getCurrentProcessingPatientFromStore = () => {
    try {
      const key = idValue.value ? `${adminType}-${idValue.value}` : adminType;
      const processingPatient = queueStore.currentProcessingPatient?.[key];
      if (!processingPatient) return null;
      
      // Dapatkan data terbaru dari allPatients langsung (bukan dari getPatientsByStage yang sudah difilter)
      // allPatients adalah ref yang di-export dari Pinia store, bisa diakses langsung atau dengan .value
      // Coba akses langsung dulu, jika undefined baru coba dengan .value
      let allPatients = [];
      if (queueStore.allPatients) {
        // Jika allPatients adalah ref (punya .value)
        allPatients = Array.isArray(queueStore.allPatients) 
          ? queueStore.allPatients 
          : (queueStore.allPatients.value || []);
      }
      
      // Cari pasien berdasarkan no, barcode, atau noAntrian
      const latestPatient = allPatients.find(
        p => (p && p.no === processingPatient.no) || 
             (p && p.barcode && p.barcode === processingPatient.barcode) ||
             (p && p.noAntrian && p.noAntrian === processingPatient.noAntrian)
      );
      
      // Jika ditemukan, return data terbaru, jika tidak return data dari currentProcessingPatient
      return latestPatient || processingPatient;
    } catch (error) {
      console.error('Error in getCurrentProcessingPatientFromStore:', error);
      // Fallback: return processingPatient dari store jika ada
      return queueStore.currentProcessingPatient?.[adminType] || null;
    }
  };

  const selectKlinik = (klinik) => {
    // Pastikan currentProcessingPatient valid, jika tidak, coba dapatkan dari store
    let patient = currentProcessingPatient.value || getCurrentProcessingPatientFromStore();
    
    if (!patient) {
      showSnackbar("Tidak ada pasien yang sedang diproses", "error");
      showKlinikDialog.value = false;
      return;
    }
    
    const result = queueStore.createAntreanKlinik(klinik, patient, adminType);
    showSnackbar(result.message, "success");
    showKlinikDialog.value = false;
  };

  const selectPenunjang = (penunjang) => {
    // Pastikan currentProcessingPatient valid, jika tidak, coba dapatkan dari store
    let patient = currentProcessingPatient.value || getCurrentProcessingPatientFromStore();
    
    if (!patient) {
      showSnackbar("Tidak ada pasien yang sedang diproses", "error");
      showPenunjangDialog.value = false;
      selectedPatientForPenunjang.value = null;
      return;
    }
    
    const result = queueStore.createAntreanPenunjang(
      penunjang,
      patient,
      adminType
    );
    showSnackbar(result.message, "success");
    showPenunjangDialog.value = false;
    selectedPatientForPenunjang.value = null;
  };

  const openPenunjangDialog = (patient = null) => {
    selectedPatientForPenunjang.value = patient;
    showPenunjangDialog.value = true;
  };

  const changeKlinik = (klinik) => {
    // Pastikan currentProcessingPatient valid, jika tidak, coba dapatkan dari store
    let patient = currentProcessingPatient.value || getCurrentProcessingPatientFromStore();
    
    if (!patient) {
      showSnackbar("Tidak ada pasien yang sedang diproses", "error");
      showChangeKlinikDialog.value = false;
      return;
    }
    
    const result = queueStore.changeKlinik(
      patient,
      klinik,
      adminType
    );
    showSnackbar(result.message, result.success ? "success" : "error");
    showChangeKlinikDialog.value = false;
  };

  const processNextQueue = () => {
    const result = queueStore.processNextQueue(adminType, idValue.value);
    showSnackbar(result.message, result.success ? "success" : "warning");
  };

  const getRowClass = (item) => {
    if (item.status === "current") {
      return "text-success font-weight-bold";
    }
    return "";
  };

  return {
    // State
    snackbar,
    snackbarText,
    snackbarColor,
    showKlinikDialog,
    showPenunjangDialog,
    showChangeKlinikDialog,
    klinikSearch,
    penunjangSearch,
    changeKlinikSearch,
    selectedPatientForPenunjang,

    // Computed
    currentProcessingPatient,
    diLoketPatients,
    terlambatPatients,
    pendingPatients,
    anjunganPatients,
    menungguPatients,
    nextPatient,
    totalPasien,
    quotaUsed,
    filteredKliniks,
    filteredPenunjangs,
    filteredChangeKliniks,
    stagePatients,

    // Methods
    showSnackbar,
    callNext,
    callMultiplePatients,
    processPatient,
    selectKlinik,
    selectPenunjang,
    openPenunjangDialog,
    changeKlinik,
    processNextQueue,
    getRowClass,
  };
};