'use client';

import { useState, useEffect, useCallback } from 'react';
import { listIPNSKeys, ipnsPublish, ipnsResolve, ipnsGenKey, type IPNSKey } from '@/lib/api/ipns';
import PortalLayout from '@/app/layout-portal';
import { RefreshCw, ExternalLink, Key, FileText, Plus } from 'lucide-react';
import { SkeletonTable } from '@/components/Skeleton';

import ErrorBoundary from '@/components/ErrorBoundary';
import type { Status } from './helpers';

export default function IPNSPage() {
  const [keys, setKeys] = useState<IPNSKey[]>([]);
  const [status, setStatus] = useState<Status>('loading');
  const [error, setError] = useState('');

  // Publish form
  const [pubCid, setPubCid] = useState('');
  const [pubKey, setPubKey] = useState('self');
  const [pubResult, setPubResult] = useState<{ name: string; value: string } | null>(null);
  const [pubLoading, setPubLoading] = useState(false);
  const [pubError, setPubError] = useState('');

  // Resolve form
  const [resolveName, setResolveName] = useState('');
  const [resolveResult, setResolveResult] = useState('');
  const [resolveLoading, setResolveLoading] = useState(false);
  const [resolveError, setResolveError] = useState('');

  // Gen key form
  const [genName, setGenName] = useState('');
  const [genLoading, setGenLoading] = useState(false);
  const [genError, setGenError] = useState('');

  const loadKeys = useCallback(async () => {
    setStatus('loading');
    setError('');
    try {
      const k = await listIPNSKeys();
      setKeys(k);
      setStatus('success');
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Failed to load keys');
      setStatus('error');
    }
  }, []);

  useEffect(() => { loadKeys(); }, [loadKeys]);

  const handlePublish = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!pubCid.trim()) return;
    setPubLoading(true);
    setPubError('');
    setPubResult(null);
    try {
      const res = await ipnsPublish(pubCid.trim(), pubKey);
      setPubResult(res);
    } catch (e) {
      setPubError(e instanceof Error ? e.message : 'Publish failed');
    } finally {
      setPubLoading(false);
    }
  };

  const handleResolve = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!resolveName.trim()) return;
    setResolveLoading(true);
    setResolveError('');
    setResolveResult('');
    try {
      const path = await ipnsResolve(resolveName.trim());
      setResolveResult(path);
    } catch (e) {
      setResolveError(e instanceof Error ? e.message : 'Resolve failed');
    } finally {
      setResolveLoading(false);
    }
  };

  const handleGenKey = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!genName.trim()) return;
    setGenLoading(true);
    setGenError('');
    try {
      await ipnsGenKey(genName.trim());
      setGenName('');
      await loadKeys();
    } catch (e) {
      setGenError(e instanceof Error ? e.message : 'Key generation failed');
    } finally {
      setGenLoading(false);
    }
  };

  return (
    <PortalLayout>
      <ErrorBoundary label="IPNS">
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-2xl font-bold text-white">IPNS</h1>
          <p className="text-sm text-surface-400 mt-0.5">
            InterPlanetary Name System — human-readable names for IPFS content
          </p>
        </div>
        <button
          onClick={loadKeys}
          className="btn-ghost p-2 rounded-lg text-surface-400 hover:text-surface-200"
          title="Refresh keys"
        >
          <RefreshCw className={`w-4 h-4 ${status === 'loading' ? 'animate-spin' : ''}`} />
        </button>
      </div>

      {/* Keys */}
      <section className="glass rounded-xl border border-surface-800 p-5">
        <div className="flex items-center justify-between mb-4">
          <h2 className="text-sm font-semibold text-surface-200 flex items-center gap-2">
            <Key className="w-4 h-4 text-brand-400" />
            Signing Keys
          </h2>
          <span className="text-xs text-surface-500">{keys.length} key{keys.length !== 1 ? 's' : ''}</span>
        </div>

        {status === 'loading' && (
          <div className="overflow-hidden">
            <SkeletonTable rows={4} cols={3} />
          </div>
        )}

        {status === 'error' && (
          <div className="text-sm text-accent-rose bg-accent-rose/5 border border-accent-rose/20 rounded-lg p-3">
            {error}
          </div>
        )}

        {status === 'success' && keys.length === 0 && (
          <p className="text-sm text-surface-500 py-2">No IPNS keys found.</p>
        )}

        {keys.length > 0 && (
          <div className="space-y-2">
            {keys.map((key) => (
              <div
                key={key.id}
                className="flex items-center justify-between p-3 rounded-lg bg-surface-900/50 border border-surface-800/50 hover:border-surface-700/50 transition-colors"
              >
                <div className="min-w-0 flex-1">
                  <p className="text-sm font-medium text-surface-200 truncate">{key.name}</p>
                  <p className="text-xs text-surface-500 font-mono truncate mt-0.5">{key.id}</p>
                </div>
                <button
                  onClick={() => setResolveName(key.id)}
                  className="btn-ghost p-1.5 rounded-md text-surface-500 hover:text-surface-300 shrink-0 ml-3"
                  title="Resolve this key"
                >
                  <ExternalLink className="w-3.5 h-3.5" />
                </button>
              </div>
            ))}
          </div>
        )}

        {/* Generate key */}
        <form onSubmit={handleGenKey} className="mt-4 pt-4 border-t border-surface-800">
          <label className="text-xs font-medium text-surface-500 mb-1.5 block">Generate New Key</label>
          <div className="flex gap-2">
            <input
              type="text"
              value={genName}
              onChange={(e) => setGenName(e.target.value)}
              placeholder="key-name"
              className="flex-1 px-3 py-1.5 text-sm bg-surface-900 border border-surface-700 rounded-lg text-surface-200 placeholder-surface-600 focus:outline-none focus:border-brand-500/50"
              required
            />
            <button
              type="submit"
              disabled={genLoading || !genName.trim()}
              className="btn-primary px-4 py-1.5 text-sm rounded-lg disabled:opacity-40 flex items-center gap-1.5"
            >
              {genLoading ? (
                <RefreshCw className="w-3.5 h-3.5 animate-spin" />
              ) : (
                <Plus className="w-3.5 h-3.5" />
              )}
              Generate
            </button>
          </div>
          {genError && <p className="text-xs text-accent-rose mt-1">{genError}</p>}
        </form>
      </section>

      {/* Two-column: Publish + Resolve */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Publish */}
        <section className="glass rounded-xl border border-surface-800 p-5">
          <h2 className="text-sm font-semibold text-surface-200 flex items-center gap-2 mb-4">
            <FileText className="w-4 h-4 text-brand-400" />
            Publish
          </h2>
          <p className="text-xs text-surface-500 mb-4">
            Point an IPNS name to a CID. Publish is signed with the selected key.
          </p>
          <form onSubmit={handlePublish} className="space-y-3">
            <div>
              <label className="text-xs font-medium text-surface-500 mb-1 block">CID</label>
              <input
                type="text"
                value={pubCid}
                onChange={(e) => setPubCid(e.target.value)}
                placeholder="Qm... or bafy..."
                className="w-full px-3 py-1.5 text-sm bg-surface-900 border border-surface-700 rounded-lg text-surface-200 placeholder-surface-600 focus:outline-none focus:border-brand-500/50 font-mono"
                required
              />
            </div>
            <div>
              <label className="text-xs font-medium text-surface-500 mb-1 block">Key</label>
              <select
                value={pubKey}
                onChange={(e) => setPubKey(e.target.value)}
                className="w-full px-3 py-1.5 text-sm bg-surface-900 border border-surface-700 rounded-lg text-surface-200 focus:outline-none focus:border-brand-500/50"
              >
                {keys.map((k) => (
                  <option key={k.id} value={k.name}>{k.name}</option>
                ))}
              </select>
            </div>
            <button
              type="submit"
              disabled={pubLoading || !pubCid.trim()}
              className="btn-primary w-full py-2 text-sm rounded-lg disabled:opacity-40"
            >
              {pubLoading ? 'Publishing...' : 'Publish'}
            </button>
          </form>
          {pubError && <p className="text-xs text-accent-rose mt-2">{pubError}</p>}
          {pubResult && (
            <div className="mt-3 p-3 rounded-lg bg-surface-900/50 border border-surface-800 text-xs space-y-1">
              <p className="text-surface-400">Name: <span className="text-surface-200 font-mono">{pubResult.name}</span></p>
              <p className="text-surface-400">Value: <span className="text-surface-200 font-mono break-all">{pubResult.value}</span></p>
            </div>
          )}
        </section>

        {/* Resolve */}
        <section className="glass rounded-xl border border-surface-800 p-5">
          <h2 className="text-sm font-semibold text-surface-200 flex items-center gap-2 mb-4">
            <ExternalLink className="w-4 h-4 text-brand-400" />
            Resolve
          </h2>
          <p className="text-xs text-surface-500 mb-4">
            Resolve an IPNS name or peer ID to the current IPFS path.
          </p>
          <form onSubmit={handleResolve} className="space-y-3">
            <div>
              <label className="text-xs font-medium text-surface-500 mb-1 block">Name / Peer ID</label>
              <input
                type="text"
                value={resolveName}
                onChange={(e) => setResolveName(e.target.value)}
                placeholder="k51... or /ipns/example.com"
                className="w-full px-3 py-1.5 text-sm bg-surface-900 border border-surface-700 rounded-lg text-surface-200 placeholder-surface-600 focus:outline-none focus:border-brand-500/50 font-mono"
                required
              />
            </div>
            <button
              type="submit"
              disabled={resolveLoading || !resolveName.trim()}
              className="btn-primary w-full py-2 text-sm rounded-lg disabled:opacity-40"
            >
              {resolveLoading ? 'Resolving...' : 'Resolve'}
            </button>
          </form>
          {resolveError && <p className="text-xs text-accent-rose mt-2">{resolveError}</p>}
          {resolveResult && (
            <div className="mt-3 p-3 rounded-lg bg-surface-900/50 border border-surface-800 text-xs">
              <p className="text-surface-400">Resolved to:</p>
              <p className="text-surface-200 font-mono break-all mt-1">{resolveResult}</p>
            </div>
          )}
        </section>
      </div>
      </ErrorBoundary>
    </PortalLayout>
  );
}
