import { useState, useEffect, useCallback, useRef } from 'react';
import { useAppStore } from '@/stores/app';
import { useI18n } from '@/i18n';
import { mcpApi, type McpServerFull, type McpServerPayload, type McpToolDef } from '@/api/endpoints/mcp';
import {
  Plug, Plus, Pencil, Trash2, Check, X, Loader2, ChevronRight,
  Power, PowerOff, Search, Wrench, Terminal, Globe, FileCode2, ChevronDown, ChevronUp,
} from 'lucide-react';

/* ── Msg ── */
function Msg({ type, text }: { type: 's' | 'e' | 'i'; text: string }) {
  const bg = type === 's' ? 'var(--gnl)' : type === 'e' ? 'var(--rdl)' : 'var(--bg2)';
  const fg = type === 's' ? 'var(--gn)' : type === 'e' ? 'var(--rd)' : 'var(--t2)';
  return (
    <div className="flex items-center gap-2 px-3 py-2 rounded-lg text-xs" style={{ background: bg, color: fg }}>
      {type === 's' && <Check size={14} />}
      {type === 'e' && <X size={14} />}
      {type === 'i' && <Loader2 size={14} className="animate-spin" />}
      <span>{text}</span>
    </div>
  );
}

/* ── Type badge ── */
function TypeBadge({ type }: { type: string }) {
  const cfg: Record<string, { icon: React.ReactNode; bg: string; fg: string }> = {
    stdio: { icon: <Terminal size={10} />, bg: 'color-mix(in srgb, var(--ac) 12%, transparent)', fg: 'var(--ac)' },
    sse: { icon: <Globe size={10} />, bg: 'color-mix(in srgb, var(--gn) 12%, transparent)', fg: 'var(--gn)' },
    module: { icon: <FileCode2 size={10} />, bg: 'color-mix(in srgb, #e67e22 12%, transparent)', fg: '#e67e22' },
  };
  const c = cfg[type] || cfg.stdio;
  return (
    <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md text-[.62rem] font-semibold" style={{ background: c.bg, color: c.fg }}>
      {c.icon} {type}
    </span>
  );
}

