import { useState, useEffect, useCallback } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { DEFAULT_SETTINGS, API_URL } from '../constants/defaults';
import { apiFetch } from '../services/api';

const DEVICE_PRINT_KEYS = new Set([
  'preferredPrintMethod',
  'printerIpAddress',
  'printerType',
  'testLabelPdfUrl',
  'localPrinterHostname',
  'localPrinterPort',
  'localPrinterDriver',
  'showAdvancedPrinterDrivers',
  'localPrinterLabelType',
]);

const coerceSettingValue = (key, val) => {
  if (!(key in DEFAULT_SETTINGS)) return undefined;
  const defaultType = typeof DEFAULT_SETTINGS[key];
  if (defaultType === 'boolean') return val === 'true' || val === '1' || val === true;
  if (defaultType === 'number') {
    const n = Number(val);
    return Number.isFinite(n) ? n : DEFAULT_SETTINGS[key];
  }
  return val;
};

export function useSettings() {
  const [settings, setSettings] = useState(DEFAULT_SETTINGS);
  const [loaded, setLoaded] = useState(false);

  const loadLocal = useCallback(async () => {
    try {
      const saved = await AsyncStorage.getItem('masterSettings');
      if (saved) setSettings(prev => ({ ...DEFAULT_SETTINGS, ...JSON.parse(saved) }));
    } catch (_) {}
    setLoaded(true);
  }, []);

  useEffect(() => { loadLocal(); }, [loadLocal]);

  const syncFromServer = useCallback(async () => {
    try {
      const res = await apiFetch(`${API_URL}?action=get_app_settings`);
      if (res.status === 401 || !res.ok) return;
      const data = await res.json();
      if (data.success && data.settings && typeof data.settings === 'object') {
        setSettings(prev => {
          const merged = { ...prev };
          const serverModeRaw = data.settings.printSettingsMode ?? data.settings.print_settings_mode;
          const serverPrintMode = serverModeRaw === 'per_device' ? 'per_device' : (serverModeRaw === 'company' ? 'company' : prev.printSettingsMode);
          for (const [rawKey, val] of Object.entries(data.settings)) {
            const key = rawKey === 'security_mode' ? 'securityMode' : rawKey;
            if (DEVICE_PRINT_KEYS.has(key) && serverPrintMode === 'per_device') continue;
            if (key in DEFAULT_SETTINGS) {
              merged[key] = coerceSettingValue(key, val);
            }
          }
          AsyncStorage.setItem('masterSettings', JSON.stringify(merged)).catch(() => {});
          return merged;
        });
      }
    } catch (_) {}
  }, []);

  const updateSetting = useCallback(async (key, value) => {
    let nextSettings = null;
    setSettings(prev => {
      const next = { ...prev, [key]: value };
      nextSettings = next;
      AsyncStorage.setItem('masterSettings', JSON.stringify(next)).catch(() => {});
      return next;
    });
    const printMode = key === 'printSettingsMode' ? value : (nextSettings?.printSettingsMode || settings.printSettingsMode);
    if (DEVICE_PRINT_KEYS.has(key) && printMode === 'per_device') return;

    const payload = { [key]: String(value) };
    if (key === 'printSettingsMode' && value === 'company' && nextSettings) {
      DEVICE_PRINT_KEYS.forEach(printKey => {
        payload[printKey] = String(nextSettings[printKey] ?? DEFAULT_SETTINGS[printKey] ?? '');
      });
    }

    // Fire-and-forget server sync
    try {
      await apiFetch(API_URL, {
        method: 'POST',
        body: JSON.stringify({ action: 'save_app_settings', settings: payload }),
      });
    } catch (_) {}
  }, [settings.printSettingsMode]);

  return { settings, updateSetting, syncFromServer, loaded };
}
