﻿import { useEffect, useState, useCallback, useRef } from "react";
import { useNavigate } from "react-router-dom";
import { Search, Loader2, MessageSquare, Trash2, PenLine, Mail, MailOpen } from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
import { useQueryClient } from "@tanstack/react-query";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/hooks/useAuth";
import AppLayout from "@/components/AppLayout";
import Avatar from "@/components/Avatar";
import RGBName from "@/components/RGBName";
import VerifiedBadge from "@/components/VerifiedBadge";
import NotesBar from "@/components/NotesBar";
import { isOnline } from "@/hooks/usePresence";
import { formatDistanceToNow } from "date-fns";
import { ptBR } from "date-fns/locale";
import { queryInChunksByField, getUnreadCountsByIds } from "@/lib/chunkedQueries";
import { toast } from "sonner";
import { cn } from "@/lib/utils";

export const MESSAGES_QUERY_KEY = ["messages-convs"];

interface ProfileLite {
  id: string; display_name: string | null; photo_url: string | null;
  username: string | null; last_seen_at?: string | null; show_activity?: boolean | null; is_verified?: boolean; profile_theme?: any;
}
interface ConvRow {
  id: string; last_message_at: string | null; other: ProfileLite | null;
  last: { content: string | null; type: string; sender_id: string; created_at: string } | null;
  unread: number;
}
interface ConvMeta {
  id: string; last_message_at: string | null;
}

const chunkArray = <T,>(arr: T[], size: number): T[][] => {
  const chunks: T[][] = [];
  for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size));
  return chunks;
};

