import React from "react";
import { createRoot } from "react-dom/client";
import { WalletModal } from "./components/WalletModal";
import {
  API_BASE_URL,
  getMultiRelayBuyQuote,
  getUserCryptoBalance,
  MultiRelayBuyQuoteParams,
  OutputDetails,
  BalanceResponse,
} from "./services/services";
import {
  WalletSDKConfig,
  ThemeMode,
  CornerRadius,
  WalletConfig,
  mapCornerRadius,
  mapAppearanceToTheme,
} from "./types/theme";

interface Token {
  chainIds: {
    chainId: number;
    address: string;
  }[];
  tokenAddress: string;
  amount?: string;
  icon?: string;
  symbol: string;
  name: string;
  decimals: number;
}

interface SwapParams {
  fromToken: {
    tokenAddress: string;
    amount?: string;
    chainId: number;
  };
  toToken: {
    tokenAddress: string;
    chainId: number;
  };
}

// Add TransferParams interface
interface TransferParams {
  inputToken: {
    symbol?: string;
    name?: string;
    address: string;
    chainId: number;
    decimals?: number;
    balance?: string;
    logoURI?: string;
    chainIds?: {
      chainId: number;
      address: string;
    }[];
  };
  inputAmount?: string;
  recipient: string;
}

class WalletSDK {
  private modalContainer: HTMLDivElement | null = null;
  private root: any = null;
  private walletSDKKey: string;
  private userSession: any = null;
  private config: WalletConfig;

  constructor(walletSDKKey: string, config: Partial<WalletConfig> = {}) {
    this.walletSDKKey = walletSDKKey;

    // Load saved config from localStorage
    let savedConfig: Partial<WalletConfig> = {};
    if (typeof window !== "undefined") {
      const storedConfig = localStorage.getItem("enclave_wallet_config");
      if (storedConfig) {
        try {
          savedConfig = JSON.parse(storedConfig);
        } catch (error) {
          console.error("Error parsing saved config:", error);
          // Clear invalid config
          localStorage.removeItem("enclave_wallet_config");
        }
      }
    }

    // Create the complete config with defaults, then saved config, then passed config
    this.config = {
      sdkKey: walletSDKKey,
      appearance: "light",
      cornerRadius: "M",
      primaryColor: "#1657FF",
      fontFamily: "Inter, sans-serif",
      showEnclave: false,
      ...savedConfig, // Apply saved config
      ...config, // Apply passed config (highest priority)
    };

    // Ensure sdkKey is always correct (override any saved or passed value)
    this.config.sdkKey = walletSDKKey;

    // Save the final config to localStorage
    this.saveConfigToLocalStorage();

    // Create a container for the modal if it doesn't exist
    if (!document.getElementById("wallet-sdk-modal")) {
      this.modalContainer = document.createElement("div");
      this.modalContainer.id = "wallet-sdk-modal";
      document.body.appendChild(this.modalContainer);
    }

    // Inject the Inter font and styles
    this.injectStyles();

    // Try to restore session from localStorage
    if (typeof window !== "undefined") {
      const saved = localStorage.getItem("enclave_wallet_login");
      if (saved) {
        const parsed = JSON.parse(saved);
        this.userSession = parsed;
      }
    }
    // Set global reference for modal to update session
    (window as any).__walletSDKInstance = this;
  }

  private saveConfigToLocalStorage() {
    if (typeof window !== "undefined") {
      try {
        // Save the complete config object
        localStorage.setItem(
          "enclave_wallet_config",
          JSON.stringify(this.config)
        );

        // Also save individual properties for backward compatibility
        localStorage.setItem("sdkTheme", this.config.appearance || "light");
        localStorage.setItem(
          "sdkCornerRadius",
          this.config.cornerRadius || "M"
        );
      } catch (error) {
        console.error("Error saving config to localStorage:", error);
      }
    }
  }

  private injectStyles() {
    // Add Google Fonts link
    const linkElement = document.createElement("link");
    linkElement.rel = "stylesheet";
    linkElement.href =
      "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";
    document.head.appendChild(linkElement);

    // Add our custom styles
    const styleElement = document.createElement("style");
    styleElement.textContent = `
      body {
        font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
      }
    `;
    document.head.appendChild(styleElement);
  }

