"use client";

import Link from "next/link";
import { useState, type FormEvent } from "react";
import { Trash2, X } from "lucide-react";
import { Badge, Button, Skeleton, Textarea } from "@/components/ui/kit";
import { ConsentBadge } from "@/components/contacts/consent-badge";
import { useToast } from "@/components/ui/toast";
import { useSession } from "@/components/session";
import { api } from "@/lib/api";
import { flag, formatDateTime, formatPhone } from "@/lib/format";
import { useApi } from "@/lib/use-api";
import type { ConversationDetail, CustomField, Note } from "@/lib/types";

export function ContactPanel({ conversation, onClose, onChanged }: { conversation: ConversationDetail; onClose: () => void; onChanged: () => void }) {
  const { me, can } = useSession();
  const toast = useToast();
  const [version, setVersion] = useState(0);
  const notes = useApi<{ data: Note[] }>(`/inbox/conversations/${conversation.id}/notes?v=${version}`);
  const fields = useApi<{ data: CustomField[] }>("/custom-fields");
  const [draft, setDraft] = useState("");
  const [saving, setSaving] = useState(false);
  // Optimistic value while the request is in flight; otherwise the conversation is the source of truth.
  // It applies until the refreshed conversation shows a different value from when the request started.
  const [pending, setPending] = useState<{ value: boolean; base: boolean; busy: boolean } | null>(null);
  const paused = pending && pending.base === conversation.automation_paused ? pending.value : conversation.automation_paused;
  const c = conversation.contact_details;

  const [stopping, setStopping] = useState(false);
  async function stopFlow() {
    setStopping(true);
    try {
      await api.post(`/inbox/conversations/${conversation.id}/flow/stop`);
      toast("success", "Flow stopped for this chat");
      onChanged();
    } catch (err) {
      toast("error", (err as Error).message);
    } finally {
      setStopping(false);
    }
  }

  async function setAutomation(paused: boolean) {
    setPending({ value: paused, base: conversation.automation_paused, busy: true });
    try {
      await api.post(`/inbox/conversations/${conversation.id}/automation`, { paused });
      toast("success", paused ? "Automated replies paused for this chat" : "Automated replies back on");
      setPending((p) => p && { ...p, busy: false });
      onChanged();
    } catch (err) {
      setPending(null);
      toast("error", (err as Error).message);
    }
  }

  async function addNote(e: FormEvent) {
    e.preventDefault();
    if (!draft.trim()) return;
    setSaving(true);
    try {
      await api.post(`/inbox/conversations/${conversation.id}/notes`, { body: draft.trim() });
      setDraft("");
      setVersion((v) => v + 1);
    } catch (err) {
      toast("error", (err as Error).message);
    } finally {
      setSaving(false);
    }
  }

  async function removeNote(id: number) {
    try {
      await api.delete(`/inbox/notes/${id}`);
      setVersion((v) => v + 1);
    } catch (err) {
      toast("error", (err as Error).message);
    }
  }

  return (
    <aside className="flex h-full min-h-0 flex-col border-l border-line bg-white" aria-label="Contact details">
      <header className="flex items-center justify-between border-b border-line px-4 py-3">
        <h2 className="font-semibold">Contact</h2>
        <button onClick={onClose} aria-label="Close contact details" className="rounded p-1 text-muted hover:bg-paper xl:hidden">
          <X className="size-5" />
        </button>
      </header>
      <div className="min-h-0 flex-1 space-y-6 overflow-y-auto p-4 text-sm">
        <section>
          <div className="text-base font-semibold text-ink">{c.full_name}</div>
          <div className="tabular text-muted">{formatPhone(c.phone)}</div>
          <dl className="mt-3 grid grid-cols-[90px_1fr] gap-x-3 gap-y-1.5">
            <dt className="text-muted">Email</dt>
            <dd className="break-all">{c.email ?? "—"}</dd>
            <dt className="text-muted">Country</dt>
            <dd>{c.country ? `${flag(c.country)} ${c.country_name}` : "—"}</dd>
            <dt className="text-muted">Language</dt>
            <dd>{c.language_code ?? "—"}</dd>
            <dt className="text-muted">Marketing</dt>
            <dd>
              <ConsentBadge status={c.opt_in_status} />
            </dd>
          </dl>
          {can("contacts.view") && (
            <Link href={`/contacts?q=${c.phone}`} className="mt-2 inline-block text-[13px] font-medium text-teal hover:underline">
              Open in Contacts
            </Link>
          )}
        </section>

        <section>
          <h3 className="mb-1.5 font-semibold">Automated replies</h3>
          <label className="flex items-start gap-3">
            <input
              type="checkbox"
              role="switch"
              className="mt-0.5 size-4 accent-teal"
              checked={!paused}
              disabled={Boolean(pending?.busy) || !can("inbox.reply")}
              onChange={(e) => setAutomation(!e.target.checked)}
            />
            <span className="text-[13px] text-muted">
              {paused ? "Paused. Bot replies and flows stay quiet so your team can handle this chat." : "On. Bot replies and flows answer matching messages in this chat."}
            </span>
          </label>
          {conversation.active_run && (
            <div className="mt-3 rounded-lg bg-teal-soft/60 p-3 text-[13px]">
              <p>
                In flow{" "}
                <Link href={`/bot-flows/${conversation.active_run.flow_id}`} className="font-semibold text-teal hover:underline">
                  {conversation.active_run.flow_title ?? "Flow"}
                </Link>
                {conversation.active_run.waiting_for === "reply" ? ", waiting for their reply" : conversation.active_run.waiting_for === "delay" ? ", waiting before the next step" : ""}
              </p>
              {can("inbox.reply") && (
                <button onClick={stopFlow} disabled={stopping} className="mt-1.5 font-medium text-brick hover:underline disabled:opacity-50">
                  Stop flow
                </button>
              )}
            </div>
          )}
        </section>

        {(c.groups.length > 0 || c.tags.length > 0) && (
          <section>
            <h3 className="mb-2 font-semibold">Groups and tags</h3>
            <div className="flex flex-wrap gap-1.5">
              {c.groups.map((g) => (
                <Badge key={`g${g.id}`} tone="teal">
                  {g.name}
                </Badge>
              ))}
              {c.tags.map((t) => (
                <Badge key={`t${t.id}`}>#{t.name}</Badge>
              ))}
            </div>
          </section>
        )}

        {(fields.data?.data.length ?? 0) > 0 && (
          <section>
            <h3 className="mb-2 font-semibold">Other information</h3>
            <dl className="grid grid-cols-[90px_1fr] gap-x-3 gap-y-1.5">
              {fields.data!.data.map((f) => (
                <div key={f.id} className="contents">
                  <dt className="text-muted">{f.label}</dt>
                  <dd className="break-words">{c.custom_fields[f.key] ?? "—"}</dd>
                </div>
              ))}
            </dl>
          </section>
        )}

        <section>
          <h3 className="mb-1 font-semibold">Internal notes</h3>
          <p className="mb-2 text-[13px] text-muted">Only your team sees these. They are never sent on WhatsApp.</p>
          <form onSubmit={addNote} className="space-y-2">
            <Textarea aria-label="New note" rows={2} value={draft} onChange={(e) => setDraft(e.target.value)} placeholder="Add a note for your team" maxLength={2000} />
            <Button size="sm" type="submit" loading={saving} disabled={!draft.trim()}>
              Add note
            </Button>
          </form>
          <ul className="mt-3 space-y-2">
            {!notes.data && <Skeleton className="h-12 w-full" />}
            {notes.data?.data.map((n) => (
              <li key={n.id} className="group rounded-lg bg-amber-soft/60 px-3 py-2">
                <p className="whitespace-pre-wrap break-words">{n.body}</p>
                <div className="mt-1 flex items-center justify-between text-[11.5px] text-muted">
                  <span>
                    {n.user_name ?? "Former member"}, {formatDateTime(n.created_at)}
                  </span>
                  {(n.user_id === me?.user.id || can("inbox.assign_any")) && (
                    <button onClick={() => removeNote(n.id)} aria-label="Delete note" className="rounded p-0.5 text-muted opacity-60 hover:text-brick group-hover:opacity-100">
                      <Trash2 className="size-3.5" />
                    </button>
                  )}
                </div>
              </li>
            ))}
          </ul>
        </section>
      </div>
    </aside>
  );
}
