'use client';

/**
 * /sign/v3-launch — Vaultfire V3 launch console (read-only, locked).
 *
 * What this route is:
 *   - An operator-facing status console for the four V3 launch tracks
 *     (Base read-only bootstrap, Base capped partner pilot, Solana V3, x402 V3).
 *   - A truthful renderer of `data/v3-launch-console-data.json`, which is
 *     derived by `tools/build_v3_launch_console_data.mjs` from checked-in public
 *     evidence and verified against its sources by tests.
 *
 * What this route is NOT, by construction:
 *   - It renders no signing, sending, broadcast, payment, route-activation, or
 *     Bazaar-mutation control. Those controls do not exist in this file, because
 *     the two prerequisites — a verified immutable transaction package and an
 *     explicit approval artifact — do not exist yet.
 *   - It has no private key, seed phrase, keystore, or mnemonic field, and it
 *     never calls the wallet context's legacy `unlock()` path.
 *
 * Wallet model:
 *   - Reuses the existing WalletAuthContext (Coinbase/Base Wallet, MetaMask,
 *     WalletConnect) and the shared WalletModal.
 *   - The canonical deployment surface is the Base App in-app browser on mobile
 *     with local wagmi/viem signing by ghostkey.base.eth. MetaMask and
 *     WalletConnect may connect and read, but are labeled non-canonical.
 *   - Chain switching uses the retained EIP-1193 provider from the context.
 *     There is no `window.ethereum` fallback for Coinbase/WalletConnect
 *     sessions.
 */

import React, { useEffect, useMemo, useState } from 'react';
import { useWalletAuth } from '../../lib/WalletAuthContext';
import WalletModal from '../../components/WalletModal';
import consoleData from './data/v3-launch-console-data.json';
import {
  AUTHORIZED_BASE_DEPLOYER,
  AUTHORIZED_BASE_DEPLOYER_LABEL,
  BASE_CHAIN_ID,
  BASE_CHAIN_ID_HEX,
  REJECTED_V3_AUTHORITY_ADDRESSES,
  SOLANA_V2_MANIFEST_PAYEE,
  evaluateOperatorAccess,
  evaluateSigningAvailability,
  isCanonicalWallet,
  resolveTrackState,
  screenPublicRoleInput,
} from './launchGuards';

type TrackState = 'prepared' | 'blocked' | 'deployed' | 'activated';

const STATE_STYLES: Record<TrackState, string> = {
  prepared: 'border-amber-600 bg-amber-950/40 text-amber-200',
  blocked: 'border-red-700 bg-red-950/40 text-red-200',
  deployed: 'border-emerald-700 bg-emerald-950/40 text-emerald-200',
  activated: 'border-emerald-600 bg-emerald-900/40 text-emerald-100',
};

const CARD = 'rounded-lg border border-zinc-800 bg-zinc-950/80 p-5';
const LABEL = 'text-[11px] uppercase tracking-widest text-zinc-500';

function StateChip({ state, label }: { state: TrackState; label: string }) {
  return (
    <span className={`inline-flex items-center gap-2 rounded border px-2 py-1 text-[11px] font-semibold ${STATE_STYLES[state]}`}>
      <span aria-hidden="true">{state === 'prepared' ? '◐' : state === 'blocked' ? '⛔' : '●'}</span>
      {label}
    </span>
  );
}

