'use client';

import { Header } from '@/components/Header';
import Link from 'next/link';
import { useAccount, useWalletClient, useWaitForTransactionReceipt } from 'wagmi';
import { parseEther, isAddress } from 'viem';
import { useMemo, useState } from 'react';
import { oneTapOnboard, walletSupports7702 } from '@/lib/oneTapOnboard';
import { nameForAddress } from '@/lib/vaultfire';

const PARTNERSHIP_TYPES = [
  'Coding partner',
  'Research companion',
  'Creative collaborator',
  'Learning guide',
  'Business partner',
  'Emotional support',
  'Other',
] as const;

/** UX minimum. Protocol enforces >0 only, but we nudge users toward a real stake. */
const SUGGESTED_MIN_STAKE_ETH = 0.005;

export default function OnboardPage() {
  const { address, isConnected } = useAccount();
  const { data: walletClient } = useWalletClient();

  const [partnerAddr, setPartnerAddr] = useState('');
  const [selectedType, setSelectedType] =
    useState<(typeof PARTNERSHIP_TYPES)[number]>('Coding partner');
  const [customType, setCustomType] = useState('');
  const [stakeEth, setStakeEth] = useState('0.005');
  const [description, setDescription] = useState('');

  const [submitting, setSubmitting] = useState(false);
  const [txHash, setTxHash] = useState<`0x${string}` | null>(null);
  const [error, setError] = useState<string | null>(null);

  const { isLoading: confirming, isSuccess: confirmed } = useWaitForTransactionReceipt({
    hash: txHash ?? undefined,
  });

  const supports7702 = useMemo(
    () => walletSupports7702(walletClient),
    [walletClient],
  );

  const resolvedType =
    selectedType === 'Other' ? customType.trim() : selectedType;

  const validAddr = partnerAddr && isAddress(partnerAddr);
  const sameAsSelf =
    validAddr && address && partnerAddr.toLowerCase() === address.toLowerCase();
  const stakeNum = Number(stakeEth);
  const validStake = !isNaN(stakeNum) && stakeNum > 0;
  const suggestedStake = !isNaN(stakeNum) && stakeNum >= SUGGESTED_MIN_STAKE_ETH;
  const validType = resolvedType.length > 0 && resolvedType.length <= 200;
  const canSubmit =
    !!address &&
    !!walletClient &&
    validAddr &&
    !sameAsSelf &&
    validStake &&
    validType &&
    !submitting &&
    !txHash;

  async function submit() {
    if (!address || !walletClient || !validAddr || sameAsSelf || !validStake || !validType) return;
    setSubmitting(true);
    setError(null);
    try {
      const { txHash: hash } = await oneTapOnboard({
        walletClient,
        userAddress: address,
        aiAgent: partnerAddr as `0x${string}`,
        partnershipType: resolvedType,
        stakeWei: parseEther(stakeEth),
        description: description.trim() || undefined,
      });
      setTxHash(hash);
    } catch (e) {
      setError(
        e instanceof Error ? e.message : 'Signing or broadcast failed.',
      );
    } finally {
      setSubmitting(false);
    }
  }

  if (!isConnected) {
    return (
      <main>
        <Header />
        <div className="card">
          <p className="text-sm text-muted mb-4">Connect your wallet first.</p>
          <Link href="/" className="btn-secondary block text-center">
            Back
          </Link>
        </div>
      </main>
    );
  }

  // Wallet connected but doesn't support EIP-7702 (e.g. Base App / Coinbase Smart
  // Wallet). Route to the classic 2-step flow.
  if (!supports7702) {
    return (
      <main>
        <Header />
        <div className="mb-6">
          <h1 className="text-2xl font-bold mb-2">One-tap onboard</h1>
          <p className="text-sm text-muted">
            Your wallet doesn&apos;t support EIP-7702 single-signature flows yet
            (Base App and Coinbase Smart Wallet are working on it). The classic
            2-step flow works for every wallet and lands the same on-chain state.
          </p>
        </div>
        <div className="card mb-4">
          <div className="label mb-2">Classic flow</div>
          <p className="text-sm text-white mb-4">
            Step 1: register your agent on-chain.
            <br />
            Step 2: create a partnership bond.
          </p>
          <Link href="/register" className="btn-primary block text-center mb-2">
            Start classic flow
          </Link>
          <Link href="/" className="btn-secondary block text-center">
            Back
          </Link>
        </div>
        <div className="card">
          <div className="label mb-1">Why the difference</div>
          <p className="text-xs text-muted leading-relaxed">
            EIP-7702 lets an EOA temporarily delegate to a batch contract so a
            registration + bond can happen in a single signature. Smart-wallet
            UIs take a different approach to account abstraction and don&apos;t
            surface 7702 authorization signing yet. We&apos;ll enable the one-tap
            path for those wallets as soon as their support lands.
          </p>
        </div>
      </main>
    );
  }

  return (
    <main>
      <Header />

      <div className="mb-6">
        <h1 className="text-2xl font-bold mb-2">One-tap onboard</h1>
        <p className="text-sm text-muted">
          Register your agent and create a partnership bond in a single signature,
          via EIP-7702.
        </p>
      </div>

      {!txHash && (
        <>
          <div className="card mb-4">
            <div className="label mb-2">Your agent name</div>
            <div className="text-lg font-bold text-white mb-1">
              {nameForAddress(address!)}
            </div>
            <div className="text-xs font-mono text-muted">
              {address?.slice(0, 6)}…{address?.slice(-4)}
            </div>
          </div>

          <div className="card mb-4">
            <label htmlFor="partner" className="label mb-2 block">
              Counterparty address
            </label>
            <input
              id="partner"
              type="text"
              value={partnerAddr}
              onChange={(e) => setPartnerAddr(e.target.value.trim())}
              placeholder="0x…"
              className="w-full bg-bg border border-border rounded-lg px-3 py-2 text-sm font-mono text-white placeholder-muted focus:outline-none focus:border-accent"
              autoComplete="off"
              spellCheck={false}
            />
            {sameAsSelf && (
              <p className="text-xs text-danger mt-2">
                Counterparty must be a different address than your wallet.
              </p>
            )}
          </div>

          <div className="card mb-4">
            <div className="label mb-2">Partnership type</div>
            <div className="grid grid-cols-2 gap-2">
              {PARTNERSHIP_TYPES.map((t) => (
                <button
                  key={t}
                  onClick={() => setSelectedType(t)}
                  className={`text-sm rounded-lg px-3 py-2 border transition-colors ${
                    selectedType === t
                      ? 'border-accent text-white bg-accent/10'
                      : 'border-border text-muted hover:text-white'
                  }`}
                >
                  {t}
                </button>
              ))}
            </div>
            {selectedType === 'Other' && (
              <input
                type="text"
                value={customType}
                onChange={(e) => setCustomType(e.target.value)}
                placeholder="Describe the partnership"
                maxLength={200}
                className="mt-3 w-full bg-bg border border-border rounded-lg px-3 py-2 text-sm text-white placeholder-muted focus:outline-none focus:border-accent"
              />
            )}
          </div>

          <div className="card mb-4">
            <label htmlFor="stake" className="label mb-2 block">
              Stake (ETH)
            </label>
            <input
              id="stake"
              type="text"
              inputMode="decimal"
              value={stakeEth}
              onChange={(e) => setStakeEth(e.target.value)}
              className="w-full bg-bg border border-border rounded-lg px-3 py-2 text-sm font-mono text-white placeholder-muted focus:outline-none focus:border-accent"
            />
            <p className="text-xs text-muted mt-2">
              On Base. {suggestedStake ? 'Good amount.' : 'Protocol accepts any amount > 0, but 0.005+ is recommended for meaningful skin in the game.'}
            </p>
          </div>

          <div className="card mb-4">
            <label htmlFor="desc" className="label mb-2 block">
              Description (optional)
            </label>
            <input
              id="desc"
              type="text"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              maxLength={280}
              placeholder="What does your agent do?"
              className="w-full bg-bg border border-border rounded-lg px-3 py-2 text-sm text-white placeholder-muted focus:outline-none focus:border-accent"
            />
          </div>

          <button
            onClick={submit}
            disabled={!canSubmit}
            className="btn-primary disabled:opacity-40 disabled:cursor-not-allowed"
          >
            {submitting ? 'Sign in your wallet…' : 'Onboard in one signature'}
          </button>

          {error && (
            <div className="card border-danger mt-4">
              <div className="label text-danger mb-1">Error</div>
              <p className="text-sm text-white break-words">{error}</p>
              <div className="mt-3">
                <Link href="/register" className="text-xs text-accent hover:underline">
                  Try the classic 2-step flow instead →
                </Link>
              </div>
            </div>
          )}
        </>
      )}

      {txHash && confirming && (
        <div className="card">
          <div className="label mb-1">Confirming</div>
          <p className="text-sm text-white mb-2">
            Type-4 transaction submitted. Waiting for Base confirmation…
          </p>
          <a
            href={`https://basescan.org/tx/${txHash}`}
            target="_blank"
            rel="noreferrer"
            className="text-xs font-mono text-accent hover:underline break-all"
          >
            {txHash}
          </a>
        </div>
      )}

      {txHash && confirmed && (
        <div className="card border-success">
          <div className="label text-success mb-1">Onboarded</div>
          <p className="text-sm text-white mb-4">
            Agent registered and bond created in one signature.
          </p>
          <div className="flex gap-2">
            <Link href="/status" className="btn-primary text-center flex-1">
              View your agent
            </Link>
            <a
              href={`https://basescan.org/tx/${txHash}`}
              target="_blank"
              rel="noreferrer"
              className="btn-secondary text-center flex-1"
            >
              Tx on Basescan
            </a>
          </div>
        </div>
      )}
    </main>
  );
}
