/**
 * SkillsForm.tsx — Settings > Skills tab
 *
 * Two-column list + detail layout for browsing, creating, editing, and
 * deleting agent skills. Supports installing skills from a URL.
 */

import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useAuthState } from '../../App';
import {
  fetchSkills,
  fetchSkillDetail,
  createSkill,
  updateSkill,
  deleteSkill,
  installSkillFromUrl,
  type SkillSummary,
  type SkillDetail,
} from '../../api';

// ── Helpers ──────────────────────────────────────────────────────────────────

const NAME_RE = /^[a-z0-9][a-z0-9_-]*$/;

function SourceBadge({ source }: { source: 'system' | 'user' }) {
  return source === 'system' ? (
    <span className="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-semibold bg-slate-100 text-slate-600">
      <span aria-label="locked">&#128274;</span> system
    </span>
  ) : (
    <span className="inline-block px-1.5 py-0.5 rounded text-[10px] font-semibold bg-blue-50 text-blue-700">
      user
    </span>
  );
}

function SeverityBadge({ severity }: { severity: string }) {
  if (severity === 'high') {
    return <span className="inline-block px-1.5 py-0.5 rounded text-[10px] font-semibold bg-red-100 text-red-700">HIGH</span>;
  }
  if (severity === 'medium') {
    return <span className="inline-block px-1.5 py-0.5 rounded text-[10px] font-semibold bg-yellow-100 text-yellow-800">MEDIUM</span>;
  }
  return null;
}

// ── Main Component ───────────────────────────────────────────────────────────