export default function V3LaunchConsole() {
  const {
    address,
    chainId,
    activeWallet,
    connect,
    connectWallet,
    logout,
    modalOpen,
    setModalOpen,
    connecting,
    provider,
    providerSource,
    requestChainSwitch,
  } = useWalletAuth();

  const [switchError, setSwitchError] = useState<string | null>(null);
  const [switching, setSwitching] = useState(false);
  const [copied, setCopied] = useState<string | null>(null);
  const [formatCheck, setFormatCheck] = useState('');
  const [solanaWallet, setSolanaWallet] = useState<string | null>(null);

  // Read-only detection of an injected Solana wallet. Presence only: no
  // connection request, no account access, no signing. Solana stays blocked.
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const sol = (window as unknown as { solana?: { isPhantom?: boolean; isBackpack?: boolean } }).solana;
    if (!sol) return setSolanaWallet(null);
    setSolanaWallet(sol.isPhantom ? 'Phantom (injected)' : sol.isBackpack ? 'Backpack (injected)' : 'Injected Solana wallet');
  }, []);

  const access = useMemo(
    () => evaluateOperatorAccess({ address, chainId, activeWallet, requiresBaseChain: true }),
    [address, chainId, activeWallet],
  );

  const tracks = consoleData.tracks as Array<Record<string, any>>;

  const signing = useMemo(
    () =>
      evaluateSigningAvailability({
        access,
        transactionPackagePresent: consoleData.approvals.transactionPackagePresent,
        approvalArtifactPresent: consoleData.approvals.approvalArtifactPresent,
        approvalPhraseRequired: consoleData.approvals.baseReadOnlyPhrase,
        approvalPhraseProvided: null,
      }),
    [access],
  );

  const formatVerdict = screenPublicRoleInput(formatCheck);

  async function onSwitchToBase() {
    setSwitchError(null);
    setSwitching(true);
    // Uses the retained provider from the wallet context — never window.ethereum.
    const result = await requestChainSwitch(BASE_CHAIN_ID_HEX);
    if (!result.ok) setSwitchError(result.error ?? 'Chain switch failed');
    setSwitching(false);
  }

  function copy(id: string, text: string) {
    if (typeof navigator === 'undefined' || !navigator.clipboard) return;
    navigator.clipboard.writeText(text).then(
      () => {
        setCopied(id);
        window.setTimeout(() => setCopied(null), 1800);
      },
      () => setCopied(null),
    );
  }

  const roleTemplateJson = JSON.stringify(consoleData.roleInputs.emptyTemplate, null, 2);

  function downloadRoleTemplate() {
    const blob = new Blob([`${roleTemplateJson}\n`], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'base_v3_read_only_public_roles.template.json';
    a.click();
    URL.revokeObjectURL(url);
  }

  return (
    <div className="min-h-screen bg-black px-5 py-8 font-mono text-zinc-100">
      <div className="mx-auto max-w-4xl">
        <header className="mb-8">
          <p className={LABEL}>Vaultfire · operator console · not indexed</p>
          <h1 className="mt-2 text-2xl font-semibold">V3 Launch Console — read-only and locked</h1>
          <p className="mt-3 max-w-3xl text-sm leading-relaxed text-zinc-400">
            This console reports the state of four V3 launch tracks from checked-in public evidence. It contains no
            signing, sending, broadcast, payment, route-activation, or Bazaar-mutation control, because no verified
            immutable transaction package and no explicit approval artifact exist yet.
          </p>
          <p className="mt-2 text-xs text-zinc-500">{consoleData.provenance.auditClaim}</p>
        </header>

        {/* Non-negotiable safety notice. There is no field on this page that
            accepts signing material of any kind. */}
        <section className={`${CARD} mb-6 border-red-900 bg-red-950/20`}>
          <h2 className="text-sm font-semibold text-red-200">Never enter secrets here</h2>
          <p className="mt-2 text-xs leading-relaxed text-red-200/80">
            This page never asks for and cannot accept a private key, seed phrase, mnemonic, keystore file, or password.
            Public addresses only. All signing, if it is ever authorized, happens locally in your own wallet.
          </p>
        </section>

        {/* Wallet + authorization */}
        <section className={`${CARD} mb-6`}>
          <div className="flex flex-wrap items-start justify-between gap-4">
            <div>
              <p className={LABEL}>Authorized Base deployer</p>
              <p className="mt-1 break-all text-sm">
                {AUTHORIZED_BASE_DEPLOYER}{' '}
                <span className="text-zinc-500">({AUTHORIZED_BASE_DEPLOYER_LABEL})</span>
              </p>
              <p className="mt-2 text-xs text-zinc-500">{consoleData.authority.base.deployer.note}</p>
            </div>
            <div className="text-right">
              {address ? (
                <>
                  <p className={LABEL}>Connected</p>
                  <p className="mt-1 break-all text-xs">{address}</p>
                  <p className="mt-1 text-xs text-zinc-500">
                    wallet: {activeWallet ?? 'unknown'} · provider: {providerSource ?? 'none retained'} · chain:{' '}
                    {chainId ?? 'unknown'}
                  </p>
                  <button
                    type="button"
                    onClick={logout}
                    className="mt-2 rounded border border-zinc-700 px-3 py-1 text-xs hover:bg-zinc-900"
                  >
                    Disconnect
                  </button>
                </>
              ) : (
                <button
                  type="button"
                  onClick={connect}
                  className="rounded border border-blue-600 bg-blue-600/20 px-4 py-2 text-sm font-semibold text-blue-100 hover:bg-blue-600/30"
                >
                  Connect wallet
                </button>
              )}
            </div>
          </div>

          <div className="mt-4 rounded border border-blue-900 bg-blue-950/30 p-3 text-xs leading-relaxed text-blue-100/90">
            <strong className="font-semibold">Canonical surface:</strong>{' '}
            {consoleData.authority.base.canonicalConnectionPath.surface} —{' '}
            {consoleData.authority.base.canonicalConnectionPath.signingModel}.{' '}
            {consoleData.authority.base.canonicalConnectionPath.note}
            {address && !isCanonicalWallet(activeWallet) && (
              <p className="mt-2 text-amber-200">
                Connected via {activeWallet}. This is accepted for reading state, but it is not the canonical Base V3
                deployment path.
              </p>
            )}
          </div>

          {/* Fail-closed authorization result */}
          <div className="mt-4">
            {access.unlocked ? (
              <p className="rounded border border-emerald-800 bg-emerald-950/30 p-3 text-xs text-emerald-200">
                Authorized deployer session on Base {BASE_CHAIN_ID}. Read-only operator view unlocked. No action
                controls exist on this page.
              </p>
            ) : (
              <ul className="space-y-2">
                {access.blockers.map((b) => (
                  <li key={b} className="rounded border border-red-900 bg-red-950/30 p-3 text-xs text-red-200">
                    {b}
                  </li>
                ))}
              </ul>
            )}
            {address && access.authorized && !access.onBaseChain && (
              <div className="mt-3">
                <button
                  type="button"
                  onClick={onSwitchToBase}
                  disabled={switching || !provider}
                  className="rounded border border-blue-600 px-3 py-1 text-xs text-blue-100 disabled:opacity-40"
                >
                  {switching ? 'Switching…' : `Switch to Base ${BASE_CHAIN_ID}`}
                </button>
                {!provider && (
                  <span className="ml-2 text-xs text-zinc-500">
                    No retained wallet provider — reconnect to switch chains.
                  </span>
                )}
                {switchError && <p className="mt-2 text-xs text-red-300">{switchError}</p>}
              </div>
            )}
          </div>

          <div className="mt-4 border-t border-zinc-800 pt-4">
            <p className={LABEL}>Permanently rejected for V3 authority</p>
            <ul className="mt-2 space-y-1 text-xs text-zinc-400">
              {REJECTED_V3_AUTHORITY_ADDRESSES.map((entry) => (
                <li key={entry.address} className="break-all">
                  <span className="text-red-300">✕</span> {entry.address} — {entry.reason}
                </li>
              ))}
              <li className="break-all">
                <span className="text-red-300">✕</span> {SOLANA_V2_MANIFEST_PAYEE} —{' '}
                {consoleData.authority.solanaPublicPayee.classification};{' '}
                {consoleData.authority.solanaPublicPayee.disposition}
              </li>
            </ul>
          </div>
        </section>

        {/* Track state cards */}
        <section className="mb-6 space-y-4">
          <h2 className="text-sm font-semibold uppercase tracking-widest text-zinc-400">Launch tracks</h2>
          {tracks.map((track) => {
            const state = resolveTrackState(track) as TrackState;
            return (
              <article key={track.id} className={CARD} data-track={track.id} data-state={state}>
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div>
                    <h3 className="text-base font-semibold">{track.title}</h3>
                    <p className="text-xs text-zinc-500">{track.chain}</p>
                  </div>
                  <StateChip state={state} label={track.stateLabel} />
                </div>

                <dl className="mt-4 grid gap-x-6 gap-y-2 sm:grid-cols-2">
                  {track.facts
                    .filter((f: any) => f.value !== null && f.value !== '')
                    .map((f: any) => (
                      <div key={f.label} className="text-xs">
                        <dt className="text-zinc-500">{f.label}</dt>
                        <dd className="break-words text-zinc-200">{f.value}</dd>
                      </div>
                    ))}
                </dl>

                <div className="mt-4 rounded border border-zinc-800 bg-black/60 p-3">
                  <p className={LABEL}>No deployment claimed</p>
                  <p className="mt-1 text-xs text-zinc-400">
                    Deployed addresses recorded: none. Deployment transactions recorded: none.
                  </p>
                </div>

                <div className="mt-4">
                  <p className={LABEL}>Missing before this track can move</p>
                  <ul className="mt-2 space-y-1 text-xs text-zinc-300">
                    {track.missingArtifacts.map((m: string) => (
                      <li key={m}>— {m}</li>
                    ))}
                  </ul>
                </div>

                {track.blockers.filter((b: any) => b.summary).length > 0 && (
                  <div className="mt-4">
                    <p className={LABEL}>Status evidence</p>
                    <ul className="mt-2 space-y-2 text-xs text-zinc-400">
                      {track.blockers
                        .filter((b: any) => b.summary)
                        .map((b: any) => (
                          <li key={b.id}>
                            <span className="text-zinc-200">{b.id}</span>{' '}
                            <span className={b.provenance?.basis === 'current-status-correction' ? 'text-emerald-300' : 'text-red-300'}>
                              [{b.status}]
                            </span>{' '}
                            {b.summary}
                            {b.provenance?.basis === 'current-status-correction' && (
                              <p className="mt-1 text-zinc-500">
                                Historical status preserved from {b.provenance.historical.path}: [{b.provenance.historical.status}].{' '}
                                Current correction: {b.provenance.correctionEvidence}.
                              </p>
                            )}
                          </li>
                        ))}
                    </ul>
                  </div>
                )}

                {track.approvalPhrase && (
                  <p className="mt-4 text-xs text-zinc-400">
                    Required approval phrase, not yet provided:{' '}
                    <code className="rounded bg-zinc-900 px-1 text-zinc-200">{track.approvalPhrase}</code>
                  </p>
                )}

                {track.id === 'base-capped-partner-pilot' && (
                  <p className="mt-4 rounded border border-red-900 bg-red-950/30 p-3 text-xs text-red-200">
                    Pilot controls are locked pending the read-only deployment, an independent human audit, approved
                    roles/caps/partner consent, and the exact phrase “{track.approvalPhrase}”.
                  </p>
                )}

                {track.id === 'solana-v3' && (
                  <p className="mt-4 rounded border border-red-900 bg-red-950/30 p-3 text-xs text-red-200">
                    Solana remains blocked pending a native build and test pass, verified program IDs,
                    authority/custody decisions, and a reviewed transaction package. Detected injected Solana wallet:{' '}
                    {solanaWallet ?? 'none'} — detection is for connection/readiness only; this console offers no Solana
                    signing.
                  </p>
                )}

                {track.id === 'x402-v3' && (
                  <p className="mt-4 rounded border border-amber-900 bg-amber-950/20 p-3 text-xs text-amber-200">
                    x402 V3 is opt-in and configured-unverified. V2 remains the default. This console performs no route
                    activation, no payment, and no Bazaar mutation.
                  </p>
                )}
              </article>
            );
          })}
        </section>

        {/* Locked actions — explicit list of what is missing */}
        <section className={`${CARD} mb-6 border-red-900`}>
          <h2 className="text-sm font-semibold text-red-200">Signing, sending, and broadcast: unavailable</h2>
          <p className="mt-2 text-xs leading-relaxed text-zinc-300">{consoleData.approvals.note}</p>
          <p className="mt-3 text-xs text-zinc-500">
            controls rendered: {String(signing.controlsRendered)} · signing available: {String(signing.canSign)}
          </p>
          <ul className="mt-3 space-y-1 text-xs text-red-200">
            {signing.missing.map((m) => (
              <li key={m}>— missing: {m}</li>
            ))}
          </ul>
        </section>

        {/* Role input requirements */}
        <section className={`${CARD} mb-6`}>
          <h2 className="text-sm font-semibold">Role inputs required from the owner</h2>
          <p className="mt-2 text-xs text-zinc-400">
            Nothing here is pre-filled and no value is invented. The template ships every address field as{' '}
            <code className="rounded bg-zinc-900 px-1">null</code>. Source:{' '}
            <code className="break-all rounded bg-zinc-900 px-1">{consoleData.roleInputs.templatePath}</code> · sha256{' '}
            <span className="break-all text-zinc-500">{consoleData.roleInputs.templateSha256}</span>
          </p>

          <dl className="mt-4 grid gap-x-6 gap-y-2 text-xs sm:grid-cols-2">
            {Object.entries(consoleData.roleInputs.requiredCounts as Record<string, number>).map(([k, v]) => (
              <div key={k}>
                <dt className="text-zinc-500">{k}</dt>
                <dd className="text-zinc-200">{v}</dd>
              </div>
            ))}
          </dl>

          <ul className="mt-4 space-y-1 text-xs text-zinc-300">
            {consoleData.roleInputs.instructions.map((line: string) => (
              <li key={line}>— {line}</li>
            ))}
          </ul>

          <div className="mt-4">
            <p className={LABEL}>Custody disclosure classifications</p>
            <ul className="mt-2 space-y-2 text-xs text-zinc-400">
              {Object.entries(consoleData.roleInputs.allowedCustodyClassifications as Record<string, any>).map(
                ([key, val]) => (
                  <li key={key}>
                    <span className="text-zinc-200">{key}</span>: {val.meaning}
                  </li>
                ),
              )}
            </ul>
          </div>

          <div className="mt-4">
            <p className={LABEL}>Required confirmations</p>
            <ul className="mt-2 space-y-1 text-xs text-zinc-400">
              {(consoleData.roleInputs.confirmations as string[]).map((c) => (
                <li key={c}>— {c}</li>
              ))}
            </ul>
          </div>

          <div className="mt-5 flex flex-wrap gap-3">
            <button
              type="button"
              onClick={downloadRoleTemplate}
              className="rounded border border-zinc-700 px-3 py-2 text-xs hover:bg-zinc-900"
            >
              Download empty role template (.json)
            </button>
            <button
              type="button"
              onClick={() => copy('roles', roleTemplateJson)}
              className="rounded border border-zinc-700 px-3 py-2 text-xs hover:bg-zinc-900"
            >
              {copied === 'roles' ? 'Copied' : 'Copy template JSON'}
            </button>
          </div>

          {/* Local-only format check. No storage, no network, no submission. */}
          <div className="mt-5 border-t border-zinc-800 pt-4">
            <label htmlFor="v3-address-format-check" className={LABEL}>
              Local format check for one public address (nothing is stored or sent)
            </label>
            <input
              id="v3-address-format-check"
              name="publicAddressFormatCheck"
              type="text"
              inputMode="text"
              autoComplete="off"
              spellCheck={false}
              placeholder="0x… public Base address"
              value={formatCheck}
              onChange={(e) => setFormatCheck(e.target.value)}
              className="mt-2 w-full rounded border border-zinc-700 bg-black px-3 py-2 text-xs text-zinc-100"
            />
            {formatCheck.trim() !== '' && (
              <p className={`mt-2 text-xs ${formatVerdict.safe ? 'text-emerald-300' : 'text-red-300'}`}>
                {formatVerdict.safe ? 'Valid public address format.' : formatVerdict.reason}
              </p>
            )}
          </div>
        </section>

        {/* Provenance */}
        <section className={`${CARD} mb-10`}>
          <h2 className="text-sm font-semibold">Provenance</h2>
          <p className="mt-2 text-xs text-zinc-400">{consoleData.provenance.derivation}</p>
          <ul className="mt-3 space-y-1 text-xs text-zinc-500">
            {consoleData.provenance.sources.map((s: any) => (
              <li key={s.path} className="break-all">
                {s.path} · {s.bytes} bytes · sha256 {s.sha256}
              </li>
            ))}
          </ul>
          <dl className="mt-4 grid gap-x-6 gap-y-2 text-xs sm:grid-cols-2">
            <div>
              <dt className="text-zinc-500">Branch</dt>
              <dd className="break-all text-zinc-200">{consoleData.provenance.branch}</dd>
            </div>
            <div>
              <dt className="text-zinc-500">Validated combined source commit</dt>
              <dd className="break-all text-zinc-200">{consoleData.provenance.validatedCombinedSourceCommit}</dd>
            </div>
            <div>
              <dt className="text-zinc-500">Frozen source commit</dt>
              <dd className="break-all text-zinc-200">{consoleData.provenance.frozenSourceCommit}</dd>
            </div>
            <div>
              <dt className="text-zinc-500">Independent human audit complete</dt>
              <dd className="text-zinc-200">{String(consoleData.provenance.independentHumanAuditComplete)}</dd>
            </div>
          </dl>
          <p className="mt-4 text-xs text-zinc-500">{consoleData.provenance.disclaimer}</p>
          <div className="mt-4 rounded border border-amber-900 bg-amber-950/20 p-3 text-xs text-amber-100">
            <p className={LABEL}>Current-status corrections</p>
            <p className="mt-1">{consoleData.provenance.currentStatusCorrections.purpose}</p>
            <p className="mt-2 text-zinc-400">
              Evidence: {consoleData.provenance.currentStatusCorrections.path} · corrected findings:{' '}
              {(consoleData.provenance.currentStatusCorrections.correctedFindingIds as string[]).join(', ')}
            </p>
          </div>
          <div className="mt-4">
            <p className={LABEL}>Claims explicitly not made</p>
            <p className="mt-1 text-xs text-zinc-400">{(consoleData.provenance.claimsNotMade as string[]).join(' · ')}</p>
          </div>
          <div className="mt-4">
            <p className={LABEL}>Remaining human decisions</p>
            <ul className="mt-2 space-y-1 text-xs text-zinc-400">
              {(consoleData.remainingHumanDecisions as string[]).map((d) => (
                <li key={d}>— {d}</li>
              ))}
            </ul>
          </div>
        </section>
      </div>

      <WalletModal
        isOpen={modalOpen}
        onClose={() => setModalOpen(false)}
        onSelect={connectWallet}
        connecting={connecting}
      />
    </div>
  );
}