export default function Messages() {
  const navigate = useNavigate();
  const { user } = useAuth();
  const [convs, setConvs] = useState<ConvRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [users, setUsers] = useState<ProfileLite[]>([]);
  const [searching, setSearching] = useState(false);
  const [starting, setStarting] = useState(false);
  const [deletingConv, setDeletingConv] = useState<string | null>(null);
  const [filterTab, setFilterTab] = useState<"all" | "unread">("all");
  const searchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const convMetaRef = useRef<Map<string, ConvMeta>>(new Map());
  const unreadRef = useRef<Map<string, number>>(new Map());
  const profilesRef = useRef<Map<string, ProfileLite>>(new Map());
  const lastMessagesRef = useRef<Map<string, ConvRow["last"]>>(new Map());
  const myConvIdsSetRef = useRef<Set<string>>(new Set());
  const hiddenSetRef = useRef<Set<string>>(new Set());
  const queryClient = useQueryClient();

  const load = useCallback(async (isSilent = false) => {
    if (!user) return;
    const cached = queryClient.getQueryData<ConvRow[]>(MESSAGES_QUERY_KEY);
    if (cached && cached.length > 0) {
      setConvs(cached);
      setLoading(false);
    } else if (!isSilent) {
      setLoading(true);
    }

    try {
      const { data: myParts } = await supabase
        .from("conversation_participants")
        .select("conversation_id")
        .eq("user_id", user.id);
      const convIds = (myParts || []).map((p) => p.conversation_id);
      if (!convIds.length) { setConvs([]); setLoading(false); return; }

      myConvIdsSetRef.current = new Set(convIds);

      const [
        convData,
        unreadMap,
        { data: hiddenData },
        otherParts,
      ] = await Promise.all([
        queryInChunksByField<any>(supabase, "conversations", "id", convIds, {
          select: "id, last_message_at", chunkSize: 200
        }),
        getUnreadCountsByIds(supabase, user.id, convIds),
        supabase.from("conversation_hidden").select("conversation_id").eq("user_id", user.id),
        queryInChunksByField<any>(supabase, "conversation_participants", "conversation_id", convIds, {
          select: "conversation_id, user_id", chunkSize: 200
        }),
      ]);

      if (!convData?.length) { setConvs([]); setLoading(false); return; }

      const metaMap = new Map<string, ConvMeta>();
      for (const c of convData) metaMap.set(c.id, c);
      convMetaRef.current = metaMap;

      unreadRef.current = unreadMap;

      const hiddenSet = new Set((hiddenData || []).map((h: any) => h.conversation_id));
      hiddenSetRef.current = hiddenSet;

      const filteredParts = (otherParts || []).filter((p: any) => p.user_id !== user.id);
      const otherIdByConv = new Map<string, string>();
      for (const row of filteredParts) {
        if (!otherIdByConv.has(row.conversation_id)) otherIdByConv.set(row.conversation_id, row.user_id);
      }
      const otherIds = Array.from(new Set(Array.from(otherIdByConv.values())));

      const lastChunks = chunkArray(convIds, 100);
      const [
        lastResults,
        profileRows,
      ] = await Promise.all([
        Promise.all(
          lastChunks.map(chunk =>
            supabase
              .from("messages")
              .select("id, conversation_id, content, type, sender_id, created_at")
              .in("conversation_id", chunk)
              .order("created_at", { ascending: false })
              .limit(chunk.length * 2)
              .then(({ data }) => data || [])
          )
        ).then(chunks => chunks.flat()),
        otherIds.length
          ? queryInChunksByField<ProfileLite>(supabase, "profiles", "id", otherIds, {
              select: "id, display_name, photo_url, username, last_seen_at, show_activity, is_verified, profile_theme",
              chunkSize: 200
            })
          : Promise.resolve([]),
      ]);

      const lastByConv = new Map<string, ConvRow["last"]>();
      for (const m of lastResults) {
        const existing = lastByConv.get(m.conversation_id);
        if (!existing || new Date(m.created_at) > new Date(existing.created_at)) {
          lastByConv.set(m.conversation_id, m);
        }
      }
      lastMessagesRef.current = lastByConv;

      const pMap = new Map<string, ProfileLite>((profileRows || []).map((p: any) => [p.id, p]));
      profilesRef.current = pMap;

      const rows: ConvRow[] = convData
        .filter((c: any) => !hiddenSet.has(c.id))
        .sort((a: any, b: any) => new Date(b.last_message_at || 0).getTime() - new Date(a.last_message_at || 0).getTime())
        .map((c: any) => {
          const otherId = otherIdByConv.get(c.id);
          const other = otherId ? profilesRef.current.get(otherId) || null : null;
          const last = lastMessagesRef.current.get(c.id) || null;
          return {
            id: c.id, last_message_at: c.last_message_at || last?.created_at || null, other, last,
            unread: unreadMap.get(c.id) || 0,
          };
        });
      setConvs(rows);
      queryClient.setQueryData(MESSAGES_QUERY_KEY, rows);
    } catch (err) {
      console.error("[Messages] load error:", err);
    } finally {
      setLoading(false);
    }
  }, [user, queryClient]);

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

  const doSearch = (query: string) => {
    setSearch(query);
    if (searchTimeoutRef.current) clearTimeout(searchTimeoutRef.current);
    if (!query.trim()) { setUsers([]); setSearching(false); return; }

    setSearching(true);
    searchTimeoutRef.current = setTimeout(async () => {
      const q = query.trim().replace(/^@/, "");
      const { data } = await supabase
        .from("profiles")
        .select("id, display_name, photo_url, username, is_verified, profile_theme")
        .or(`username.ilike.%${q}%,display_name.ilike.%${q}%`)
        .neq("id", user?.id || "")
        .limit(10);
      setUsers((data as ProfileLite[]) || []);
      setSearching(false);
    }, 250);
  };

  const startConv = async (targetUserId: string) => {
    if (!user || starting) return;
    setStarting(true);
    try {
      const { data, error } = await supabase.rpc("get_or_create_direct_conversation", {
        p_user_a: user.id,
        p_user_b: targetUserId,
      });
      if (error) throw error;
      navigate(`/chat/${data}`);
    } catch (err: any) {
      toast.error(err.message || "Falha ao iniciar conversa");
    } finally {
      setStarting(false);
    }
  };

  const hideConv = async (convId: string) => {
    if (!user) return;
    setDeletingConv(convId);
    try {
      await supabase.from("conversation_hidden").upsert({
        conversation_id: convId,
        user_id: user.id,
      });
      setConvs(prev => prev.filter(c => c.id !== convId));
      toast.success("Conversa removida");
    } catch {
      toast.error("Falha ao remover conversa");
    } finally {
      setDeletingConv(null);
    }
  };

  const preview = (c: ConvRow) => {
    if (!c.last) return "Nova conversa";
    if (c.last.type === "image") return "📷 Foto";
    if (c.last.type === "video") return "📹 Vídeo";
    if (c.last.type === "audio") return "🎙️ Mensagem de áudio";
    if (c.last.type === "sticker") return "🎨 Figurinha";
    return c.last.content || "...";
  };

  const filteredConvs = filterTab === "unread" ? convs.filter(c => c.unread > 0) : convs;

  return (
    <AppLayout transparentBg>
      <div className="min-h-dvh">
        <div className="max-w-lg sm:max-w-xl mx-auto px-4 pt-6 pb-6 space-y-5">

          {/* Header */}
          <div className="flex items-center justify-between">
            <h1 className="font-display text-2xl font-bold text-white tracking-tight flex items-center gap-2.5">
              Mensagens
              <span className="px-2.5 py-0.5 rounded-full bg-sky-500/15 border border-sky-500/25 text-sky-400 text-xs font-semibold">
                {convs.length}
              </span>
            </h1>
            <button
              onClick={() => {
                const searchEl = document.getElementById("search-input");
                searchEl?.focus();
              }}
              className="w-10 h-10 rounded-2xl bg-slate-800/80 border border-white/[0.1] flex items-center justify-center text-slate-300 hover:text-white hover:border-sky-500/40 transition-all active:scale-95 shadow-sm"
              aria-label="Nova Mensagem"
            >
              <PenLine className="w-5 h-5 text-sky-400" />
            </button>
          </div>

          {/* Search Input */}
          <div className="relative">
            <div className="absolute inset-y-0 left-3.5 flex items-center pointer-events-none">
              <Search className="w-4 h-4 text-slate-400" />
            </div>
            <input
              id="search-input"
              value={search}
              onChange={(e) => doSearch(e.target.value)}
              placeholder="Buscar conversas ou pessoas..."
              className="w-full h-11 pl-10 pr-4 rounded-2xl bg-slate-900/90 border border-white/[0.1] text-xs text-white placeholder:text-slate-500 outline-none focus:border-sky-500/50 focus:ring-2 focus:ring-sky-500/20 transition-all"
            />
          </div>

          {/* Filter Tabs */}
          <div className="flex items-center gap-1.5 bg-slate-900/80 border border-white/[0.08] rounded-2xl p-1 w-fit backdrop-blur-xl">
            <button
              onClick={() => setFilterTab("all")}
              className={cn(
                "flex items-center gap-2 px-4 py-2 rounded-xl text-xs font-semibold transition-all duration-200",
                filterTab === "all" ? "bg-sky-600 text-white shadow-sm" : "text-slate-400 hover:text-white"
              )}
            >
              <Mail className="w-3.5 h-3.5" />
              Todas
            </button>
            <button
              onClick={() => setFilterTab("unread")}
              className={cn(
                "flex items-center gap-2 px-4 py-2 rounded-xl text-xs font-semibold transition-all duration-200",
                filterTab === "unread" ? "bg-sky-600 text-white shadow-sm" : "text-slate-400 hover:text-white"
              )}
            >
              <MailOpen className="w-3.5 h-3.5" />
              Não Lidas
              {convs.filter(c => c.unread > 0).length > 0 && (
                <span className="ml-1 px-1.5 py-0.2 rounded-full bg-emerald-500 text-white text-[9px] font-bold">
                  {convs.filter(c => c.unread > 0).length}
                </span>
              )}
            </button>
          </div>

          {/* Search Results Drawer */}
          <AnimatePresence>
            {search && users.length > 0 && (
              <motion.div
                initial={{ opacity: 0, y: -8 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: -8 }}
                className="bg-slate-900/95 rounded-2xl overflow-hidden border border-white/10 shadow-xl"
              >
                <div className="px-4 py-2.5 border-b border-white/[0.08] bg-slate-950/60">
                  <p className="text-[11px] font-bold text-slate-400 uppercase tracking-wider">Pessoas Encontradas</p>
                </div>
                {users.map((u, i) => (
                  <motion.button
                    key={u.id}
                    initial={{ opacity: 0, x: -10 }}
                    animate={{ opacity: 1, x: 0 }}
                    transition={{ delay: i * 0.03 }}
                    onClick={() => { setSearch(""); setUsers([]); startConv(u.id); }}
                    className="flex items-center gap-3 w-full px-4 py-3.5 text-left border-b border-white/[0.04] last:border-0 hover:bg-white/[0.06] transition-all active:scale-[0.99]"
                  >
                    <div className="relative">
                      <Avatar url={u.photo_url} name={u.display_name} size="md" />
                      {isOnline(u.last_seen_at) && (
                        <span className="absolute bottom-0 right-0 w-3 h-3 bg-emerald-500 rounded-full border-2 border-slate-950" />
                      )}
                    </div>
                    <div className="min-w-0 flex-1">
                      <p className="text-xs font-bold text-white truncate flex items-center gap-1.5">
                        <RGBName name={u.display_name || u.username || "Usuário"} profile_theme={u.profile_theme} />
                        {u.is_verified && <VerifiedBadge size="xxs" />}
                      </p>
                      <p className="text-[11px] text-slate-400 truncate">@{u.username || "usuario"}</p>
                    </div>
                    <span className="btn-friendly text-[10px] px-3 py-1.5 font-semibold">
                      Conversar
                    </span>
                  </motion.button>
                ))}
              </motion.div>
            )}
            {search && users.length === 0 && !searching && (
              <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="text-center py-12">
                <div className="w-14 h-14 mx-auto rounded-2xl bg-slate-900/80 border border-white/10 flex items-center justify-center mb-3">
                  <Search className="w-6 h-6 text-slate-500" />
                </div>
                <p className="text-xs font-semibold text-slate-400">Nenhum usuário encontrado</p>
              </motion.div>
            )}
          </AnimatePresence>

          {/* Notes Bar */}
          <NotesBar />

          {/* Conversation List */}
          {loading ? (
            <div className="flex flex-col items-center py-20 gap-4">
              <div className="w-12 h-12 rounded-2xl bg-sky-500/10 border border-sky-500/20 flex items-center justify-center shadow-sm">
                <Loader2 className="w-6 h-6 text-sky-400 animate-spin" />
              </div>
              <p className="text-xs font-semibold text-slate-400">Carregando conversas...</p>
            </div>
          ) : filteredConvs.length === 0 && !search ? (
            <motion.div
              initial={{ opacity: 0, y: 12 }}
              animate={{ opacity: 1, y: 0 }}
              className="text-center py-20 space-y-4"
            >
              <div className="w-16 h-16 mx-auto rounded-2xl bg-slate-900/80 border border-white/[0.1] flex items-center justify-center">
                <MessageSquare className="w-8 h-8 text-sky-400/70" />
              </div>
              <div>
                <p className="text-base font-bold text-white">
                  {filterTab === "unread" ? "Nenhuma mensagem não lida" : "Nenhuma conversa ainda"}
                </p>
                <p className="text-xs text-slate-400 mt-1 max-w-[240px] mx-auto">
                  {filterTab === "unread" ? "Todas as suas mensagens foram lidas" : "Inicie um bate-papo com seus amigos!"}
                </p>
              </div>
            </motion.div>
          ) : (
            <div className="space-y-2">
              <AnimatePresence mode="popLayout">
                {filteredConvs.map((c) => {
                  const online = c.other?.show_activity !== false && isOnline(c.other?.last_seen_at);
                  const hasUnread = c.unread > 0;
                  return (
                    <motion.div
                      key={c.id}
                      layout
                      initial={{ opacity: 0, y: 8 }}
                      animate={{ opacity: 1, y: 0 }}
                      exit={{ opacity: 0, height: 0, marginBottom: 0 }}
                      transition={{ type: "spring", stiffness: 350, damping: 25 }}
                      className="relative group"
                    >
                      <button
                        onClick={() => navigate(`/chat/${c.id}`)}
                        className={cn(
                          "flex items-center gap-3.5 w-full p-3.5 rounded-2xl border text-left transition-all duration-200 active:scale-[0.98]",
                          hasUnread
                            ? "bg-slate-900/90 border-sky-500/40 shadow-sm"
                            : "bg-slate-900/60 border-white/[0.08] hover:bg-slate-900/85 hover:border-white/15"
                        )}
                      >
                        {/* Avatar */}
                        <div className="relative shrink-0">
                          <Avatar url={c.other?.photo_url} name={c.other?.display_name} size="md" />
                          {online && (
                            <span className="absolute bottom-0 right-0 w-3 h-3 bg-emerald-500 rounded-full border-2 border-slate-950" />
                          )}
                        </div>

                        {/* Text Metadata */}
                        <div className="min-w-0 flex-1">
                          <div className="flex items-center justify-between gap-2 mb-1">
                            <span className="font-bold text-xs sm:text-sm text-white truncate flex items-center gap-1.5">
                              <RGBName name={c.other?.display_name || c.other?.username || "Conversa"} profile_theme={c.other?.profile_theme} />
                              {c.other?.is_verified && <VerifiedBadge size="xxs" />}
                            </span>
                            {c.last_message_at && (
                              <span className="text-[10px] text-slate-400 shrink-0 font-medium">
                                {formatDistanceToNow(new Date(c.last_message_at), { addSuffix: true, locale: ptBR })}
                              </span>
                            )}
                          </div>

                          <div className="flex items-center justify-between gap-2">
                            <p className={cn(
                              "text-xs truncate max-w-[240px]",
                              hasUnread ? "font-bold text-sky-400" : "text-slate-400"
                            )}>
                              {preview(c)}
                            </p>

                            {hasUnread && (
                              <span className="min-w-[20px] h-[20px] px-1.5 rounded-full bg-sky-500 text-white font-bold text-[10px] flex items-center justify-center shrink-0 shadow-sm">
                                {c.unread > 99 ? "99+" : c.unread}
                              </span>
                            )}
                          </div>
                        </div>
                      </button>

                      {/* Quick Delete Action */}
                      <button
                        onClick={(e) => { e.stopPropagation(); hideConv(c.id); }}
                        className="absolute right-3 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 p-2 rounded-xl bg-red-500/15 text-red-400 border border-red-500/20 hover:bg-red-500/25 transition-all"
                        title="Remover conversa"
                      >
                        <Trash2 className="w-4 h-4" />
                      </button>
                    </motion.div>
                  );
                })}
              </AnimatePresence>
            </div>
          )}
        </div>
      </div>
    </AppLayout>
  );
}