// stores/loketStore.js
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { useClinicStore } from './clinicStore';
import { useAnjunganStore } from './anjunganStore';

// Helper function: Convert nomor loket ke huruf (1 -> A, 2 -> B, dst)
const numberToLetter = (num) => {
  if (num < 1) return 'A';
  // 1 -> A (65), 2 -> B (66), ..., 26 -> Z (90)
  const charCode = 64 + num; // 64 = '@', 65 = 'A'
  return String.fromCharCode(Math.min(charCode, 90)); // Maksimal Z (90)
};

// Helper function: Get pelayanan contoh dari master anjungan
// Mengambil data klinik dari anjungan pertama (Reguler) sebagai contoh
const getPelayananContohDariAnjungan = (anjunganItems) => {
  // Ambil data klinik dari anjungan pertama (Reguler) jika ada
  let klinikAnjunganReguler = [];
  if (anjunganItems && anjunganItems.length > 0) {
    // Cari anjungan dengan jenisPasien 'Reguler' atau ambil yang pertama
    const anjunganReguler = anjunganItems.find(a => a.jenisPasien === 'Reguler') || anjunganItems[0];
    klinikAnjunganReguler = anjunganReguler.klinik || [];
  }
  
  // Jika tidak ada data dari anjungan, gunakan data default dari master anjungan
  if (klinikAnjunganReguler.length === 0) {
    klinikAnjunganReguler = ['AN', 'AS', 'BD', 'GR', 'HO', 'GI', 'GZ', 'IP', 'JT', 'JW', 'KK', 'MT', 'OB', 'PR', 'RT', 'RM', 'SR'];
  }
  
  // Distribusi pelayanan ke beberapa loket sebagai contoh
  // Menggunakan data klinik yang tersedia dari master anjungan
  return {
    loket1: klinikAnjunganReguler.filter(k => ['AN','RT', 'RM', 'TD'].includes(k)).length > 0 
      ? klinikAnjunganReguler.filter(k => ['RT', 'RM', 'TD'].includes(k))
      : klinikAnjunganReguler.slice(0, 3), // Ambil 3 pertama jika tidak ada match
    loket2: klinikAnjunganReguler.filter(k => ['JW', 'SR'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['JW', 'SR'].includes(k))
      : klinikAnjunganReguler.slice(3, 5), // Ambil 2 berikutnya
    loket3: klinikAnjunganReguler.filter(k => ['AS', 'JT'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['AS', 'JT'].includes(k))
      : klinikAnjunganReguler.slice(5, 7), // Ambil 2 berikutnya
    loket4: klinikAnjunganReguler.filter(k => ['KK', 'PR'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['KK', 'PR'].includes(k))
      : klinikAnjunganReguler.slice(7, 9), // Ambil 2 berikutnya
    loket5: klinikAnjunganReguler.filter(k => ['BD', 'GI'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['BD', 'GI'].includes(k))
      : klinikAnjunganReguler.slice(9, 11), // Ambil 2 berikutnya
    loket6: klinikAnjunganReguler.filter(k => ['GR', 'GZ'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['GR', 'GZ'].includes(k))
      : klinikAnjunganReguler.slice(11, 13), // Ambil 2 berikutnya
    loket7: klinikAnjunganReguler.filter(k => ['IP', 'MT'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['IP', 'MT'].includes(k))
      : klinikAnjunganReguler.slice(13, 15), // Ambil 2 berikutnya
    loket8: klinikAnjunganReguler.filter(k => ['OB', 'HO'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['OB', 'HO'].includes(k))
      : klinikAnjunganReguler.slice(15, 17), // Ambil 2 berikutnya
    loket9: klinikAnjunganReguler.filter(k => ['AN', 'BD'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['AN', 'BD'].includes(k))
      : klinikAnjunganReguler.slice(0, 2), // Ambil 2 pertama jika tidak ada match
    loket10: klinikAnjunganReguler.filter(k => ['GI', 'GZ'].includes(k)).length > 0
      ? klinikAnjunganReguler.filter(k => ['GI', 'GZ'].includes(k))
      : klinikAnjunganReguler.slice(2, 4), // Ambil 2 berikutnya
  };
};


export const useLoketStore = defineStore('loket', () => {
  const clinicStore = useClinicStore();
  const anjunganStore = useAnjunganStore();

  // ============================================
  // STATE - SEPARATED DATA SOURCES
  // ============================================
  
  // API Data (JKN/REGULER) - ID 1-14 dari backend
  // TIDAK di-persist ke localStorage, selalu fetch fresh dari API
  const apiLoketData = ref([])
  
  // Local Data (EKSEKUTIF) - ID 1000+ manual input
  // DI-persist ke localStorage. Default 14 loket hardcoded.
  const localLoketData = ref(Array.from({ length: 14 }, (_, i) => {
    // Distribute services securely
    // Loket 1-5: Single service
    // Loket 6-10: Dual services
    // Loket 11+: Single service
    let services = [];
    if (i < 5) {
      services = [1000 + i];
    } else if (i < 10) {
      services = [1000 + i, 1005 + i]; 
    } else {
      services = [1000 + i];
    }

    return {
      id: 1000 + i,
      no: i + 1,
      namaLoket: `LOKET ${i + 1} EKS`,
      kuota: 500,
      pelayanan: services, 
      pembayaran: ['EKSEKUTIF'],  // Changed to array for consistency
      tipeLoket: 'EKSEKUTIF',  // Add tipeLoket field for consistency
      keterangan: 'ONLINE',
      statusPelayanan: 'RAWAT JALAN',
      source: 'local',
      loketAktif: true
    };
  }))
  
  // Merged data (computed) - Gabungan API + Local
  const loketData = computed(() => {
    // Debug log
    if (apiLoketData.value.length > 0) {
      console.log('📊 [loketData computed] API data found:', apiLoketData.value.length, 'items');
    }
    if (localLoketData.value.length > 0) {
      console.log('📊 [loketData computed] Local data found:', localLoketData.value.length, 'items');
    }
    
    // Create new objects to prevent state mutation in computed
    const merged = [
      ...apiLoketData.value.map(i => ({...i})),
      ...localLoketData.value.map(i => ({...i}))
    ]
    
    console.log('📊 [loketData computed] Merged total:', merged.length, 'items');
    
    // Sort by ID
    merged.sort((a, b) => a.id - b.id)
    
    // Recalculate sequential No
    return merged.map((item, index) => ({
      ...item,
      no: index + 1
    }))
  })

  // Computed - Available services (reference dari clinicStore)
  // Mengambil data dari clinicStore untuk dropdown pelayanan
  // Menggunakan getAllClinics computed untuk memastikan reactivity
  const availableServices = computed(() => {
    try {
      // Gunakan getAllClinics computed dari clinicStore
      // Ini akan otomatis reactive ketika clinics berubah
      const clinicsComputed = clinicStore.getAllClinics;
      
      if (!clinicsComputed) {
        console.warn('clinicStore.getAllClinics is not available');
        return [];
      }
      
      // getAllClinics adalah computed, akses .value untuk mendapatkan array
      // Vue akan otomatis track dependency ini
      const clinicsArray = clinicsComputed.value || [];
      
      // Pastikan clinicsArray adalah array
      if (!Array.isArray(clinicsArray)) {
        console.warn('getAllClinics.value is not an array:', typeof clinicsArray, clinicsArray);
        return [];
      }
      
      if (clinicsArray.length === 0) {
        console.warn('No clinics available from clinicStore');
        return [];
      }
      
      // Map ke format yang dibutuhkan form: { id, nama, kode }
      // id menggunakan kode untuk kompatibilitas dengan form yang menggunakan item-value="id"
      return clinicsArray.map(c => {
        if (!c || !c.kode || !c.name) {
          console.warn('Invalid clinic data:', c);
          return null;
        }
        return {
          id: c.kode, // Menggunakan kode sebagai id (sesuai dengan item-value="id" di form)
          nama: c.name,
          kode: c.kode,
        };
      }).filter(Boolean); // Filter out null values
    } catch (error) {
      console.error('Error getting available services from clinicStore:', error);
      return [];
    }
  });

  // Actions - CRUD Operations
  // ADD: Hanya untuk EKSEKUTIF (ID 1000+)
  const addLoket = (loketPayload) => {
    // Generate ID starting from 1000 for EKSEKUTIF
    const maxLocalId = localLoketData.value.length > 0
      ? Math.max(...localLoketData.value.map(l => l.id))
      : 999;
    
    const newId = maxLocalId + 1;
    const newNo = loketData.value.length + 1;

    const newLoket = {
      id: newId,
      no: newNo,
      ...loketPayload,
      pembayaran: loketPayload.pembayaran || ['EKSEKUTIF'],  // Ensure array format
      tipeLoket: loketPayload.tipeLoket || 'EKSEKUTIF',  // Add tipeLoket support
      source: 'local',          // Mark as local data
      loketAktif: loketPayload.loketAktif ?? true,  // Default aktif
    };

    localLoketData.value.push(newLoket);
    return { success: true, message: `Loket ${newLoket.namaLoket} berhasil ditambahkan`, data: newLoket };
  };

  // UPDATE: Hanya untuk EKSEKUTIF (source='local')
  const updateLoket = (loketPayload) => {
    // Check if trying to edit API data
    if (loketPayload.source === 'api' || (loketPayload.id >= 1 && loketPayload.id <= 100)) {
      return { success: false, message: 'Data JKN dari API tidak bisa diedit. Hanya data EKSEKUTIF yang bisa diubah.' };
    }
    
    const index = localLoketData.value.findIndex(l => l.id === loketPayload.id);
    if (index !== -1) {
      localLoketData.value[index] = {
        ...localLoketData.value[index],
        ...loketPayload,
        source: 'local',  // Ensure source stays local
        pembayaran: loketPayload.pembayaran && Array.isArray(loketPayload.pembayaran) 
          ? loketPayload.pembayaran 
          : ['EKSEKUTIF'],  // Ensure array format
        tipeLoket: loketPayload.tipeLoket || 'EKSEKUTIF',  // Add tipeLoket support
      };
      return { success: true, message: `Loket ${loketPayload.namaLoket} berhasil diupdate` };
    }
    return { success: false, message: 'Loket tidak ditemukan' };
  };

  // DELETE: Hanya untuk EKSEKUTIF (source='local')
  const deleteLoket = (loketId) => {
    // Check if trying to delete API data
    if (loketId >= 1 && loketId <= 100) {
      return { success: false, message: 'Data JKN dari API tidak bisa dihapus. Hanya data EKSEKUTIF yang bisa dihapus.' };
    }
    
    const index = localLoketData.value.findIndex(l => l.id === loketId);
    if (index !== -1) {
      const loketName = localLoketData.value[index].namaLoket;
      localLoketData.value.splice(index, 1);
      return { success: true, message: `Loket ${loketName} berhasil dihapus` };
    }
    return { success: false, message: 'Loket tidak ditemukan' };
  };

  const getLoketById = (id) => {
    return loketData.value.find(l => l.id === id);
  };

  // Helper function untuk convert nomor ke huruf (export untuk digunakan di komponen)
  const getLoketLetter = (num) => numberToLetter(num);

  // ============================================
  // API INTEGRATION
  // ============================================
  
  // State untuk API management
  const isLoadingAPI = ref(false);
  const apiError = ref(null);
  const lastSyncTimestamp = ref(null);
  let activeFetchPromise = null;
  
  /**
   * Fetch loket data dari API backend
   * MENGGUNAKAN endpoint /api/v1/klinik/loket yang sudah terstruktur per Loket
   */
  const fetchLoketFromAPI = async (force = false, retryCount = 0) => {
    if (activeFetchPromise && retryCount === 0) {
      console.log('⏳ Loket fetch in progress, reusing existing request...');
      return activeFetchPromise;
    }
    
    const hasData = apiLoketData.value && apiLoketData.value.length > 0;
    const hasCachedData = hasData && lastSyncTimestamp.value;
    
    // If we have cached data and not forcing refresh, use cache
    if (hasCachedData && !force && retryCount === 0) {
      const cacheAge = Date.now() - new Date(lastSyncTimestamp.value).getTime();
      const cacheAgeMinutes = Math.floor(cacheAge / 60000);
      console.log(`📦 Using cached API data (${cacheAgeMinutes} minutes old, ${apiLoketData.value.length} items)`);
      return { 
        success: true, 
        message: `Data tersedia dari cache (${cacheAgeMinutes} menit yang lalu)`,
        cached: true
      };
    }
    
    const performFetch = async () => {
      isLoadingAPI.value = true;
      apiError.value = null;
      
      try {
        console.log(`🔄 [loketStore] Fetching loket configuration (Try ${retryCount + 1})...`);
        const response = await fetch('http://10.10.123.140:8089/api/v1/klinik/loket');
        
        if (!response.ok) {
          if (response.status === 429 && retryCount < 3) {
            const delay = (retryCount + 1) * 1500;
            await new Promise(resolve => setTimeout(resolve, delay));
            activeFetchPromise = null;
            return fetchLoketFromAPI(force, retryCount + 1);
          }
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const rawData = await response.json();
        const loketsRaw = rawData.data || [];
        
        // MAPPING: Convert API Structure to Store Format
        const mappedLokets = loketsRaw.map(l => {
          const id = parseInt(l.idloket);
          
          // Map pelayanan (clinic codes) dan detail spesialis
          const spesialisDetail = (l.spesialis || []).map(s => {
            // Coba cari kode klinik dari clinicStore untuk konsistensi
            const clinic = clinicStore.clinics.find(c => 
              String(c.id) === String(s.idklinik) || 
              c.name === s.namaklinik
            );
            
            return {
              idklinik: s.idklinik,
              namaklinik: s.namaklinik,
              code: clinic ? clinic.kode : (s.kode || s.idklinik)
            };
          });

          // Extract unique codes for 'pelayanan' field
          const pelayananCodes = [...new Set(spesialisDetail.map(s => s.code))];

          // Map payment types as array for multiple chips display
          const pembayaranArray = (l.pembayaran || [])
            .map(p => p.pembayaran)
            .filter(Boolean);
          
          // If no payment types, default to ['JKN']
          const pembayaran = pembayaranArray.length > 0 ? pembayaranArray : ['JKN'];

          return {
            id: id,
            namaLoket: l.namaloket,
            kodeLoket: l.kodeloket,
            kuota: parseInt(l.kuotaloket) || 100,
            pelayanan: pelayananCodes,
            _spesialisDetail: spesialisDetail,
            pembayaran: pembayaran,  // Now an array instead of joined string
            tipeLoket: l.tipeloket || 'REGULER',  // Map tipeloket to tipeLoket (capital L)
            source: 'api',
            loketAktif: l.loketaktif ?? true,
            jenisloket: l.jenisloket,
            tipeloket: l.tipeloket  // Keep original for backward compatibility
          };
        });
        
        // Sort by id for stability and set sequential No
        mappedLokets.sort((a, b) => a.id - b.id);
        mappedLokets.forEach((loket, idx) => {
          loket.no = idx + 1;
        });
        
        console.log(`✅ [loketStore] Successfully mapped ${mappedLokets.length} lokets from API`);
        
        apiLoketData.value = mappedLokets;
        lastSyncTimestamp.value = new Date().toISOString();
        
        return { 
          success: true, 
          message: `${mappedLokets.length} loket berhasil dikonfigurasi`,
          data: mappedLokets 
        };
        
      } catch (error) {
        console.error('❌ [loketStore] Error fetching loket config:', error);
        apiError.value = error.message;

        // FALLBACK 1: Use cached data if available
        if (apiLoketData.value.length > 0) {
          const cacheAge = lastSyncTimestamp.value 
            ? Math.floor((Date.now() - new Date(lastSyncTimestamp.value).getTime()) / 60000)
            : 'unknown';
          console.warn(`⚠️ [loketStore] API failed, using cached data (${cacheAge} minutes old)`);
          return { 
            success: true, 
            message: `API gagal, menggunakan data cache (${cacheAge} menit yang lalu)`,
            warning: true,
            cached: true
          };
        }

        // FALLBACK 2: If no cache, populate with dummy Reguler data for Dev/Offline mode
        console.warn('⚠️ [loketStore] No cache available, using FALLBACK dummy data...');
        const dummyLokets = Array.from({length: 6}, (_, i) => ({
           id: i + 1,
           namaLoket: `LOKET ${i + 1} REG (Mock)`,
           kodeLoket: `L${i+1}`,
           kuota: 100,
           pelayanan: ['UM', 'BP', 'OB', 'AN', 'IP', 'SR', 'TH', 'MT', 'KK', 'PR'], // Mock all services
           _spesialisDetail: [], // Empty detail
           pembayaran: ['BPJS', 'UMUM'],  // Changed to array for consistency
           tipeLoket: 'REGULER',  // Add tipeLoket for fallback data
           source: 'api', // Mimic API
           loketAktif: true,
           jenisloket: 'REGULER',
           tipeloket: 'REGULER',
           no: i + 1
        }));
        apiLoketData.value = dummyLokets;
        return { success: true, message: 'Menggunakan data fallback (API Offline)', warning: true };

        return { success: false, message: `Gagal memuat: ${error.message}` };
      } finally {
        isLoadingAPI.value = false;
        activeFetchPromise = null;
      }
    };
    
    activeFetchPromise = performFetch();
    return activeFetchPromise;
  };

  /**
   * Fetch detail data for a SPECIFIC loket
   * Endpoint: /api/v1/loket/:loketid
   */
  const fetchSingleLoketFromAPI = async (loketId) => {
    if (!loketId) return { success: false, message: 'ID Loket diperlukan' };
    
    isLoadingAPI.value = true;
    apiError.value = null;

    try {
      console.log(`🔄 [loketStore] Fetching detail for loket ${loketId}...`);
      const response = await fetch(`http://10.10.123.140:8089/api/v1/loket/${loketId}`);
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const rawData = await response.json();
      
      if (rawData.metadata && rawData.metadata.code !== 200) {
        throw new Error(rawData.message || 'API returned error status');
      }

      // Check if data is array or single object
      const data = rawData.data;
      if (!data) throw new Error('No data returned from API');

      // The API /api/v1/loket/:id seems to return structure similar to /api/v1/klinik/loket 
      // but filtered for one loket. Let's handle both array and object.
      const l = Array.isArray(data) ? data[0] : data;
      
      if (!l) throw new Error('Loket data empty');

      // Map to store format
      const id = parseInt(l.idloket || l.id);
      
      const spesialisDetail = (l.spesialis || []).map(s => {
        const clinic = clinicStore.clinics.find(c => 
          String(c.id) === String(s.idklinik) || 
          c.name === s.namaklinik
        );
        return {
          idklinik: s.idklinik,
          namaklinik: s.namaklinik,
          code: clinic ? clinic.kode : (s.kode || s.idklinik)
        };
      });

      const pelayananCodes = [...new Set(spesialisDetail.map(s => s.code))];
      const pembayaranArray = (l.pembayaran || []).map(p => p.pembayaran).filter(Boolean);
      const pembayaran = pembayaranArray.length > 0 ? pembayaranArray : ['JKN'];

      const mapped = {
        id: id,
        namaLoket: l.namaloket,
        kodeLoket: l.kodeloket,
        kuota: parseInt(l.kuotaloket) || 100, // Kuota is part of the detail but we keep it
        pelayanan: pelayananCodes,
        _spesialisDetail: spesialisDetail,
        pembayaran: pembayaran,
        tipeLoket: l.tipeloket || 'REGULER',
        source: 'api',
        loketAktif: l.loketaktif ?? true,
        jenisloket: l.jenisloket,
        tipeloket: l.tipeloket
      };

      // Sync to apiLoketData
      const index = apiLoketData.value.findIndex(item => item.id === id);
      if (index !== -1) {
        // PRESERVE sequential 'no' if exists
        mapped.no = apiLoketData.value[index].no;
        apiLoketData.value[index] = mapped;
      } else {
        mapped.no = apiLoketData.value.length + 1;
        apiLoketData.value.push(mapped);
        apiLoketData.value.sort((a, b) => a.id - b.id);
      }

      return { success: true, message: `Detail loket ${mapped.namaLoket} diperbarui`, data: mapped };
    } catch (error) {
      console.error(`❌ [loketStore] Error fetching detail for loket ${loketId}:`, error);
      apiError.value = error.message;
      return { success: false, message: `Gagal memuat detail loket: ${error.message}` };
    } finally {
      isLoadingAPI.value = false;
    }
  };

  return {
    // State - Base refs (for persist)
    apiLoketData,         // Raw API data array (persisted)
    localLoketData,       // Raw local data array (persisted)
    
    // State - Computed
    loketData,
    lokets: loketData, // Alias for backward compatibility/clarity
    availableServices,
    
    // API State
    isLoadingAPI,
    apiError,
    lastSyncTimestamp,

    // Actions
    addLoket,
    updateLoket,
    deleteLoket,
    getLoketById,
    getLoketLetter,
    
    // API Actions
    fetchLoketFromAPI,
    fetchSingleLoketFromAPI,
  };
}, {
  persist: {
    key: 'loket-store-state',
    storage: typeof window !== 'undefined' ? localStorage : undefined,
    paths: [
      'localLoketData',     // Persist EKSEKUTIF data (ID 1000+)
      'apiLoketData',       // Persist API data (REGULER) to minimize data loss
      'lastSyncTimestamp'   // Track when API data was last fetched
    ],
    serializer: {
      deserialize: JSON.parse,
      serialize: JSON.stringify,
    },
  },
});

