"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Send, Paperclip, X, Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Textarea, Select } from "@/components/ui/input";
import { initials, timeAgo, cn } from "@/lib/utils";

type Any = any;

export function InboxClient({
  initialConversations,
  members,
  whatsappConfigured,
}: {
  initialConversations: Any[];
  members: Any[];
  whatsappConfigured: boolean;
}) {
  const router = useRouter();
  const [conversations, setConversations] = useState(initialConversations);
  const [selected, setSelected] = useState<string | null>(initialConversations[0]?.id ?? null);
  const [messages, setMessages] = useState<Any[]>([]);
  const [contactInfo, setContactInfo] = useState<Any | null>(null);
  const [text, setText] = useState("");
  const [sending, setSending] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [zoomedImage, setZoomedImage] = useState<string | null>(null);
  const [attachment, setAttachment] = useState<{ url: string; type: "image" | "video" | "document" | "audio"; name: string } | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const bottomRef = useRef<HTMLDivElement>(null);

  const loadConversation = useCallback(async (id: string) => {
    const res = await fetch(`/api/inbox/${id}`);
    const json = await res.json().catch(() => ({}));
    if (res.ok) {
      setMessages(json.conversation?.messages ?? []);
      setContactInfo(json.conversation?.contact ?? null);
    }
  }, []);

  useEffect(() => {
    if (selected) loadConversation(selected);
  }, [selected, loadConversation]);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages.length]);

  useEffect(() => {
    const t = setInterval(async () => {
      const res = await fetch("/api/inbox");
      if (res.ok) setConversations((await res.json()).conversations);
      if (selected) loadConversation(selected);
    }, 8000);
    return () => clearInterval(t);
  }, [selected, loadConversation]);

  async function refreshList() {
    const res = await fetch("/api/inbox");
    if (res.ok) setConversations((await res.json()).conversations);
  }

  async function handleUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    const form = new FormData();
    form.append("file", file);
    form.append("kind", "CHAT");
    const res = await fetch("/api/upload", { method: "POST", body: form });
    const json = await res.json().catch(() => ({}));
    setUploading(false);
    if (!res.ok) return toast.error(json.error ?? "Failed to upload file.");
    
    let type: "image" | "video" | "document" | "audio" = "document";
    if (file.type.startsWith("image/")) type = "image";
    else if (file.type.startsWith("video/")) type = "video";
    else if (file.type.startsWith("audio/")) type = "audio";

    setAttachment({ url: json.url, type, name: file.name });
    if (fileInputRef.current) fileInputRef.current.value = "";
  }

  async function send(e?: React.FormEvent) {
    e?.preventDefault();
    if ((!text.trim() && !attachment) || !selected) return;
    setSending(true);
    const payload: any = { conversationId: selected };
    if (text.trim()) payload.body = text.trim();
    if (attachment) {
      payload.mediaUrl = attachment.url;
      payload.mediaType = attachment.type;
    }
    const res = await fetch("/api/inbox", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    setSending(false);
    if (!res.ok) {
      const j = await res.json().catch(() => ({}));
      toast.error(j.error ?? "Failed to send. Is WhatsApp connected?");
      return;
    }
    setText("");
    setAttachment(null);
    await loadConversation(selected);
    await refreshList();
  }

  async function updateConversation(data: Record<string, unknown>) {
    if (!selected) return;
    const res = await fetch(`/api/inbox/${selected}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });
    if (!res.ok) return toast.error("Update failed.");
    router.refresh();
  }

  const selectedConv = conversations.find((c) => c.id === selected);

  return (
    <div className="flex h-[calc(100vh-7rem)] gap-4">
      {/* Conversation list */}
      <div className="flex w-72 shrink-0 flex-col rounded-xl border border-zinc-200 bg-white">
        <div className="border-b border-zinc-100 px-4 py-3">
          <h2 className="text-sm font-semibold text-zinc-900">Inbox</h2>
          <p className="text-xs text-zinc-500">{conversations.length} conversations</p>
        </div>
        <div className="flex-1 overflow-y-auto">
          {conversations.length === 0 && (
            <div className="p-4 text-sm text-zinc-500">
              {whatsappConfigured
                ? "No conversations yet. Incoming WhatsApp messages will appear here."
                : "Connect your WhatsApp number in Settings → WhatsApp to get started."}
            </div>
          )}
          {conversations.map((c) => {
            const last = c.messages[0];
            return (
              <button
                key={c.id}
                onClick={() => setSelected(c.id)}
                className={cn(
                  "flex w-full items-start gap-3 border-b border-zinc-50 px-4 py-3 text-left hover:bg-zinc-50",
                  selected === c.id && "bg-indigo-50/60 hover:bg-indigo-50"
                )}
              >
                <span className="mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-indigo-100 text-xs font-semibold text-indigo-700">
                  {initials(c.contact.name)}
                </span>
                <span className="min-w-0 flex-1">
                  <span className="flex items-center justify-between">
                    <span className="truncate text-sm font-medium text-zinc-900">{c.contact.name}</span>
                    <span className="shrink-0 text-[10px] text-zinc-400">{timeAgo(c.lastMessageAt)}</span>
                  </span>
                  <span className="flex items-center gap-1">
                    {c.status !== "CLOSED" && <span className="h-1.5 w-1.5 shrink-0 rounded-full bg-emerald-500" />}
                    <span className="truncate text-xs text-zinc-500">
                      {last ? `${last.direction === "INBOUND" ? "←" : "→"} ${last.body}` : "No messages"}
                    </span>
                  </span>
                </span>
              </button>
            );
          })}
        </div>
      </div>

      {/* Thread */}
      <div className="flex min-w-0 flex-1 flex-col rounded-xl border border-zinc-200 bg-white">
        {!selected ? (
          <div className="flex flex-1 items-center justify-center text-sm text-zinc-400">
            Select a conversation
          </div>
        ) : (
          <>
            <div className="flex items-center gap-3 border-b border-zinc-100 px-4 py-3">
              <div className="flex h-9 w-9 items-center justify-center rounded-full bg-indigo-100 text-sm font-semibold text-indigo-700">
                {initials(contactInfo?.name ?? "?")}
              </div>
              <div className="min-w-0">
                <p className="truncate text-sm font-semibold text-zinc-900">{contactInfo?.name ?? "Unknown"}</p>
                <p className="truncate text-xs text-zinc-500">{contactInfo?.phone}</p>
              </div>
              <div className="ml-auto flex items-center gap-2">
                <Select
                  className="h-8 w-40 text-xs"
                  defaultValue={selectedConv?.assigneeId ?? ""}
                  onChange={(e) => updateConversation({ assigneeId: e.target.value || null })}
                >
                  <option value="">Assign to…</option>
                  {members.map((m) => (
                    <option key={m.user.id} value={m.user.id}>
                      {m.user.name}
                    </option>
                  ))}
                </Select>
                <Select
                  className="h-8 w-28 text-xs"
                  value={selectedConv?.status ?? "OPEN"}
                  onChange={(e) => updateConversation({ status: e.target.value })}
                >
                  <option value="OPEN">Open</option>
                  <option value="PENDING">Pending</option>
                  <option value="CLOSED">Closed</option>
                </Select>
              </div>
            </div>

            <div className="flex-1 space-y-3 overflow-y-auto px-5 py-4">
              {messages.length === 0 && (
                <p className="pt-10 text-center text-sm text-zinc-400">No messages yet.</p>
              )}
              {messages.map((m) => (
                <div key={m.id} className={cn("flex", m.direction === "OUTBOUND" ? "justify-end" : "justify-start")}>
                  <div
                    className={cn(
                      "max-w-[70%] rounded-2xl px-4 py-2 text-sm shadow-sm",
                      m.direction === "OUTBOUND"
                        ? "rounded-br-sm bg-indigo-600 text-white"
                        : "rounded-bl-sm border border-zinc-200 bg-white text-zinc-800"
                    )}
                  >
                    {m.mediaUrl && (m.messageType === "image" || m.messageType === "video") && (
                      // eslint-disable-next-line @next/next/no-img-element
                      <img
                        src={m.mediaUrl}
                        alt="media"
                        className="mb-2 max-h-64 cursor-zoom-in rounded-lg hover:opacity-90 transition-opacity"
                        onClick={() => m.messageType === "image" && setZoomedImage(m.mediaUrl)}
                      />
                    )}
                    {!["text", "image", "video"].includes(m.messageType) && (
                      <p className="mb-1 text-xs opacity-70">
                        [{m.messageType}]{m.mediaUrl ? ` · ${m.mediaUrl.split("/").pop()}` : ""}
                      </p>
                    )}
                    <p className="whitespace-pre-wrap break-words">{m.body}</p>
                    <p className={cn("mt-1 text-right text-[10px]", m.direction === "OUTBOUND" ? "text-white/60" : "text-zinc-400")}>
                      {new Date(m.createdAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
                      {m.direction === "OUTBOUND" && m.status && m.status !== "SENT" ? ` · ${m.status}` : ""}
                    </p>
                  </div>
                </div>
              ))}
              <div ref={bottomRef} />
            </div>

            <form onSubmit={send} className="flex flex-col border-t border-zinc-100 p-3">
              {attachment && (
                <div className="mb-2 flex items-center justify-between rounded-md border border-zinc-200 bg-zinc-50 px-3 py-2 text-sm">
                  <span className="truncate text-zinc-600">
                    {attachment.type === "image" ? "📷 " : "📄 "}
                    {attachment.name}
                  </span>
                  <button
                    type="button"
                    onClick={() => setAttachment(null)}
                    className="ml-2 text-zinc-400 hover:text-red-500"
                  >
                    <X className="h-4 w-4" />
                  </button>
                </div>
              )}
              <div className="flex items-end gap-2">
                <input
                  type="file"
                  className="hidden"
                  ref={fileInputRef}
                  onChange={handleUpload}
                />
                <Button
                  type="button"
                  variant="outline"
                  size="icon"
                  className="h-10 w-10 shrink-0 text-zinc-500"
                  disabled={uploading}
                  onClick={() => fileInputRef.current?.click()}
                >
                  {uploading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Paperclip className="h-4 w-4" />}
                </Button>
                <Textarea
                  value={text}
                  onChange={(e) => setText(e.target.value)}
                  rows={2}
                  placeholder="Type a message or caption…"
                  onKeyDown={(e) => {
                    if (e.key === "Enter" && !e.shiftKey) {
                      e.preventDefault();
                      send();
                    }
                  }}
                />
                <Button type="submit" loading={sending || uploading} disabled={!text.trim() && !attachment} size="icon" className="h-10 w-10 shrink-0">
                  <Send className="h-4 w-4" />
                </Button>
              </div>
            </form>
          </>
        )}
      </div>

      {/* Image Zoom Modal */}
      {zoomedImage && (
        <div 
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm p-4"
          onClick={() => setZoomedImage(null)}
        >
          <button 
            className="absolute right-4 top-4 rounded-full bg-white/10 p-2 text-white hover:bg-white/20 transition-colors"
            onClick={(e) => { e.stopPropagation(); setZoomedImage(null); }}
          >
            <X className="h-6 w-6" />
          </button>
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img 
            src={zoomedImage} 
            alt="Zoomed media" 
            className="max-h-[90vh] max-w-[90vw] rounded-md object-contain shadow-2xl"
            onClick={(e) => e.stopPropagation()}
          />
        </div>
      )}
    </div>
  );
}
