import { createContext, useContext, useEffect, useState } from 'react';
import { isTransientApiError } from '../api/offlineCache';
import { getHouseholdStores, getLocationZones } from '../api/stores';
import { AuthContext } from './AuthContext';
import { HouseholdContext } from './HouseholdContext';

const DEFAULT_LOCATION_NAME = "Default Location";

function getHouseholdStoreKey(store) {
  return String(store?.household_store_id ?? store?.store_id ?? store?.id ?? "");
}

function isDefaultLocationName(store) {
  return store?.location_name === DEFAULT_LOCATION_NAME || store?.display_name === store?.name;
}

function chooseStoreLocation(locations) {
  if (!locations || locations.length === 0) return null;
  return (
    locations.find(isDefaultLocationName) ||
    locations.find((store) => store.is_default) ||
    locations[0]
  );
}

function chooseStoreByHouseholdStoreId(stores, householdStoreId) {
  const matchingLocations = stores.filter(
    (store) => getHouseholdStoreKey(store) === String(householdStoreId)
  );
  return chooseStoreLocation(matchingLocations);
}

function getLocationStorageKey(householdId, householdStoreId) {
  return `activeStoreLocationId_${householdId}_${householdStoreId}`;
}

function chooseLocationByStoredIds(stores, householdId, householdStoreId) {
  const storageKey = getLocationStorageKey(householdId, householdStoreId);
  const savedLocationId = localStorage.getItem(storageKey);
  if (!savedLocationId) return null;

  return stores.find(
    (store) =>
      String(store.id) === String(savedLocationId) &&
      getHouseholdStoreKey(store) === String(householdStoreId)
  );
}

export const StoreContext = createContext({
  stores: [],
  activeStore: null,
  zones: [],
  loading: false,
  zonesLoading: false,
  error: null,
  setActiveStore: () => { },
  refreshStores: () => { },
  refreshZones: () => { },
});

export const StoreProvider = ({ children }) => {
  const { token } = useContext(AuthContext);
  const { activeHousehold } = useContext(HouseholdContext);
  const [stores, setStores] = useState([]);
  const [activeStore, setActiveStoreState] = useState(null);
  const [zones, setZones] = useState([]);
  const [loading, setLoading] = useState(false);
  const [zonesLoading, setZonesLoading] = useState(false);
  const [error, setError] = useState(null);

  // Load stores when household changes
  useEffect(() => {
    if (token && activeHousehold) {
      loadStores();
    } else {
      // Clear state when logged out or no household
      setStores([]);
      setActiveStoreState(null);
      setZones([]);
    }
  }, [token, activeHousehold?.id]);

  // Load active store from localStorage on mount (per household)
  useEffect(() => {
    if (!activeHousehold || stores.length === 0) return;

    const householdStoreStorageKey = `activeHouseholdStoreId_${activeHousehold.id}`;
    const legacyLocationStorageKey = `activeStoreId_${activeHousehold.id}`;
    const savedHouseholdStoreId = localStorage.getItem(householdStoreStorageKey);

    if (savedHouseholdStoreId) {
      const store =
        chooseLocationByStoredIds(stores, activeHousehold.id, savedHouseholdStoreId) ||
        chooseStoreByHouseholdStoreId(stores, savedHouseholdStoreId);
      if (store) {
        setActiveStoreState(store);
        return;
      }
    }

    const savedLocationId = localStorage.getItem(legacyLocationStorageKey);
    if (savedLocationId) {
      const savedLocation = stores.find(s => String(s.id) === String(savedLocationId));
      const store = savedLocation || chooseStoreByHouseholdStoreId(stores, getHouseholdStoreKey(savedLocation));
      if (store) {
        const householdStoreId = getHouseholdStoreKey(store);
        setActiveStoreState(store);
        localStorage.setItem(householdStoreStorageKey, householdStoreId);
        localStorage.setItem(
          getLocationStorageKey(activeHousehold.id, householdStoreId),
          String(store.id)
        );
        return;
      }
    }

    // No saved store or not found, use the default store's representative location.
    const defaultStore = chooseStoreByHouseholdStoreId(
      stores,
      getHouseholdStoreKey(stores.find(s => s.is_default) || stores[0])
    );
    setActiveStoreState(defaultStore);
    const householdStoreId = getHouseholdStoreKey(defaultStore);
    localStorage.setItem(householdStoreStorageKey, householdStoreId);
    localStorage.setItem(
      getLocationStorageKey(activeHousehold.id, householdStoreId),
      String(defaultStore.id)
    );
  }, [stores, activeHousehold]);

  useEffect(() => {
    if (token && activeHousehold?.id && activeStore?.id) {
      loadZones();
    } else {
      setZones([]);
    }
  }, [token, activeHousehold?.id, activeStore?.id]);

  const loadStores = async () => {
    if (!token || !activeHousehold) return;

    setLoading(true);
    setError(null);
    try {
      const response = await getHouseholdStores(activeHousehold.id);
      setStores(response.data);
    } catch (err) {
      console.error('[StoreContext] Failed to load stores:', err);
      setError(
        err.response?.data?.error?.message ||
        err.response?.data?.message ||
        'Failed to load stores'
      );
      if (!isTransientApiError(err)) {
        setStores([]);
        setActiveStoreState(null);
      }
    } finally {
      setLoading(false);
    }
  };

  const setActiveStore = (store) => {
    setActiveStoreState(store);
    if (store && activeHousehold) {
      const storageKey = `activeHouseholdStoreId_${activeHousehold.id}`;
      const householdStoreId = getHouseholdStoreKey(store);
      localStorage.setItem(storageKey, householdStoreId);
      localStorage.setItem(
        getLocationStorageKey(activeHousehold.id, householdStoreId),
        String(store.id)
      );
    }
  };

  const loadZones = async () => {
    if (!token || !activeHousehold?.id || !activeStore?.id) return;

    setZonesLoading(true);
    try {
      const response = await getLocationZones(activeHousehold.id, activeStore.id);
      setZones(response.data?.zones || []);
    } catch (err) {
      console.error('[StoreContext] Failed to load zones:', err);
      if (!isTransientApiError(err)) {
        setZones([]);
      }
    } finally {
      setZonesLoading(false);
    }
  };

  const value = {
    stores,
    activeStore,
    zones,
    loading,
    zonesLoading,
    error,
    setActiveStore,
    refreshStores: loadStores,
    refreshZones: loadZones,
  };

  return (
    <StoreContext.Provider value={value}>
      {children}
    </StoreContext.Provider>
  );
};