/* ── Main ── */
export default function McpServersPage() {
  const { adbCfg } = useAppStore();
  const { t } = useI18n();

  const [servers, setServers] = useState<McpServerFull[]>([]);
  const [loading, setLoading] = useState(true);

  // Form
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<McpServerFull | null>(null);
  const [saving, setSaving] = useState(false);
  const [formMsg, setFormMsg] = useState<{ type: 's' | 'e' | 'i'; text: string } | null>(null);
  const formRef = useRef<HTMLDivElement>(null);

  // Form fields
  const [sName, setSName] = useState('');
  const [sDesc, setSDesc] = useState('');
  const [sType, setSType] = useState<'stdio' | 'sse' | 'module'>('stdio');
  const [sCmd, setSCmd] = useState('');
  const [sArgs, setSArgs] = useState('');
  const [sUrl, setSUrl] = useState('');
  const [sAdb, setSAdb] = useState('');

  // Table
  const [tableMsg, setTableMsg] = useState<{ type: 's' | 'e' | 'i'; text: string } | null>(null);
  const [confirmDelete, setConfirmDelete] = useState<string | null>(null);
  const [toggling, setToggling] = useState<Record<string, boolean>>({});
  const [discovering, setDiscovering] = useState<Record<string, boolean>>({});
  const [expandedTools, setExpandedTools] = useState<Record<string, boolean>>({});

  const fetchServers = useCallback(async () => {
    try {
      const data = await mcpApi.list();
      setServers(data);
    } catch {} finally {
      setLoading(false);
    }
  }, []);

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

  const resetForm = () => {
    setEditing(null);
    setFormOpen(false);
    setSName('');
    setSDesc('');
    setSType('stdio');
    setSCmd('');
    setSArgs('');
    setSUrl('');
    setSAdb('');
    setFormMsg(null);
    setSaving(false);
  };

  const startEdit = (srv: McpServerFull) => {
    setEditing(srv);
    setSName(srv.name);
    setSDesc(srv.description || '');
    setSType((srv.server_type || 'stdio') as 'stdio' | 'sse' | 'module');
    setSCmd(srv.command || '');
    setSArgs(srv.args ? JSON.stringify(srv.args) : '');
    setSUrl(srv.url || '');
    setSAdb(srv.linked_adb_id || '');
    setFormOpen(true);
    setFormMsg(null);
    setTimeout(() => formRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }), 100);
  };

  const handleSave = async () => {
    if (!sName.trim()) { setFormMsg({ type: 'e', text: t('mcp.fillName') }); return; }

    let args: string[] | null = null;
    if (sArgs.trim()) {
      try { args = JSON.parse(sArgs); } catch { setFormMsg({ type: 'e', text: t('mcp.invalidArgs') }); return; }
    }

    const body: McpServerPayload = {
      name: sName.trim(),
      description: sDesc.trim() || null,
      server_type: sType,
      command: sType !== 'sse' ? (sCmd.trim() || null) : null,
      url: sType === 'sse' ? (sUrl.trim() || null) : null,
      args,
      linked_adb_id: sAdb || null,
    };

    setSaving(true);
    setFormMsg({ type: 'i', text: editing ? t('mcp.updating') : t('mcp.saving') });

    try {
      if (editing) {
        await mcpApi.update(editing.id, body);
      } else {
        await mcpApi.create(body);
      }
      setFormMsg({ type: 's', text: `Server ${editing ? 'atualizado' : 'registrado'} com sucesso!` });
      await fetchServers();
      useAppStore.getState().loadData();
      setTimeout(resetForm, 1200);
    } catch (err) {
      setFormMsg({ type: 'e', text: err instanceof Error ? err.message : 'Erro ao salvar' });
      setSaving(false);
    }
  };

  const handleDelete = async (id: string) => {
    setConfirmDelete(null);
    setTableMsg({ type: 'i', text: 'Excluindo server...' });
    try {
      await mcpApi.remove(id);
      await fetchServers();
      useAppStore.getState().loadData();
      setTableMsg({ type: 's', text: 'Server excluido com sucesso!' });
      if (editing?.id === id) resetForm();
      setTimeout(() => setTableMsg(null), 3000);
    } catch (err) {
      setTableMsg({ type: 'e', text: err instanceof Error ? err.message : 'Erro ao excluir' });
    }
  };

  const handleToggle = async (id: string) => {
    setToggling((p) => ({ ...p, [id]: true }));
    try {
      await mcpApi.toggle(id);
      await fetchServers();
      useAppStore.getState().loadData();
    } catch (err) {
      setTableMsg({ type: 'e', text: err instanceof Error ? err.message : 'Erro' });
    } finally {
      setToggling((p) => ({ ...p, [id]: false }));
    }
  };

  const handleDiscover = async (id: string) => {
    setDiscovering((p) => ({ ...p, [id]: true }));
    setTableMsg({ type: 'i', text: t('mcp.discovering') });
    try {
      const res = await mcpApi.discoverTools(id);
      await fetchServers();
      useAppStore.getState().loadData();
      setTableMsg({ type: 's', text: `${res.discovered} tool(s) descoberta(s), ${res.total} total` });
      setExpandedTools((p) => ({ ...p, [id]: true }));
      setTimeout(() => setTableMsg(null), 4000);
    } catch (err) {
      setTableMsg({ type: 'e', text: err instanceof Error ? err.message : 'Erro ao descobrir tools' });
    } finally {
      setDiscovering((p) => ({ ...p, [id]: false }));
    }
  };

  const handleRemoveTool = async (srvId: string, idx: number) => {
    const srv = servers.find((s) => s.id === srvId);
    if (!srv?.tools) return;
    const tool = srv.tools[idx];
    const toolName = typeof tool === 'string' ? tool : (tool as McpToolDef).name;
    if (!confirm(`Remover tool "${toolName}"?`)) return;
    const newTools = [...srv.tools];
    newTools.splice(idx, 1);
    try {
      await mcpApi.updateTools(srvId, newTools);
      await fetchServers();
      useAppStore.getState().loadData();
    } catch (err) {
      setTableMsg({ type: 'e', text: err instanceof Error ? err.message : 'Erro' });
    }
  };

  const isFormVisible = formOpen || !!editing;
  const inputCls = "w-full px-3 py-2 rounded-lg text-[.78rem] outline-none transition-colors focus:ring-1";
  const inputStyle = { background: 'var(--bg2)', border: '1.5px solid var(--bd)', color: 'var(--t1)' };
  const labelCls = "block";
  const labelStyle = {};
  const hintCls = "text-[.64rem] mt-0.5";
  const hintStyle = { color: 'var(--t4)' };

  return (
    <div className="page">

        {/* Header */}
        <div className="page-header">
          <div className="icon" style={{ background: 'var(--gnl)' }}>
            <Plug size={24} style={{ color: 'var(--gn)' }} />
          </div>
          <div>
            <h1>{t('mcp.title')}</h1>
            <div className="subtitle">{t('mcp.subtitle')}</div>
          </div>
          <div className="spacer" />
          <span className="count">
            {servers.length} {servers.length === 1 ? 'server' : 'servers'}
          </span>
        </div>

        {/* Server cards */}
        <div className="card">
          <div className="card-header">
            <div className="icon" style={{ background: 'var(--gnl)' }}>
              <Plug size={16} style={{ color: 'var(--gn)' }} />
            </div>
            <h2>{t('mcp.registered')}</h2>
          </div>

          {tableMsg && <div className="px-5 py-2"><Msg type={tableMsg.type} text={tableMsg.text} /></div>}

          {loading ? (
            <div className="flex items-center justify-center py-12">
              <Loader2 size={20} className="animate-spin" style={{ color: 'var(--t4)' }} />
            </div>
          ) : servers.length === 0 ? (
            <div className="py-10 text-center">
              <Plug size={28} style={{ color: 'var(--t4)', margin: '0 auto 8px' }} />
              <p className="text-xs" style={{ color: 'var(--t4)' }}>{t('mcp.noServers')}</p>
            </div>
          ) : (
            <div className="flex flex-col">
              {servers.map((srv) => {
                const tools: McpToolDef[] = Array.isArray(srv.tools) ? srv.tools : [];
                const isExpanded = expandedTools[srv.id];
                const adb = srv.linked_adb_id ? adbCfg.find((a) => a.id === srv.linked_adb_id) : null;
                return (
                  <div
                    key={srv.id}
                    className="px-5 py-4 transition-colors"
                    style={{
                      borderBottom: '1px solid var(--bd)',
                      background: editing?.id === srv.id ? 'color-mix(in srgb, var(--gn) 5%, var(--bg1))' : undefined,
                    }}
                  >
                    {/* Header row */}
                    <div className="flex items-center justify-between mb-2">
                      <div className="flex items-center gap-2.5">
                        <strong className="text-[.88rem]" style={{ color: 'var(--t1)' }}>{srv.name}</strong>
                        <TypeBadge type={srv.server_type} />
                        <span
                          className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md text-[.6rem] font-semibold"
                          style={{
                            background: srv.is_active ? 'var(--gnl)' : 'var(--rdl)',
                            color: srv.is_active ? 'var(--gn)' : 'var(--rd)',
                          }}
                        >
                          {srv.is_active ? <Power size={8} /> : <PowerOff size={8} />}
                          {srv.is_active ? t('mcp.active') : t('mcp.inactive')}
                        </span>
                      </div>
                      <div className="flex gap-1.5">
                        <button onClick={() => startEdit(srv)} className="btn btn-secondary btn-sm">
                          <Pencil size={10} /> {t('mcp.edit')}
                        </button>
                        <button
                          onClick={() => handleToggle(srv.id)}
                          disabled={toggling[srv.id]}
                          className="btn btn-secondary btn-sm"
                        >
                          {toggling[srv.id] ? <Loader2 size={10} className="animate-spin" /> : srv.is_active ? <PowerOff size={10} /> : <Power size={10} />}
                          {srv.is_active ? t('mcp.deactivate') : t('mcp.activate')}
                        </button>
                        {confirmDelete === srv.id ? (
                          <div className="flex gap-1">
                            <button onClick={() => handleDelete(srv.id)} className="btn btn-sm" style={{ background: 'var(--rd)', color: '#fff' }}>
                              <Check size={10} /> {t('common.yes')}
                            </button>
                            <button onClick={() => setConfirmDelete(null)} className="btn btn-secondary btn-sm">
                              {t('common.no')}
                            </button>
                          </div>
                        ) : (
                          <button onClick={() => setConfirmDelete(srv.id)} className="btn btn-danger btn-sm">
                            <Trash2 size={10} /> {t('mcp.delete')}
                          </button>
                        )}
                      </div>
                    </div>

                    {/* Description */}
                    {srv.description && (
                      <div className="text-[.72rem] mb-2" style={{ color: 'var(--t3)' }}>{srv.description}</div>
                    )}

                    {/* Details row */}
                    <div className="flex gap-4 flex-wrap text-[.72rem] mb-2" style={{ color: 'var(--t4)' }}>
                      {srv.command && (
                        <div>
                          <span className="font-semibold" style={{ color: 'var(--t3)' }}>{t('mcp.command')}</span>{' '}
                          <code className="text-[.66rem]" style={{ fontFamily: 'var(--fm)' }}>{srv.command}</code>
                        </div>
                      )}
                      {srv.url && (
                        <div>
                          <span className="font-semibold" style={{ color: 'var(--t3)' }}>{t('mcp.url')}</span>{' '}
                          <code className="text-[.66rem]" style={{ fontFamily: 'var(--fm)' }}>{srv.url}</code>
                        </div>
                      )}
                      {srv.module_path && (
                        <div>
                          <span className="font-semibold" style={{ color: 'var(--t3)' }}>{t('mcp.module')}</span>{' '}
                          <code className="text-[.66rem]" style={{ fontFamily: 'var(--fm)' }}>{srv.module_path}</code>
                        </div>
                      )}
                      <div>
                        <span className="font-semibold" style={{ color: 'var(--t3)' }}>{t('mcp.adb')}</span>{' '}
                        {adb ? (
                          <span className="px-1.5 py-0.5 rounded text-[.6rem] font-semibold" style={{ background: 'var(--gnl)', color: 'var(--gn)' }}>{adb.config_name}</span>
                        ) : t('mcp.noAdb')}
                      </div>
                    </div>

                    {/* Tools section */}
                    <div className="mt-2" style={{ borderTop: '1px solid var(--bd)', paddingTop: 8 }}>
                      <div
                        className="flex items-center gap-2 cursor-pointer select-none mb-1"
                        onClick={() => setExpandedTools((p) => ({ ...p, [srv.id]: !p[srv.id] }))}
                      >
                        <Wrench size={12} style={{ color: 'var(--t2)' }} />
                        <span className="text-[.74rem] font-semibold" style={{ color: 'var(--t2)' }}>
                          {t('mcp.tools')} ({tools.length})
                        </span>
                        {isExpanded ? <ChevronUp size={12} style={{ color: 'var(--t4)' }} /> : <ChevronDown size={12} style={{ color: 'var(--t4)' }} />}
                      </div>

                      {isExpanded && tools.length > 0 && (
                        <div className="flex flex-col gap-1 mt-1">
                          {tools.map((tool, i) => (
                            <div key={i} className="flex items-start gap-2 px-3 py-1.5 rounded-md text-[.72rem]" style={{ background: 'var(--bg)', border: '1px solid var(--bd)' }}>
                              <div className="flex-1 min-w-0">
                                <strong style={{ color: 'var(--t1)' }}>{typeof tool === 'string' ? tool : tool.name}</strong>
                                {typeof tool === 'object' && tool.description && (
                                  <span style={{ color: 'var(--t4)' }}> — {tool.description}</span>
                                )}
                                {typeof tool === 'object' && tool.input_schema && (tool.input_schema as { properties?: Record<string, unknown> }).properties && (
                                  <div className="text-[.64rem] mt-0.5" style={{ color: 'var(--t4)' }}>
                                    Params: {Object.keys((tool.input_schema as { properties: Record<string, unknown> }).properties).join(', ')}
                                  </div>
                                )}
                              </div>
                              <button
                                onClick={() => handleRemoveTool(srv.id, i)}
                                className="flex-shrink-0 px-1.5 py-0.5 rounded text-[.6rem] font-semibold transition-colors"
                                style={{ color: 'var(--rd)', background: 'color-mix(in srgb, var(--rd) 8%, transparent)' }}
                              >
                                <X size={10} />
                              </button>
                            </div>
                          ))}
                        </div>
                      )}
                      {isExpanded && tools.length === 0 && (
                        <div className="text-[.72rem] py-1" style={{ color: 'var(--t4)' }}>{t('mcp.noTools')}</div>
                      )}
                    </div>

                    {/* Action buttons */}
                    <div className="flex gap-2 mt-3 flex-wrap">
                      <button
                        onClick={() => handleDiscover(srv.id)}
                        disabled={discovering[srv.id]}
                        className="btn btn-success btn-sm"
                      >
                        {discovering[srv.id] ? <Loader2 size={12} className="animate-spin" /> : <Search size={12} />}
                        {t('mcp.discoverTools')}
                      </button>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>

        {/* Form */}
        <div ref={formRef} className="card" style={{ overflow: 'hidden' }}>
          <div className="flex items-center gap-2.5 px-5 py-3.5 cursor-pointer select-none" onClick={() => { if (!editing) setFormOpen(!formOpen); }}>
            <ChevronRight size={14} style={{ color: 'var(--t3)', transition: 'transform .2s', transform: isFormVisible ? 'rotate(90deg)' : 'rotate(0)' }} />
            <div className="flex items-center gap-2">
              {editing ? <Pencil size={14} style={{ color: 'var(--gn)' }} /> : <Plus size={14} style={{ color: 'var(--gn)' }} />}
              <span className="text-[.76rem] font-semibold" style={{ color: 'var(--t2)' }}>
                {editing ? `${t('mcp.editServer')} — ${editing.name}` : t('mcp.newServer')}
              </span>
            </div>
          </div>

          {isFormVisible && (
            <div className="px-5 pb-5 flex flex-col gap-4" style={{ borderTop: '1px solid var(--bd)' }}>
              <p className="text-[.7rem] pt-3" style={{ color: 'var(--t4)' }}>
                {editing
                  ? <>Editando: <strong style={{ color: 'var(--t2)' }}>{editing.name}</strong></>
                  : t('mcp.configDesc')}
              </p>

              {formMsg && <Msg type={formMsg.type} text={formMsg.text} />}

              {/* Name + description */}
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                  <label className={labelCls} style={labelStyle}>{t('mcp.name')}</label>
                  <input type="text" value={sName} onChange={(e) => setSName(e.target.value)} placeholder="CIS Benchmark Server" className={inputCls} style={inputStyle} />
                </div>
                <div>
                  <label className={labelCls} style={labelStyle}>{t('mcp.description')}</label>
                  <input type="text" value={sDesc} onChange={(e) => setSDesc(e.target.value)} placeholder="Executa checks CIS 3.0" className={inputCls} style={inputStyle} />
                </div>
              </div>

              {/* Server type */}
              <div>
                <label className={labelCls} style={labelStyle}>{t('mcp.serverType')}</label>
                <div className="flex gap-2 mt-1">
                  {(['stdio', 'sse', 'module'] as const).map((tp) => {
                    const icons = { stdio: <Terminal size={12} />, sse: <Globe size={12} />, module: <FileCode2 size={12} /> };
                    const labels = { stdio: 'stdio', sse: 'SSE (HTTP)', module: 'Python Module' };
                    const selected = sType === tp;
                    return (
                      <button
                        key={tp}
                        type="button"
                        onClick={() => setSType(tp)}
                        className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[.72rem] font-semibold transition-all"
                        style={{
                          background: selected ? 'color-mix(in srgb, var(--gn) 15%, transparent)' : 'var(--bg2)',
                          color: selected ? 'var(--gn)' : 'var(--t4)',
                          border: `1.5px solid ${selected ? 'var(--gn)' : 'var(--bd)'}`,
                        }}
                      >
                        {icons[tp]} {labels[tp]}
                      </button>
                    );
                  })}
                </div>
              </div>

              {/* Conditional fields */}
              {sType !== 'sse' && (
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <div>
                    <label className={labelCls} style={labelStyle}>{t('mcp.commandLabel')}</label>
                    <p className={hintCls} style={{ ...hintStyle, marginBottom: 4 }}>{t('mcp.commandHint')}</p>
                    <input type="text" value={sCmd} onChange={(e) => setSCmd(e.target.value)} placeholder="python3 server.py" className={inputCls} style={inputStyle} />
                  </div>
                  <div>
                    <label className={labelCls} style={labelStyle}>{t('mcp.argsLabel')}</label>
                    <p className={hintCls} style={{ ...hintStyle, marginBottom: 4 }}>{t('mcp.argsHint')}</p>
                    <input type="text" value={sArgs} onChange={(e) => setSArgs(e.target.value)} placeholder='["--config", "/path/to/config"]' className={inputCls} style={{ ...inputStyle, fontFamily: 'var(--fm)', fontSize: '.72rem' }} />
                  </div>
                </div>
              )}
              {sType === 'sse' && (
                <div>
                  <label className={labelCls} style={labelStyle}>{t('mcp.urlLabel')}</label>
                  <p className={hintCls} style={{ ...hintStyle, marginBottom: 4 }}>{t('mcp.urlHint')}</p>
                  <input type="text" value={sUrl} onChange={(e) => setSUrl(e.target.value)} placeholder="http://localhost:8001/sse" className={inputCls} style={inputStyle} />
                </div>
              )}

              {/* ADB link */}
              <div>
                <label className={labelCls} style={labelStyle}>{t('mcp.linkAdb')}</label>
                <p className={hintCls} style={{ ...hintStyle, marginBottom: 4 }}>{t('mcp.linkAdbHint')}</p>
                <select value={sAdb} onChange={(e) => setSAdb(e.target.value)} className={inputCls} style={inputStyle}>
                  <option value="">{t('mcp.noAdb')}</option>
                  {adbCfg.map((a) => (
                    <option key={a.id} value={a.id}>{a.config_name}</option>
                  ))}
                </select>
              </div>

              {/* Buttons */}
              <div className="flex gap-2 pt-1">
                <button onClick={handleSave} disabled={saving} className="btn btn-success">
                  {saving && <Loader2 size={14} className="animate-spin" />}
                  {editing ? t('mcp.saveChanges') : t('mcp.saveServer')}
                </button>
                {editing && (
                  <button onClick={resetForm} className="btn btn-secondary">
                    {t('mcp.cancel')}
                  </button>
                )}
              </div>
            </div>
          )}
        </div>

    </div>
  );
}
