import * as React from 'react';
import { useState } from 'react';
import { useParams, Link } from 'react-router-dom';
import { api, type Agent, type Prompt, type Personality } from '../api';
import { useFetch } from '../hooks/useFetch';
import { PromptEditor, type PromptDraft } from '../components/PromptEditor';

/**
 * Agent detail page. Two tabs:
 *   - Direct prompts (Prompt.agentId === agent.id) — always-on overlay.
 *   - Personalities — list, create, click-through to bind prompts.
 *
 * Why both on one page: an agent's "what it does" lives in this triple
 * (systemPrompt + direct prompts + personalities). Splitting them across
 * routes hides the relationship that the chat engine cares about.
 */
type Tab = 'direct' | 'personalities';

export function AgentDetailPage(): React.JSX.Element {
  const { name } = useParams<{ name: string }>();
  const agentName = name ?? '';
  const { data: agent, error: agentError, loading: agentLoading } = useFetch(
    () => api.get<Agent>(`/api/v1/agents/${encodeURIComponent(agentName)}`),
    [agentName],
  );
  const [tab, setTab] = useState<Tab>('direct');

  if (agentLoading) return <div>Loading agent…</div>;
  if (agentError !== null) return <div style={{ color: '#ff7b72' }}>Error: {agentError.message}</div>;
  if (agent === null) return <div>Not found.</div>;

  return (
    <section>
      <p style={{ marginTop: 0 }}>
        <Link to="/agents" style={{ color: '#58a6ff' }}>← Agents</Link>
      </p>
      <h2 style={{ marginTop: 0 }}>
        {agent.name}
        <span style={{ color: '#7d8590', fontSize: 14, marginLeft: 12 }}>
          {agent.llm.name}{agent.project !== null && ` · ${agent.project.name}`}
        </span>
      </h2>
      {agent.systemPrompt !== '' && (
        <details style={{ background: '#161b22', border: '1px solid #30363d', borderRadius: 6, padding: 12, margin: '12px 0' }}>
          <summary style={{ cursor: 'pointer', color: '#7d8590' }}>System prompt</summary>
          <pre style={{ background: '#0d1117', padding: 12, borderRadius: 4, marginTop: 8, whiteSpace: 'pre-wrap' }}>{agent.systemPrompt}</pre>
        </details>
      )}
      <div style={{ display: 'flex', gap: 4, borderBottom: '1px solid #30363d', marginBottom: 16 }}>
        <TabButton active={tab === 'direct'} onClick={() => setTab('direct')}>Direct prompts</TabButton>
        <TabButton active={tab === 'personalities'} onClick={() => setTab('personalities')}>Personalities</TabButton>
      </div>
      {tab === 'direct' && <DirectPromptsTab agentName={agentName} />}
      {tab === 'personalities' && <PersonalitiesTab agentName={agentName} />}
    </section>
  );
}

function TabButton({ active, onClick, children }: { active: boolean; onClick: () => void; children: React.ReactNode }): React.JSX.Element {
  return (
    <button
      onClick={onClick}
      style={{
        background: 'transparent',
        color: active ? '#58a6ff' : '#c9d1d9',
        border: 'none',
        borderBottom: active ? '2px solid #58a6ff' : '2px solid transparent',
        padding: '8px 16px',
        cursor: 'pointer',
        marginBottom: -1,
      }}
    >
      {children}
    </button>
  );
}

// ── Direct prompts tab ──

function DirectPromptsTab({ agentName }: { agentName: string }): React.JSX.Element {
  const { data, error, loading, refetch } = useFetch(
    () => api.get<Prompt[]>(`/api/v1/agents/${encodeURIComponent(agentName)}/prompts`),
    [agentName],
  );
  const [creating, setCreating] = useState(false);
  const [busy, setBusy] = useState(false);

  if (loading) return <div>Loading…</div>;
  if (error !== null) return <div style={{ color: '#ff7b72' }}>Error: {error.message}</div>;
  const prompts = data ?? [];

  async function handleCreate(draft: PromptDraft): Promise<void> {
    setBusy(true);
    try {
      await api.post('/api/v1/prompts', {
        name: draft.name,
        content: draft.content,
        priority: draft.priority,
        agent: agentName,
      });
      setCreating(false);
      refetch();
    } finally {
      setBusy(false);
    }
  }

  async function handleDelete(id: string, name: string): Promise<void> {
    if (!confirm(`Delete prompt '${name}'?`)) return;
    await api.delete(`/api/v1/prompts/${id}`);
    refetch();
  }

  return (
    <div>
      <p style={{ color: '#7d8590', marginTop: 0 }}>
        Always-on prompts for this agent. Injected after the agent's system prompt and before project prompts.
      </p>
      {!creating && (
        <button onClick={() => setCreating(true)} style={primaryBtn}>+ New direct prompt</button>
      )}
      {creating && (
        <div style={card}>
          <h3>New direct prompt</h3>
          <PromptEditor
            submitLabel="Create"
            onSubmit={handleCreate}
            onCancel={() => setCreating(false)}
            busy={busy}
          />
        </div>
      )}
      {prompts.length === 0 && !creating && <p style={{ color: '#7d8590' }}>No direct prompts yet.</p>}
      <ul style={{ listStyle: 'none', padding: 0, margin: '16px 0 0 0' }}>
        {prompts.sort((a, b) => b.priority - a.priority).map((p) => (
          <li key={p.id} style={card}>
            <div style={cardHeader}>
              <div>
                <strong style={{ fontFamily: 'ui-monospace, monospace' }}>{p.name}</strong>
                <span style={{ color: '#7d8590', marginLeft: 8, fontSize: 12 }}>priority {p.priority}</span>
              </div>
              <button onClick={() => handleDelete(p.id, p.name)} style={dangerBtn}>Delete</button>
            </div>
            <pre style={contentPre}>{p.content}</pre>
          </li>
        ))}
      </ul>
    </div>
  );
}

