import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import type { ProviderProfile, ProviderMigrationState } from '@/types/settings';

// Basic encoding/decoding utilities for API key obfuscation
// Note: Base64 encoding is NOT encryption - it's basic obfuscation for MVP
// Post-MVP: Use Web Crypto API for actual encryption
const encodeApiKey = (key: string): string => {
  if (!key) return '';
  try {
    return btoa(key);
  } catch {
    return '';
  }
};

const decodeApiKey = (encoded: string): string => {
  if (!encoded) return '';
  try {
    return atob(encoded);
  } catch {
    // Handle invalid encoding gracefully
    return '';
  }
};

// Generate unique ID for provider profiles
const generateProviderId = (): string => {
  return `provider-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
};

// Migration function from legacy single-provider to multi-provider
const migrateLegacyToProfiles = (state: any): void => {
  // Only migrate if not already migrated and legacy settings exist
  if (!state.providerMigrationState?.hasMigrated && (state.apiKey || state.baseUrl || state.modelName)) {
    const migratedProfile: ProviderProfile = {
      id: generateProviderId(),
      name: 'Default Provider (Migrated)',
      baseUrl: state.baseUrl || 'https://api.openai.com/v1',
      apiKey: state.apiKey,
      modelName: state.modelName || 'gpt-4o',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };

    state.savedProviders = [migratedProfile];
    state.activeProviderId = migratedProfile.id;
    state.providerMigrationState = {
      hasMigrated: true,
      migratedAt: new Date().toISOString(),
    };

    // Clear legacy settings
    state.apiKey = '';
    state.baseUrl = 'https://api.openai.com/v1';
    state.modelName = 'gpt-4o';
    state.isConfigured = false;
  }
};

interface SettingsState {
  // Legacy single-provider (deprecated, kept for migration)
  apiKey: string;
  baseUrl: string;
  modelName: string;
  isConfigured: boolean;

  // New multi-provider system
  savedProviders: ProviderProfile[];
  activeProviderId: string | null;

  // Migration state
  providerMigrationState: ProviderMigrationState;

  actions: {
    // Legacy actions (deprecated)
    setApiKey: (key: string) => void;
    setBaseUrl: (url: string) => void;
    setModelName: (name: string) => void;
    clearSettings: () => void;

    // New multi-provider actions
    addProvider: (profile: Omit<ProviderProfile, 'id' | 'createdAt' | 'updatedAt'>) => string;
    removeProvider: (id: string) => void;
    setActiveProvider: (id: string) => void;
    updateProvider: (id: string, updates: Partial<ProviderProfile>) => void;
    completeMigration: () => void;
  };

  // Computed getter for active provider
  getActiveProvider: () => ProviderProfile | null;
}

export const useSettingsStore = create<SettingsState>()(
  persist(
    (set, get) => ({
      // Legacy single-provider defaults
      apiKey: '',
      baseUrl: 'https://api.openai.com/v1',
      modelName: 'gpt-4o',
      isConfigured: false,

      // New multi-provider defaults
      savedProviders: [],
      activeProviderId: null,
      providerMigrationState: {
        hasMigrated: false,
      },

      actions: {
        // Legacy actions (deprecated)
        setApiKey: (apiKey) => set({ apiKey, isConfigured: !!apiKey }),
        setBaseUrl: (baseUrl) => set({ baseUrl }),
        setModelName: (modelName) => set({ modelName }),
        clearSettings: () => set({ apiKey: '', isConfigured: false }),

        // New multi-provider actions
        addProvider: (profile) => {
          const newProfile: ProviderProfile = {
            ...profile,
            id: generateProviderId(),
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
          };

          set((state) => {
            const updatedProviders = [...state.savedProviders, newProfile];

            // Auto-select if this is the first provider
            const newActiveProviderId = state.savedProviders.length === 0
              ? newProfile.id
              : state.activeProviderId;

            return {
              savedProviders: updatedProviders,
              activeProviderId: newActiveProviderId,
            };
          });

          return newProfile.id;
        },

        removeProvider: (id) => {
          set((state) => {
            const filteredProviders = state.savedProviders.filter(p => p.id !== id);
            let newActiveProviderId = state.activeProviderId;

            // If we removed the active provider and there are others, select the first available
            if (state.activeProviderId === id && filteredProviders.length > 0) {
              newActiveProviderId = filteredProviders[0].id;
            } else if (state.activeProviderId === id && filteredProviders.length === 0) {
              // No providers left
              newActiveProviderId = null;
            }

            return {
              savedProviders: filteredProviders,
              activeProviderId: newActiveProviderId,
            };
          });
        },

        setActiveProvider: (id) => set({ activeProviderId: id }),

        updateProvider: (id, updates) => {
          set((state) => ({
            savedProviders: state.savedProviders.map(p =>
              p.id === id
                ? { ...p, ...updates, updatedAt: new Date().toISOString() }
                : p
            ),
          }));
        },

        completeMigration: () => set({
          providerMigrationState: {
            hasMigrated: true,
            migratedAt: new Date().toISOString(),
          },
        }),
      },

      // Computed getter for active provider
      getActiveProvider: () => {
        const state = get();
        const { activeProviderId, savedProviders } = state;

        if (!activeProviderId) return null;

        return savedProviders.find(p => p.id === activeProviderId) || null;
      },
    }),
    {
      name: 'test01-settings-storage',
      storage: createJSONStorage(() => localStorage),
      partialize: (state) => ({
        // Encode API keys before persisting to localStorage
        // Legacy single-provider
        apiKey: state.apiKey ? encodeApiKey(state.apiKey) : '',
        baseUrl: state.baseUrl,
        modelName: state.modelName,

        // New multi-provider (with encoded API keys)
        savedProviders: state.savedProviders.map(profile => ({
          ...profile,
          apiKey: encodeApiKey(profile.apiKey),
        })),
        activeProviderId: state.activeProviderId,
        providerMigrationState: state.providerMigrationState,
      }),
      onRehydrateStorage: () => (state) => {
        if (state) {
          // Run migration if needed
          migrateLegacyToProfiles(state);

          // Decode legacy API key after rehydration from localStorage
          state.apiKey = decodeApiKey(state.apiKey);
          state.isConfigured = !!state.apiKey;

          // Decode API keys in all profiles
          if (state.savedProviders) {
            state.savedProviders = state.savedProviders.map(profile => ({
              ...profile,
              apiKey: decodeApiKey(profile.apiKey),
            }));
          }
        }
      },
    }
  )
);

// Atomic selector hooks - CRITICAL: Use these to prevent unnecessary re-renders
export const useApiKey = () => useSettingsStore((s) => s.apiKey);
export const useBaseUrl = () => useSettingsStore((s) => s.baseUrl);
export const useModelName = () => useSettingsStore((s) => s.modelName);
export const useIsConfigured = () => useSettingsStore((s) => s.isConfigured);
export const useSettingsActions = () => useSettingsStore((s) => s.actions);

// New multi-provider atomic selectors
export const useSavedProviders = () => useSettingsStore((s) => s.savedProviders);
export const useActiveProviderId = () => useSettingsStore((s) => s.activeProviderId);
export const useActiveProvider = () => useSettingsStore((s) => s.getActiveProvider());
export const useProviderMigrationState = () => useSettingsStore((s) => s.providerMigrationState);
