import { http, createConfig, createStorage } from '@wagmi/vue';
import { baseSepolia } from '@wagmi/vue/chains';
import { coinbaseWallet, injected, walletConnect } from '@wagmi/vue/connectors';
import { defineChain } from 'viem';

/**
 * Shared wagmi config for all harb apps.
 * RPC URL and WalletConnect project ID are passed in to keep this package env-agnostic.
 */
export interface HarbWeb3Options {
  rpcUrl?: string;
  walletConnectProjectId?: string;
}

const defaults = {
  rpcUrl: '/api/rpc',
  walletConnectProjectId: 'd8e5ecb0353c02e21d4c0867d4473ac5',
};

export const KRAIKEN_LOCAL_CHAIN = defineChain({
  id: 31337,
  name: 'Kraiken Local Fork',
  network: 'kraiken-local',
  nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
  rpcUrls: {
    default: { http: ['http://localhost:8545'] },
    public: { http: ['http://localhost:8545'] },
  },
  blockExplorers: {
    default: { name: 'Local Explorer', url: '' },
  },
  testnet: true,
});

let _config: ReturnType<typeof createConfig> | null = null;

export function createHarbConfig(opts: HarbWeb3Options = {}) {
  const rpcUrl = opts.rpcUrl ?? defaults.rpcUrl;
  const wcProjectId = opts.walletConnectProjectId ?? defaults.walletConnectProjectId;

  // Build chain with provided RPC URL
  const chain = defineChain({
    ...KRAIKEN_LOCAL_CHAIN,
    rpcUrls: {
      default: { http: [rpcUrl] },
      public: { http: [rpcUrl] },
    },
  });

  _config = createConfig({
    chains: [chain, baseSepolia],
    storage: createStorage({ storage: window.localStorage }),
    connectors: [
      injected(),
      walletConnect({
        projectId: wcProjectId,
        metadata: {
          name: 'Kraiken',
          description: 'Connect your wallet with Kraiken',
          url: 'https://kraiken.eth.limo',
          icons: [''],
        },
      }),
      coinbaseWallet({
        appName: 'Kraiken',
        darkMode: true,
        preference: { options: 'all', telemetry: false },
      }),
    ],
    transports: {
      [chain.id]: http(rpcUrl),
      [baseSepolia.id]: http(),
    },
  });

  // Default to local chain
  if (_config.state.chainId !== chain.id) {
    _config.setState(state => ({ ...state, chainId: chain.id }));
  }

  return _config;
}

export function getHarbConfig() {
  if (!_config) throw new Error('@harb/web3: call createHarbConfig() first');
  return _config;
}