  // Method to update the entire config
  updateConfig(newConfig: Partial<WalletConfig>) {
    this.config = {
      ...this.config,
      ...newConfig,
      sdkKey: this.walletSDKKey, // Ensure sdkKey is always correct
    };
    this.saveConfigToLocalStorage();
  }

  // Method to update theme dynamically
  setTheme(appearance: "light" | "dark") {
    this.updateConfig({ appearance });
  }

  // Method to update cornerRadius dynamically
  setCornerRadius(cornerRadius: "S" | "M" | "L") {
    this.updateConfig({ cornerRadius });
  }

  // Method to update primary color
  setPrimaryColor(primaryColor: string) {
    this.updateConfig({ primaryColor });
  }

  // Method to update font family
  setFontFamily(fontFamily: string) {
    this.updateConfig({ fontFamily });
  }

  // Method to update brand logo
  setBrandLogo(brandLogo: string) {
    this.updateConfig({ brandLogo });
  }

  // Method to update authentication settings
  setAuthentication(authentication: { social?: string[]; passkey?: boolean }) {
    this.updateConfig({ authentication });
  }

  // Method to update show enclave
  setShowEnclave(showEnclave: boolean) {
    this.updateConfig({ showEnclave });
  }

  // Method to get current config
  getConfig(): WalletConfig {
    return { ...this.config };
  }

  // Method to get current theme
  getTheme(): "light" | "dark" {
    return this.config.appearance || "light";
  }

  // Method to get current cornerRadius
  getCornerRadius(): "S" | "M" | "L" {
    return this.config.cornerRadius || "M";
  }

  // Method to clear saved config
  clearSavedConfig() {
    if (typeof window !== "undefined") {
      localStorage.removeItem("enclave_wallet_config");
      localStorage.removeItem("sdkTheme");
      localStorage.removeItem("sdkCornerRadius");
    }
  }

  // Method to get buy quote from multi relay using the services function
  async getMultiRelayBuyQuote(
    params: MultiRelayBuyQuoteParams
  ): Promise<OutputDetails | string> {
    return getMultiRelayBuyQuote(params, this.walletSDKKey);
  }

  setUserSession(session: any) {
    this.userSession = session;
  }

  async getUserCryptoBalance(): Promise<BalanceResponse | null> {
    if (!this.userSession?.result?.username) return null;
    return getUserCryptoBalance(
      this.userSession.result.username,
      this.walletSDKKey
    );
  }

  getWalletAddress() {
    return this.userSession?.result?.wallet?.scw_address || null;
  }

  getUsername() {
    return this.userSession?.result?.username || null;
  }

  setUsername(username: string | null) {
    this.userSession = {
      ...this.userSession,
      result: {
        ...this.userSession?.result,
        username,
      },
    };
  }

  getUserSession() {
    return this.userSession.result;
  }

  logout() {
    // Clear the session
    this.userSession = null;
    // Remove from localStorage
    if (typeof window !== "undefined") {
      localStorage.removeItem("enclave_wallet_login");
    }
    // Unmount the modal if it's open
    if (this.root) {
      this.root.unmount();
      this.root = null;
    }
  }

  openWalletModal(swapParams?: SwapParams, transferParams?: TransferParams) {
    const container = document.getElementById("wallet-sdk-modal");
    if (!container) return;

    const handleClose = () => {
      if (this.root) {
        this.clearSavedConfig();
        this.root.unmount();
        this.root = null;
      }
    };

    // Map config values to the old format for backward compatibility
    const theme = mapAppearanceToTheme(this.config.appearance);
    const cornerRadius = mapCornerRadius(this.config.cornerRadius);

    this.root = createRoot(container);
    this.root.render(
      <WalletModal
        walletSDKKey={this.walletSDKKey}
        isOpen={true}
        onClose={handleClose}
        swapParams={swapParams}
        transferParams={transferParams}
        theme={theme}
        cornerRadius={cornerRadius}
        config={this.config}
      />
    );
  }

  swap(params: SwapParams) {
    this.openWalletModal(params);
  }

  close() {
    if (this.root) {
      this.root.unmount();
      this.root = null;
    }
  }
}

export default WalletSDK;

// Export components for use in React applications
export { WalletProvider } from "./components/WalletProvider";
export { useWallet } from "./components/WalletProvider";
export { WalletModal } from "./components/WalletModal";
export type { WalletConfig } from "./types/theme";
