import { Plus, Save, Trash2, Wifi } from 'lucide-react';
import { useEffect, useState } from 'react';
import { api, errorMessage } from '../api.js';

export function Nodes({ nodes, onChanged }) {
  const [drafts, setDrafts] = useState(() => nodes);
  const [newNode, setNewNode] = useState({ name: '', baseUrl: '', token: '', enabled: true });
  const [message, setMessage] = useState('');
  const [error, setError] = useState('');

  async function createNode(event) {
    event.preventDefault();
    setError('');
    setMessage('');
    try {
      await api.post('/nodes', newNode);
      setNewNode({ name: '', baseUrl: '', token: '', enabled: true });
      setMessage('Node added.');
      await onChanged();
    } catch (requestError) {
      setError(errorMessage(requestError));
    }
  }

  async function saveNode(node) {
    setError('');
    setMessage('');
    try {
      const body = { ...node };
      if (!body.token) delete body.token;
      await api.put(`/nodes/${encodeURIComponent(node.id)}`, body);
      setMessage('Node saved.');
      await onChanged();
    } catch (requestError) {
      setError(errorMessage(requestError));
    }
  }

  async function testNode(node) {
    setError('');
    setMessage('');
    try {
      await api.post(`/nodes/${encodeURIComponent(node.id)}/test`);
      setMessage('Node connection ok.');
      await onChanged();
    } catch (requestError) {
      setError(errorMessage(requestError));
    }
  }

  async function deleteNode(node) {
    setError('');
    setMessage('');
    try {
      await api.delete(`/nodes/${encodeURIComponent(node.id)}`);
      setMessage('Node deleted.');
      await onChanged();
    } catch (requestError) {
      setError(errorMessage(requestError));
    }
  }

  function updateDraft(id, values) {
    setDrafts((current) => current.map((node) => node.id === id ? { ...node, ...values } : node));
  }

  useEffect(() => {
    setDrafts(nodes);
  }, [nodes]);

  return (
    <section className="space-y-5">
      <div className="border-b border-zinc-800 pb-5">
        <h1 className="text-2xl font-semibold text-zinc-100">Nodes</h1>
        <p className="mt-2 max-w-3xl text-sm leading-6 text-zinc-500">Register Incus backend agents by URL and token.</p>
      </div>

      {error ? <Notice tone="bad" text={error} /> : null}
      {message ? <Notice tone="good" text={message} /> : null}

      <form className="rounded-md border border-zinc-800 bg-zinc-900/70" onSubmit={createNode}>
        <div className="grid gap-4 p-4 lg:grid-cols-[1fr_1.5fr_1.5fr_auto]">
          <Input label="Name" onChange={(value) => setNewNode((current) => ({ ...current, name: value }))} value={newNode.name} />
          <Input label="Base URL" onChange={(value) => setNewNode((current) => ({ ...current, baseUrl: value }))} placeholder="http://node:3000" value={newNode.baseUrl} />
          <Input label="Token" onChange={(value) => setNewNode((current) => ({ ...current, token: value }))} type="password" value={newNode.token} />
          <button className="mt-6 inline-flex h-10 items-center gap-2 rounded-md border border-cyan-800 bg-cyan-950 px-3 text-sm text-cyan-100" type="submit">
            <Plus className="h-4 w-4" />
            Add
          </button>
        </div>
      </form>

      <div className="overflow-hidden rounded-md border border-zinc-800 bg-zinc-900/70">
        <div className="overflow-x-auto">
          <table className="w-full min-w-[900px] text-left text-sm">
            <thead className="border-b border-zinc-800 text-xs uppercase text-zinc-500">
              <tr>
                <th className="px-4 py-3 font-medium">Enabled</th>
                <th className="px-4 py-3 font-medium">Name</th>
                <th className="px-4 py-3 font-medium">URL</th>
                <th className="px-4 py-3 font-medium">New Token</th>
                <th className="px-4 py-3 font-medium">Status</th>
                <th className="px-4 py-3 text-right font-medium">Actions</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-zinc-800">
              {drafts.map((node) => (
                <tr key={node.id}>
                  <td className="px-4 py-3">
                    <input checked={node.enabled} className="h-4 w-4 accent-cyan-500" onChange={(event) => updateDraft(node.id, { enabled: event.target.checked })} type="checkbox" />
                  </td>
                  <td className="px-4 py-3"><input className="h-9 w-full rounded-md border border-zinc-700 bg-zinc-950 px-2 text-zinc-100" onChange={(event) => updateDraft(node.id, { name: event.target.value })} value={node.name} /></td>
                  <td className="px-4 py-3"><input className="h-9 w-full rounded-md border border-zinc-700 bg-zinc-950 px-2 text-zinc-100" onChange={(event) => updateDraft(node.id, { baseUrl: event.target.value })} value={node.baseUrl} /></td>
                  <td className="px-4 py-3"><input className="h-9 w-full rounded-md border border-zinc-700 bg-zinc-950 px-2 text-zinc-100" onChange={(event) => updateDraft(node.id, { token: event.target.value })} type="password" value={node.token || ''} /></td>
                  <td className="px-4 py-3 text-zinc-300">{node.lastHealthStatus || 'unknown'}</td>
                  <td className="px-4 py-3 text-right">
                    <div className="inline-flex items-center gap-2">
                      <button className="inline-flex h-8 items-center gap-1 rounded-md border border-zinc-700 px-2.5 text-xs text-zinc-100" onClick={() => testNode(node)} type="button"><Wifi className="h-4 w-4" /> Test</button>
                      <button className="inline-flex h-8 items-center gap-1 rounded-md border border-cyan-800 px-2.5 text-xs text-cyan-100" onClick={() => saveNode(node)} type="button"><Save className="h-4 w-4" /> Save</button>
                      <button className="inline-flex h-8 items-center gap-1 rounded-md border border-red-900 px-2.5 text-xs text-red-300" onClick={() => deleteNode(node)} type="button"><Trash2 className="h-4 w-4" /> Delete</button>
                    </div>
                  </td>
                </tr>
              ))}
              {!drafts.length ? <tr><td className="px-4 py-8 text-center text-zinc-500" colSpan="6">No nodes configured.</td></tr> : null}
            </tbody>
          </table>
        </div>
      </div>
    </section>
  );
}

function Input({ label, onChange, placeholder = '', type = 'text', value }) {
  return (
    <label className="block text-sm text-zinc-300">
      {label}
      <input className="mt-2 h-10 w-full rounded-md border border-zinc-700 bg-zinc-950 px-3 text-zinc-100" onChange={(event) => onChange(event.target.value)} placeholder={placeholder} type={type} value={value} />
    </label>
  );
}

function Notice({ text, tone }) {
  const classes = {
    bad: 'border-red-900 bg-red-950/50 text-red-200',
    good: 'border-emerald-900 bg-emerald-950/50 text-emerald-200',
  };
  return <div className={`rounded-md border px-4 py-3 text-sm ${classes[tone]}`}>{text}</div>;
}