// ── Personalities tab ──

function PersonalitiesTab({ agentName }: { agentName: string }): React.JSX.Element {
  const { data, error, loading, refetch } = useFetch(
    () => api.get<Personality[]>(`/api/v1/agents/${encodeURIComponent(agentName)}/personalities`),
    [agentName],
  );
  const [creating, setCreating] = useState(false);
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [busy, setBusy] = useState(false);

  if (loading) return <div>Loading…</div>;
  if (error !== null) return <div style={{ color: '#ff7b72' }}>Error: {error.message}</div>;
  const personalities = data ?? [];

  async function handleCreate(e: React.FormEvent): Promise<void> {
    e.preventDefault();
    if (!/^[a-z0-9-]+$/.test(name)) {
      alert('Name must be lowercase alphanumeric with hyphens.');
      return;
    }
    setBusy(true);
    try {
      await api.post(`/api/v1/agents/${encodeURIComponent(agentName)}/personalities`, {
        name, description,
      });
      setName('');
      setDescription('');
      setCreating(false);
      refetch();
    } catch (err) {
      alert((err as Error).message);
    } finally {
      setBusy(false);
    }
  }

  async function handleDelete(id: string, name: string): Promise<void> {
    if (!confirm(`Delete personality '${name}'?`)) return;
    await api.delete(`/api/v1/personalities/${id}`);
    refetch();
  }

  return (
    <div>
      <p style={{ color: '#7d8590', marginTop: 0 }}>
        Named overlays of prompts. Pick at chat time with <code>--personality &lt;name&gt;</code> or set
        a default on the agent.
      </p>
      {!creating && (
        <button onClick={() => setCreating(true)} style={primaryBtn}>+ New personality</button>
      )}
      {creating && (
        <form onSubmit={handleCreate} style={card}>
          <h3>New personality</h3>
          <div style={{ display: 'flex', gap: 12, marginBottom: 12 }}>
            <label style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 4, fontSize: 12, color: '#7d8590' }}>
              Name
              <input
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="grumpy"
                style={input}
              />
            </label>
            <label style={{ flex: 2, display: 'flex', flexDirection: 'column', gap: 4, fontSize: 12, color: '#7d8590' }}>
              Description
              <input
                type="text"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder="Be terse and slightly grumpy"
                style={input}
              />
            </label>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button type="submit" disabled={busy} style={primaryBtn}>{busy ? 'Saving…' : 'Create'}</button>
            <button type="button" onClick={() => setCreating(false)} style={secondaryBtn}>Cancel</button>
          </div>
        </form>
      )}
      {personalities.length === 0 && !creating && <p style={{ color: '#7d8590' }}>No personalities yet.</p>}
      <ul style={{ listStyle: 'none', padding: 0, margin: '16px 0 0 0' }}>
        {personalities.map((p) => (
          <li key={p.id} style={card}>
            <div style={cardHeader}>
              <div>
                <Link
                  to={`/personalities/${p.id}`}
                  style={{ color: '#58a6ff', fontFamily: 'ui-monospace, monospace', fontWeight: 600, textDecoration: 'none' }}
                >
                  {p.name}
                </Link>
                <span style={{ color: '#7d8590', marginLeft: 8, fontSize: 12 }}>
                  {p.promptCount} prompt{p.promptCount === 1 ? '' : 's'}
                </span>
              </div>
              <button onClick={() => handleDelete(p.id, p.name)} style={dangerBtn}>Delete</button>
            </div>
            {p.description !== '' && <div style={{ color: '#c9d1d9' }}>{p.description}</div>}
          </li>
        ))}
      </ul>
    </div>
  );
}

const card: React.CSSProperties = {
  background: '#161b22',
  border: '1px solid #30363d',
  borderRadius: 6,
  padding: 16,
  margin: '12px 0',
};
const cardHeader: React.CSSProperties = {
  display: 'flex',
  justifyContent: 'space-between',
  alignItems: 'center',
  marginBottom: 8,
};
const contentPre: React.CSSProperties = {
  background: '#0d1117',
  color: '#c9d1d9',
  padding: 12,
  borderRadius: 4,
  margin: 0,
  whiteSpace: 'pre-wrap',
  fontFamily: 'ui-monospace, "SF Mono", Menlo, monospace',
  fontSize: 12,
};
const input: React.CSSProperties = {
  background: '#0d1117',
  color: '#c9d1d9',
  border: '1px solid #30363d',
  borderRadius: 4,
  padding: '6px 10px',
  fontFamily: 'ui-monospace, "SF Mono", Menlo, monospace',
};
const primaryBtn: React.CSSProperties = {
  background: '#238636',
  color: '#fff',
  border: 'none',
  borderRadius: 4,
  padding: '8px 16px',
  cursor: 'pointer',
  fontWeight: 600,
};
const secondaryBtn: React.CSSProperties = {
  background: 'transparent',
  color: '#c9d1d9',
  border: '1px solid #30363d',
  borderRadius: 4,
  padding: '8px 16px',
  cursor: 'pointer',
};
const dangerBtn: React.CSSProperties = {
  background: 'transparent',
  color: '#ff7b72',
  border: '1px solid #f85149',
  borderRadius: 4,
  padding: '4px 12px',
  cursor: 'pointer',
};
