"use client";

import { useEffect, useState } from "react";
import { Button } from "@/components/ui";
import { Loader2, Save, MessageCircle, Send, Hash, Mail, Slack, CheckCircle, AlertCircle, ChevronDown, Plug } from "lucide-react";
import { KnowledgeBank } from "@/components/dashboard/knowledge-bank";

type ChannelType = "telegram" | "discord" | "whatsapp_cloud" | "slack" | "email";
type Field = { key: string; label: string; required: boolean; secret?: boolean };
type ChannelState = { type: string; enabled: boolean; status: string; last_error?: string | null; config: Record<string, string> };

const META: Record<ChannelType, { label: string; icon: React.ComponentType<{ size?: number }> }> = {
  telegram: { label: "Telegram", icon: Send },
  whatsapp_cloud: { label: "WhatsApp", icon: MessageCircle },
  email: { label: "Email", icon: Mail },
  discord: { label: "Discord", icon: Hash },
  slack: { label: "Slack", icon: Slack },
};
const ORDER: ChannelType[] = ["telegram", "whatsapp_cloud", "email", "discord", "slack"];

export function AgentConfigPanel({ instanceId, initialNotes, roleId }: { instanceId: number; initialNotes: string | null; roleId?: number | null }) {
  const [open, setOpen] = useState(false);
  const [notes, setNotes] = useState(initialNotes || "");
  const [savingNotes, setSavingNotes] = useState(false);
  const [notesMsg, setNotesMsg] = useState("");

  const [fields, setFields] = useState<Record<string, Field[]>>({});
  const [channels, setChannels] = useState<Record<string, ChannelState>>({});
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (!open) return;
    fetch(`/api/instances/${instanceId}/channels`)
      .then((r) => r.json())
      .then((b) => {
        setFields(b.fields || {});
        const map: Record<string, ChannelState> = {};
        for (const c of b.channels || []) map[c.type] = c;
        setChannels(map);
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, [open, instanceId]);

  async function saveNotes() {
    setSavingNotes(true);
    setNotesMsg("");
    const res = await fetch(`/api/instances/${instanceId}/config`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ notes }),
    });
    const b = await res.json().catch(() => ({}));
    setSavingNotes(false);
    setNotesMsg(res.ok ? b.warning || "Saved and applied to your agent." : b.error || "Save failed.");
  }

  return (
    <div className="mt-3 border-t border-slate-100 pt-3">
      <button onClick={() => setOpen((o) => !o)} className="flex items-center gap-1 text-sm font-semibold text-brand">
        <ChevronDown size={16} className={open ? "rotate-180 transition" : "transition"} /> Notes & channels
      </button>

      {open && (
        <div className="mt-3 grid gap-5">
          {/* Notes */}
          <div>
            <p className="mb-1 text-xs font-semibold uppercase tracking-wide text-slate-400">Notes for the agent</p>
            <textarea
              value={notes}
              onChange={(e) => setNotes(e.target.value)}
              rows={3}
              className="w-full rounded-md border border-slate-300 bg-white px-3 py-2 text-sm text-ink focus:border-brand focus:outline-none"
              placeholder="Add or change instructions for your agent…"
            />
            <div className="mt-2 flex items-center gap-3">
              <Button onClick={saveNotes} disabled={savingNotes}>
                {savingNotes ? <Loader2 size={14} className="animate-spin" /> : <Save size={14} />}
                {savingNotes ? "Applying…" : "Save & apply"}
              </Button>
              {notesMsg && <span className="text-xs text-slate-500">{notesMsg}</span>}
            </div>
          </div>

          {/* Job knowledge bank */}
          {roleId ? (
            <div>
              <p className="mb-1 text-xs font-semibold uppercase tracking-wide text-slate-400">بنك المعلومات الوظيفي</p>
              <KnowledgeBank roleId={roleId} />
            </div>
          ) : null}

          {/* Channels */}
          <div>
            <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-slate-400">Channels</p>
            {loading ? (
              <div className="flex items-center gap-2 text-sm text-slate-500">
                <Loader2 size={16} className="animate-spin" /> Loading…
              </div>
            ) : (
              <div className="grid gap-2">
                {ORDER.map((type) => (
                  <ChannelRow
                    key={type}
                    type={type}
                    instanceId={instanceId}
                    fields={fields[type] || []}
                    state={channels[type]}
                    onSaved={(s) => setChannels((c) => ({ ...c, [type]: s }))}
                    onRemoved={() => setChannels((c) => { const n = { ...c }; delete n[type]; return n; })}
                  />
                ))}
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

function ChannelRow({
  type,
  instanceId,
  fields,
  state,
  onSaved,
  onRemoved,
}: {
  type: ChannelType;
  instanceId: number;
  fields: Field[];
  state?: ChannelState;
  onSaved: (s: ChannelState) => void;
  onRemoved: () => void;
}) {
  const meta = META[type];
  const Icon = meta.icon;
  const [expanded, setExpanded] = useState(false);
  const [values, setValues] = useState<Record<string, string>>({});
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [msg, setMsg] = useState("");

  const connected = state?.status === "CONNECTED";
  const configured = Boolean(state);

  async function test() {
    setTesting(true);
    setMsg("");
    const res = await fetch(`/api/instances/${instanceId}/channels/test?type=${type}`, { method: "POST" });
    const b = await res.json().catch(() => ({}));
    setTesting(false);
    setMsg(b.message || (res.ok ? "OK" : "Test failed."));
    if (state) onSaved({ ...state, status: res.ok ? "CONNECTED" : "ERROR" });
  }

  async function save() {
    setSaving(true);
    setMsg("");
    const res = await fetch(`/api/instances/${instanceId}/channels`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ type, config: values }),
    });
    const b = await res.json().catch(() => ({}));
    setSaving(false);
    if (!res.ok) {
      setMsg(b.error || "Failed.");
      return;
    }
    setMsg(b.warning || "Connected.");
    onSaved({ type, enabled: true, status: b.warning ? "ERROR" : "CONNECTED", config: {} });
    setValues({});
  }

  async function remove() {
    await fetch(`/api/instances/${instanceId}/channels?type=${type}`, { method: "DELETE" });
    onRemoved();
    setExpanded(false);
  }

  return (
    <div className="rounded-lg border border-slate-200">
      <button onClick={() => setExpanded((e) => !e)} className="flex w-full items-center justify-between px-3 py-2">
        <span className="flex items-center gap-2 text-sm font-medium text-ink">
          <Icon size={16} /> {meta.label}
        </span>
        <span className="flex items-center gap-2">
          {connected ? (
            <span className="flex items-center gap-1 text-xs text-emerald-600">
              <CheckCircle size={13} /> Connected
            </span>
          ) : configured ? (
            <span className="flex items-center gap-1 text-xs text-amber-600">
              <AlertCircle size={13} /> {state?.status === "ERROR" ? "Error" : "Configured"}
            </span>
          ) : (
            <span className="text-xs text-slate-400">Not connected</span>
          )}
          <ChevronDown size={15} className={expanded ? "rotate-180 transition text-slate-400" : "transition text-slate-400"} />
        </span>
      </button>

      {expanded && (
        <div className="grid gap-2 border-t border-slate-100 px-3 py-3">
          {fields.map((f) => (
            <div key={f.key}>
              <label className="text-xs text-slate-500">
                {f.label} {f.required && <span className="text-red-400">*</span>}
              </label>
              <input
                type={f.secret ? "password" : "text"}
                value={values[f.key] || ""}
                onChange={(e) => setValues((v) => ({ ...v, [f.key]: e.target.value }))}
                placeholder={configured && f.secret ? "•••••• (leave blank to keep)" : ""}
                className="mt-0.5 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 text-sm focus:border-brand focus:outline-none"
              />
            </div>
          ))}
          {state?.last_error && <p className="text-xs text-red-600">{state.last_error}</p>}
          <div className="flex items-center gap-3">
            <Button onClick={save} disabled={saving}>
              {saving ? <Loader2 size={14} className="animate-spin" /> : <Save size={14} />}
              {saving ? "Connecting…" : "Connect"}
            </Button>
            {configured && (
              <button
                onClick={test}
                disabled={testing}
                className="inline-flex items-center gap-1 rounded-md border border-slate-300 px-2.5 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-50 disabled:opacity-50"
              >
                {testing ? <Loader2 size={13} className="animate-spin" /> : <Plug size={13} />}
                {testing ? "Testing…" : "Test connection"}
              </button>
            )}
            {configured && (
              <button onClick={remove} className="text-xs text-red-600 hover:underline">
                Disconnect
              </button>
            )}
            {msg && <span className="text-xs text-slate-500">{msg}</span>}
          </div>
        </div>
      )}
    </div>
  );
}
