/**
 * Shared Accounting Period Store Factory
 *
 * Creates a Pinia store for accounting period selection that can be used by any ROA2WEB application.
 * Each app passes its own apiService and store references.
 *
 * Usage:
 *   import { createAccountingPeriodStore } from '@shared/frontend/stores/accountingPeriod';
 *   import { apiService } from '../services/api';
 *   import { useAuthStore } from './auth';
 *   import { useCompanyStore } from './companies';
 *   export const useAccountingPeriodStore = createAccountingPeriodStore(apiService, useAuthStore, useCompanyStore);
 */

import { defineStore } from "pinia";
import { ref, computed } from "vue";

/**
 * Factory function to create an accounting period store
 * @param {Object} apiService - Axios instance configured for the app's API
 * @param {Function} useAuthStore - Reference to the auth store function
 * @param {Function} useCompanyStore - Reference to the company store function
 * @returns {Function} Pinia store definition
 */
export function createAccountingPeriodStore(apiService, useAuthStore, useCompanyStore) {
  return defineStore("accountingPeriod", () => {
    // State
    const periods = ref([]);
    const selectedPeriod = ref(null);
    const isLoading = ref(false);
    const error = ref(null);

    // Getters
    const hasPeriods = computed(() => periods.value.length > 0);
    const currentPeriod = computed(() => selectedPeriod.value);

    // Computed date range for current period (first/last day of month)
    const dateRange = computed(() => {
      if (!selectedPeriod.value) return { dateFrom: null, dateTo: null };

      const { an, luna } = selectedPeriod.value;
      const firstDay = new Date(an, luna - 1, 1);
      const lastDay = new Date(an, luna, 0);

      return {
        dateFrom: firstDay,
        dateTo: lastDay,
      };
    });

    // localStorage helpers - lazy instantiate stores only when needed
    const getStorageKey = () => {
      try {
        const authStore = useAuthStore();
        const companyStore = useCompanyStore();
        const username = authStore.user?.username;
        const companyId = companyStore.selectedCompany?.id_firma;
        if (!username || !companyId) return null;
        return `selected_period_${username}_${companyId}`;
      } catch (e) {
        // Stores not yet initialized, skip localStorage
        return null;
      }
    };

    const initializeSelectedPeriod = () => {
      const key = getStorageKey();
      if (!key) return null;

      const saved = localStorage.getItem(key);
      if (saved) {
        try {
          return JSON.parse(saved);
        } catch (e) {
          localStorage.removeItem(key);
        }
      }
      return null;
    };

    const persistSelectedPeriod = (period) => {
      const key = getStorageKey();
      if (key && period) {
        localStorage.setItem(key, JSON.stringify(period));
      }
    };

    // Actions
    const loadPeriods = async (companyId) => {
      if (!companyId) {
        console.warn('[Period] loadPeriods called without companyId');
        return { success: false };
      }

      isLoading.value = true;
      error.value = null;

      try {
        console.log('[Period] Loading periods for company:', companyId);
        const response = await apiService.get("/calendar/periods", {
          params: { company: companyId },
        });

        periods.value = response.data.periods || [];
        console.log('[Period] Loaded', periods.value.length, 'periods');
        console.log('[Period] Backend current_period:', response.data.current_period);

        // Try to restore saved period or use most recent
        const saved = initializeSelectedPeriod();
        console.log('[Period] Saved period from localStorage:', saved);

        if (saved) {
          const exists = periods.value.find(
            (p) => p.an === saved.an && p.luna === saved.luna
          );
          if (exists) {
            console.log('[Period] Restoring saved period:', exists);
            selectedPeriod.value = exists;
          } else if (response.data.current_period) {
            console.log('[Period] Saved period not found, using current:', response.data.current_period);
            setSelectedPeriod(response.data.current_period);
          }
        } else if (response.data.current_period) {
          console.log('[Period] No saved period, auto-selecting current:', response.data.current_period);
          setSelectedPeriod(response.data.current_period);
        } else {
          console.warn('[Period] No saved period and no current_period from backend!');
        }

        console.log('[Period] Final selectedPeriod:', selectedPeriod.value);
        return { success: true };
      } catch (err) {
        error.value = err.response?.data?.detail || "Failed to load periods";
        console.error("[Period] Failed to load periods - Full error:", err);
        console.error("[Period] Error response:", err.response);
        console.error("[Period] Error message:", err.message);
        console.error("[Period] Error status:", err.response?.status);
        console.error("[Period] Error data:", err.response?.data);
        return { success: false, error: error.value };
      } finally {
        isLoading.value = false;
      }
    };

    const setSelectedPeriod = (period) => {
      selectedPeriod.value = period;
      persistSelectedPeriod(period);
    };

    const resetToLatest = () => {
      if (periods.value.length > 0) {
        setSelectedPeriod(periods.value[0]);
      }
    };

    const reset = () => {
      periods.value = [];
      selectedPeriod.value = null;
      isLoading.value = false;
      error.value = null;
    };

    return {
      // State
      periods,
      selectedPeriod,
      isLoading,
      error,

      // Getters
      hasPeriods,
      currentPeriod,
      dateRange,

      // Actions
      loadPeriods,
      setSelectedPeriod,
      resetToLatest,
      reset,
    };
  });
}
