import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { invoke } from '@tauri-apps/api/core';

/**
 * Sanitized error logging - prevents sensitive data from being logged
 * Only logs generic error types in production, full errors in development
 */
function logError(context: string, error: unknown): void {
  // In production, only log the context and error type, not the full message
  // which might contain sensitive information like addresses or amounts
  if (import.meta.env.PROD) {
    const errorType = error instanceof Error ? error.name : 'Unknown';
    console.error(`[Wallet] ${context}: ${errorType}`);
  } else {
    // In development, log full error for debugging (but still sanitize)
    const safeError = error instanceof Error ? error.message : 'Unknown error';
    // Remove any potential sensitive patterns (addresses, keys, etc.)
    const sanitized = safeError
      .replace(/synor1[a-z0-9]{38,}/gi, '[ADDRESS]')
      .replace(/tsynor1[a-z0-9]{38,}/gi, '[ADDRESS]')
      .replace(/[a-f0-9]{64}/gi, '[HASH]')
      .replace(/\b[a-z]{3,}\s+[a-z]{3,}\s+[a-z]{3,}/gi, '[POSSIBLE_MNEMONIC]');
    console.error(`[Wallet] ${context}:`, sanitized);
  }
}

export interface WalletAddress {
  address: string;
  index: number;
  isChange: boolean;
  label?: string;
}

export interface Balance {
  balance: number;
  balanceHuman: string;
  pending: number;
}

export interface NetworkStatus {
  connected: boolean;
  network?: string;
  blockHeight?: number;
  peerCount?: number;
  synced?: boolean;
}

interface WalletState {
  // State
  isInitialized: boolean;
  isUnlocked: boolean;
  addresses: WalletAddress[];
  balance: Balance | null;
  networkStatus: NetworkStatus;

  // Actions
  setInitialized: (initialized: boolean) => void;
  setUnlocked: (unlocked: boolean) => void;
  setAddresses: (addresses: WalletAddress[]) => void;
  setBalance: (balance: Balance | null) => void;
  setNetworkStatus: (status: NetworkStatus) => void;

  // Async actions (invoke Tauri commands)
  createWallet: (password: string) => Promise<{ mnemonic: string; address: string }>;
  importWallet: (mnemonic: string, password: string) => Promise<string>;
  unlockWallet: (password: string) => Promise<boolean>;
  lockWallet: () => Promise<void>;
  refreshBalance: () => Promise<void>;
  refreshAddresses: () => Promise<void>;
  connectNode: (rpcUrl: string, wsUrl?: string) => Promise<void>;
}

export const useWalletStore = create<WalletState>()(
  persist(
    (set, get) => ({
      // Initial state
      isInitialized: false,
      isUnlocked: false,
      addresses: [],
      balance: null,
      networkStatus: { connected: false },

      // Sync setters
      setInitialized: (initialized) => set({ isInitialized: initialized }),
      setUnlocked: (unlocked) => set({ isUnlocked: unlocked }),
      setAddresses: (addresses) => set({ addresses }),
      setBalance: (balance) => set({ balance }),
      setNetworkStatus: (status) => set({ networkStatus: status }),

      // Async actions
      createWallet: async (password: string) => {
        const result = await invoke<{ mnemonic: string; address: string }>(
          'create_wallet',
          { password }
        );
        set({
          isInitialized: true,
          isUnlocked: true,
          addresses: [{ address: result.address, index: 0, isChange: false }],
        });
        return result;
      },

      importWallet: async (mnemonic: string, password: string) => {
        const address = await invoke<string>('import_wallet', {
          request: { mnemonic, password },
        });
        set({
          isInitialized: true,
          isUnlocked: true,
          addresses: [{ address, index: 0, isChange: false }],
        });
        return address;
      },

      unlockWallet: async (password: string) => {
        const success = await invoke<boolean>('unlock_wallet', { password });
        if (success) {
          set({ isUnlocked: true });
          // Refresh data after unlock
          get().refreshBalance();
          get().refreshAddresses();
        }
        return success;
      },

      lockWallet: async () => {
        await invoke('lock_wallet');
        set({
          isUnlocked: false,
          balance: null,
        });
      },

      refreshBalance: async () => {
        try {
          const balance = await invoke<Balance>('get_balance');
          set({ balance });
        } catch (error) {
          logError('refreshBalance', error);
        }
      },

      refreshAddresses: async () => {
        try {
          const addresses = await invoke<WalletAddress[]>('get_addresses');
          set({ addresses });
        } catch (error) {
          logError('refreshAddresses', error);
        }
      },

      connectNode: async (rpcUrl: string, wsUrl?: string) => {
        try {
          const connection = await invoke<NetworkStatus>('connect_node', {
            rpcUrl,
            wsUrl,
          });
          set({ networkStatus: { ...connection, connected: true } });
        } catch (error) {
          logError('connectNode', error);
          set({ networkStatus: { connected: false } });
        }
      },
    }),
    {
      name: 'synor-wallet-storage',
      partialize: (state) => ({
        isInitialized: state.isInitialized,
        // Don't persist sensitive state like isUnlocked
      }),
    }
  )
);