export function SkillsForm() {
  const qc = useQueryClient();
  const auth = useAuthState();
  const isAdmin = auth.mode === 'authenticated' && auth.user.role === 'admin';

  const [selected, setSelected] = useState<string | null>(null);
  const [editMode, setEditMode] = useState(false);
  const [editContent, setEditContent] = useState('');
  const [newMode, setNewMode] = useState(false);
  const [newName, setNewName] = useState('');
  const [newContent, setNewContent] = useState('');
  const [newScope, setNewScope] = useState<'user' | 'system'>('user');
  const [installUrl, setInstallUrl] = useState('');
  const [error, setError] = useState<string | null>(null);

  // ── Queries ──────────────────────────────────────────────────────────────

  const skillsQuery = useQuery<SkillSummary[]>({
    queryKey: ['skills'],
    queryFn: () => fetchSkills(),
  });

  const detailQuery = useQuery<SkillDetail>({
    queryKey: ['skill-detail', selected],
    queryFn: () => fetchSkillDetail(selected!),
    enabled: !!selected && !newMode,
  });

  // ── Mutations ────────────────────────────────────────────────────────────

  const createMut = useMutation({
    mutationFn: () => createSkill(newName.trim(), newContent, newScope),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['skills'] });
      setSelected(newName.trim());
      setNewMode(false);
      setNewName('');
      setNewContent('');
      setError(null);
    },
    onError: (e: Error) => setError(e.message),
  });

  const updateMut = useMutation({
    mutationFn: ({ name, content, scope }: { name: string; content: string; scope: string }) =>
      updateSkill(name, content, scope),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['skills'] });
      qc.invalidateQueries({ queryKey: ['skill-detail', selected] });
      setEditMode(false);
      setError(null);
    },
    onError: (e: Error) => setError(e.message),
  });

  const deleteMut = useMutation({
    mutationFn: ({ name, scope }: { name: string; scope: string }) => deleteSkill(name, scope),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['skills'] });
      setSelected(null);
      setEditMode(false);
      setError(null);
    },
    onError: (e: Error) => setError(e.message),
  });

  const installMut = useMutation({
    mutationFn: () => installSkillFromUrl(installUrl.trim(), 'user'),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['skills'] });
      setInstallUrl('');
      setError(null);
    },
    onError: (e: Error) => setError(e.message),
  });

  // ── Handlers ─────────────────────────────────────────────────────────────

  const skills = skillsQuery.data ?? [];

  const handleSelect = (name: string) => {
    setSelected(name);
    setNewMode(false);
    setEditMode(false);
    setError(null);
  };

  const handleNew = () => {
    setNewMode(true);
    setSelected(null);
    setEditMode(false);
    setNewName('');
    setNewContent('');
    setNewScope('user');
    setError(null);
  };

  const handleStartEdit = () => {
    if (detailQuery.data) {
      setEditContent(detailQuery.data.content);
      setEditMode(true);
      setError(null);
    }
  };

  const handleSaveEdit = () => {
    if (!selected || !detailQuery.data) return;
    updateMut.mutate({ name: selected, content: editContent, scope: detailQuery.data.source });
  };

  const handleDelete = () => {
    if (!selected || !detailQuery.data) return;
    if (!confirm(`Delete skill "${selected}"?`)) return;
    deleteMut.mutate({ name: selected, scope: detailQuery.data.source });
  };

  const canEdit = (skill: SkillSummary | SkillDetail | undefined) => {
    if (!skill) return false;
    return skill.source === 'user' || isAdmin;
  };

  // ── Render ───────────────────────────────────────────────────────────────

  return (
    <div>
      <h2 className="text-sm font-semibold text-slate-800 mb-3">Skills</h2>
      <p className="text-xs text-slate-500 mb-4">
        Skills are agent reference guides and knowledge bases. They provide context and instructions to the agent during task execution.
      </p>

      {error && (
        <div className="mb-3 px-3 py-2 rounded bg-red-50 border border-red-200 text-xs text-red-700">
          {error}
        </div>
      )}

      <div className="flex gap-4" style={{ minHeight: '500px' }}>
        {/* ── Left panel: list ────────────────────────────────────────── */}
        <div className="w-1/3 border border-hairline rounded-lg p-3 overflow-y-auto flex flex-col gap-2">
          {/* Install from URL */}
          <div className="flex gap-1.5">
            <input
              type="text"
              placeholder="Install from URL..."
              value={installUrl}
              onChange={e => setInstallUrl(e.target.value)}
              className="flex-1 min-w-0 px-2 py-1 text-xs border border-hairline rounded bg-white text-slate-700 placeholder:text-slate-400"
            />
            <button
              onClick={() => installMut.mutate()}
              disabled={!installUrl.trim() || installMut.isPending}
              className="px-2 py-1 text-xs font-semibold bg-accent text-accent-fg rounded hover:bg-accent-deep disabled:opacity-50 transition-colors whitespace-nowrap flex-shrink-0"
            >
              {installMut.isPending ? '...' : 'Install'}
            </button>
          </div>

          {/* Skill list */}
          {skillsQuery.isLoading ? (
            <div className="text-xs text-slate-400 py-4 text-center">Loading...</div>
          ) : skills.length === 0 ? (
            <div className="text-xs text-slate-400 py-4 text-center">No skills installed</div>
          ) : (
            <div className="flex flex-col gap-0.5">
              {skills.map(s => (
                <button
                  key={s.name}
                  onClick={() => handleSelect(s.name)}
                  className={`w-full text-left px-2 py-1.5 rounded text-xs transition-colors ${
                    selected === s.name && !newMode
                      ? 'bg-accent-soft text-accent font-semibold'
                      : 'text-slate-700 hover:bg-surface'
                  }`}
                >
                  <div className="flex items-center gap-1.5">
                    <span className="truncate font-medium">{s.name}</span>
                    <SourceBadge source={s.source} />
                  </div>
                  {s.description && (
                    <div className="text-[10px] text-slate-500 truncate mt-0.5">{s.description}</div>
                  )}
                </button>
              ))}
            </div>
          )}

          {/* New skill button */}
          <button
            onClick={handleNew}
            className="mt-auto px-2 py-1.5 text-xs font-semibold text-accent border border-accent/30 rounded hover:bg-accent-soft transition-colors"
          >
            + New Skill
          </button>
        </div>

        {/* ── Right panel: detail / new / empty ──────────────────────── */}
        <div className="flex-1 border border-hairline rounded-lg p-4 overflow-y-auto">
          {newMode ? (
            /* ── New skill form ─────────────────────────────────────── */
            <div className="flex flex-col gap-3">
              <h3 className="text-sm font-semibold text-slate-800">Create New Skill</h3>

              <label className="block">
                <span className="text-xs text-slate-600 font-medium">Name</span>
                <input
                  type="text"
                  value={newName}
                  onChange={e => setNewName(e.target.value)}
                  placeholder="my-skill-name"
                  className="mt-1 block w-full px-2 py-1.5 text-xs border border-hairline rounded bg-white text-slate-700 placeholder:text-slate-400"
                />
                {newName && !NAME_RE.test(newName) && (
                  <span className="text-[10px] text-red-500 mt-0.5">Lowercase letters, numbers, hyphens, underscores only</span>
                )}
              </label>

              <label className="block">
                <span className="text-xs text-slate-600 font-medium">Content</span>
                <textarea
                  value={newContent}
                  onChange={e => setNewContent(e.target.value)}
                  rows={14}
                  className="mt-1 block w-full px-2 py-1.5 text-xs font-mono border border-hairline rounded bg-white text-slate-700 resize-y"
                  placeholder="# My Skill&#10;&#10;Instructions for the agent..."
                />
              </label>

              <fieldset>
                <legend className="text-xs text-slate-600 font-medium mb-1">Scope</legend>
                <div className="flex gap-4">
                  <label className="flex items-center gap-1.5 text-xs text-slate-700">
                    <input type="radio" name="scope" value="user" checked={newScope === 'user'} onChange={() => setNewScope('user')} />
                    Personal
                  </label>
                  {isAdmin && (
                    <label className="flex items-center gap-1.5 text-xs text-slate-700">
                      <input type="radio" name="scope" value="system" checked={newScope === 'system'} onChange={() => setNewScope('system')} />
                      System
                    </label>
                  )}
                </div>
              </fieldset>

              <div className="flex gap-2">
                <button
                  onClick={() => createMut.mutate()}
                  disabled={!newName.trim() || !NAME_RE.test(newName) || !newContent.trim() || createMut.isPending}
                  className="px-3 py-1.5 text-xs font-semibold bg-accent text-accent-fg rounded hover:bg-accent-deep disabled:opacity-50 transition-colors"
                >
                  {createMut.isPending ? 'Creating...' : 'Create'}
                </button>
                <button
                  onClick={() => { setNewMode(false); setError(null); }}
                  className="px-3 py-1.5 text-xs text-slate-700 border border-hairline rounded hover:bg-surface transition-colors"
                >
                  Cancel
                </button>
              </div>
            </div>
          ) : selected && detailQuery.data ? (
            /* ── Skill detail ──────────────────────────────────────── */
            <div className="flex flex-col gap-3">
              <div className="flex items-center gap-2">
                <h3 className="text-sm font-semibold text-slate-800">{detailQuery.data.name}</h3>
                <SourceBadge source={detailQuery.data.source} />
                {detailQuery.data.maxSeverity !== 'none' && (
                  <SeverityBadge severity={detailQuery.data.maxSeverity} />
                )}
              </div>

              {detailQuery.data.description && (
                <p className="text-xs text-slate-600">{detailQuery.data.description}</p>
              )}

              {detailQuery.data.triggers.length > 0 && (
                <div className="flex flex-wrap gap-1">
                  {detailQuery.data.triggers.map(t => (
                    <span key={t} className="px-1.5 py-0.5 rounded text-[10px] bg-slate-100 text-slate-600 font-mono">{t}</span>
                  ))}
                </div>
              )}

              {/* Findings */}
              {detailQuery.data.findings.length > 0 && (
                <div className="border border-yellow-200 bg-yellow-50 rounded p-2 flex flex-col gap-1">
                  <div className="text-xs font-semibold text-yellow-800">Security Findings</div>
                  {detailQuery.data.findings.map((f, i) => (
                    <div key={i} className="text-[10px] text-yellow-700 font-mono">
                      <SeverityBadge severity={f.severity} />{' '}
                      L{f.line}: {f.pattern} &mdash; <code>{f.match}</code>
                      {f.file && <span className="text-slate-500"> ({f.file})</span>}
                    </div>
                  ))}
                </div>
              )}

              {/* Content */}
              {editMode ? (
                <div className="flex flex-col gap-2">
                  <textarea
                    value={editContent}
                    onChange={e => setEditContent(e.target.value)}
                    rows={18}
                    className="block w-full px-2 py-1.5 text-xs font-mono border border-hairline rounded bg-white text-slate-700 resize-y"
                  />
                  <div className="flex gap-2">
                    <button
                      onClick={handleSaveEdit}
                      disabled={updateMut.isPending}
                      className="px-3 py-1.5 text-xs font-semibold bg-accent text-accent-fg rounded hover:bg-accent-deep disabled:opacity-50 transition-colors"
                    >
                      {updateMut.isPending ? 'Saving...' : 'Save'}
                    </button>
                    <button
                      onClick={() => { setEditMode(false); setError(null); }}
                      className="px-3 py-1.5 text-xs text-slate-700 border border-hairline rounded hover:bg-surface transition-colors"
                    >
                      Cancel
                    </button>
                  </div>
                </div>
              ) : (
                <pre className="whitespace-pre-wrap text-xs font-mono text-slate-700 bg-surface/50 border border-hairline rounded p-3 max-h-[400px] overflow-y-auto">
                  {detailQuery.data.content}
                </pre>
              )}

              {/* Files (directory skills) */}
              {detailQuery.data.hasDir && detailQuery.data.files.length > 0 && (
                <div>
                  <div className="text-xs font-medium text-slate-600 mb-1">Files</div>
                  <ul className="list-disc list-inside text-xs text-slate-500 font-mono">
                    {detailQuery.data.files.map(f => <li key={f}>{f}</li>)}
                  </ul>
                </div>
              )}

              {/* Action buttons */}
              {canEdit(detailQuery.data) && !editMode && (
                <div className="flex gap-2 mt-1">
                  <button
                    onClick={handleStartEdit}
                    className="px-3 py-1.5 text-xs font-semibold text-accent border border-accent/30 rounded hover:bg-accent-soft transition-colors"
                  >
                    Edit
                  </button>
                  <button
                    onClick={handleDelete}
                    disabled={deleteMut.isPending}
                    className="px-3 py-1.5 text-xs font-semibold text-red-600 border border-red-200 rounded hover:bg-red-50 disabled:opacity-50 transition-colors"
                  >
                    {deleteMut.isPending ? 'Deleting...' : 'Delete'}
                  </button>
                </div>
              )}
            </div>
          ) : selected && detailQuery.isLoading ? (
            <div className="text-xs text-slate-400 py-8 text-center">Loading skill...</div>
          ) : (
            /* ── Empty state ───────────────────────────────────────── */
            <div className="flex flex-col items-center justify-center h-full text-center py-12">
              <div className="text-sm text-slate-400 mb-2">Skills are agent reference guides and knowledge bases.</div>
              <div className="text-xs text-slate-400">Select a skill from the list, or install one from a URL.</div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
