import { useState, useEffect } from "react";
import { useAuth } from "@/contexts/AuthContext";
import { supabase } from "@/integrations/supabase/client";
import { STAFF_GROUP_ID, STAFF_GROUP_NAME, useConversations, type Conversation } from "@/hooks/useDirectMessages";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { Search, PenSquare, Loader2 } from "lucide-react";
import { formatDistanceToNow } from "date-fns";
import { cn } from "@/lib/utils";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger,
} from "@/components/ui/dialog";

interface Props {
  selectedPartnerId: string | null;
  onSelectPartner: (id: string, name: string) => void;
}

function getInitials(name: string) {
  return name.split(" ").map((w) => w[0]).join("").toUpperCase().slice(0, 2);
}

export default function ConversationList({ selectedPartnerId, onSelectPartner }: Props) {
  const { isHomeowner, isRvBoatLot, isBoardMember, isStaff } = useAuth();
  const { conversations, loading } = useConversations();
  const [search, setSearch] = useState("");
  const useStaffConversation = isHomeowner || isRvBoatLot;
  const isBoardOnly = isBoardMember && !isStaff;

  const filtered = conversations.filter((c) =>
    c.partner_name.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="flex flex-col h-full border-r border-border">
      <div className="p-3 border-b border-border space-y-2">
        <div className="flex items-center justify-between">
          <h3 className="font-semibold text-sm">Messages</h3>
          {useStaffConversation ? (
            <Button
              variant="ghost"
              size="icon"
              className="h-7 w-7"
              onClick={() => onSelectPartner(STAFF_GROUP_ID, STAFF_GROUP_NAME)}
            >
              <PenSquare className="h-4 w-4" />
            </Button>
          ) : (
            <div className="flex items-center gap-1">
              {isBoardOnly && (
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-7 w-7"
                  title="Message all of management"
                  onClick={() => onSelectPartner(STAFF_GROUP_ID, STAFF_GROUP_NAME)}
                >
                  <PenSquare className="h-4 w-4" />
                </Button>
              )}
              <NewConversationDialog onSelectPartner={onSelectPartner} />
            </div>
          )}
        </div>
        <div className="relative">
          <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
          <Input
            placeholder="Search..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="pl-8 h-8 text-sm"
          />
        </div>
      </div>

      <ScrollArea className="flex-1">
        {loading ? (
          <div className="flex justify-center py-8">
            <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
          </div>
        ) : filtered.length === 0 ? (
          useStaffConversation ? (
            <button
              onClick={() => onSelectPartner(STAFF_GROUP_ID, STAFF_GROUP_NAME)}
              className={cn(
                "w-full flex items-start gap-3 px-3 py-3 text-left hover:bg-accent transition-colors",
                selectedPartnerId === STAFF_GROUP_ID && "bg-accent"
              )}
            >
              <Avatar className="h-9 w-9 shrink-0 mt-0.5">
                <AvatarFallback className="text-xs bg-primary/10 text-primary">AC</AvatarFallback>
              </Avatar>
              <div className="flex-1 min-w-0">
                <span className="text-sm font-medium truncate">{STAFF_GROUP_NAME}</span>
                <p className="text-xs text-muted-foreground truncate mt-0.5">Contact the management team</p>
              </div>
            </button>
          ) : (
            <div className="text-center py-8 px-4">
              <p className="text-sm text-muted-foreground">No conversations yet</p>
              <p className="text-xs text-muted-foreground mt-1">Start a new message to get going</p>
            </div>
          )
        ) : (
          <div className="divide-y divide-border">
            {filtered.map((conv) => (
              <button
                key={conv.partner_id}
                onClick={() => onSelectPartner(conv.partner_id, conv.partner_name)}
                className={cn(
                  "w-full flex items-start gap-3 px-3 py-3 text-left hover:bg-accent transition-colors",
                  selectedPartnerId === conv.partner_id && "bg-accent"
                )}
              >
                <Avatar className="h-9 w-9 shrink-0 mt-0.5">
                  <AvatarImage src={conv.partner_avatar ?? undefined} />
                  <AvatarFallback className="text-xs bg-primary/10 text-primary">
                    {getInitials(conv.partner_name)}
                  </AvatarFallback>
                </Avatar>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center justify-between gap-2">
                    <span className="text-sm font-medium truncate">{conv.partner_name}</span>
                    <span className="text-[10px] text-muted-foreground shrink-0">
                      {formatDistanceToNow(new Date(conv.last_message_at), { addSuffix: true })}
                    </span>
                  </div>
                  {(conv.partner_owner_name || conv.partner_unit) && (
                    <p className="text-[11px] text-muted-foreground/90 truncate">
                      {[conv.partner_owner_name, conv.partner_unit].filter(Boolean).join(" • ")}
                    </p>
                  )}
                  <div className="flex items-center gap-2 mt-0.5">
                    <p className="text-xs text-muted-foreground truncate flex-1">
                      {conv.last_message}
                    </p>
                    {conv.unread_count > 0 && (
                      <Badge className="h-4 min-w-4 px-1 text-[10px] bg-primary text-primary-foreground">
                        {conv.unread_count}
                      </Badge>
                    )}
                  </div>
                </div>
              </button>
            ))}
          </div>
        )}
      </ScrollArea>
    </div>
  );
}

// Dialog to start a new conversation
type RecipientUser = {
  user_id: string;
  full_name: string | null;
  avatar_url: string | null;
  category: "staff" | "homeowner" | "board";
  context?: string;
};

function NewConversationDialog({ onSelectPartner }: { onSelectPartner: (id: string, name: string) => void }) {
  const { user, isStaff, isBoardMember } = useAuth();
  const [open, setOpen] = useState(false);
  const [users, setUsers] = useState<RecipientUser[]>([]);
  const [search, setSearch] = useState("");
  const [tab, setTab] = useState<"all" | "homeowner" | "board" | "staff">("all");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!open) return;
    setLoading(true);
    const loadUsers = async () => {
      // Board members can only message staff
      if (isBoardMember && !isStaff) {
        const { data: roles } = await supabase
          .from("user_roles")
          .select("user_id, role")
          .in("role", ["admin", "manager"]);
        const staffIds = Array.from(new Set((roles ?? []).map((r) => r.user_id).filter((id) => id !== user?.id)));
        if (staffIds.length === 0) {
          setUsers([]);
          setLoading(false);
          return;
        }
        const { data } = await supabase
          .from("profiles")
          .select("user_id, full_name, avatar_url")
          .in("user_id", staffIds);
        setUsers((data ?? []).map((p) => ({ ...p, category: "staff" as const })));
        setLoading(false);
        return;
      }

      // Staff: list homeowners + board members + other staff
      if (isStaff) {
        const [ownersRes, boardRes, rolesRes] = await Promise.all([
          supabase
            .from("owners")
            .select("user_id, first_name, last_name, property_address, associations(name)")
            .not("user_id", "is", null)
            .neq("status", "archived"),
          (supabase as any)
            .from("board_members")
            .select("user_id, role, associations(name)")
            .not("user_id", "is", null),
          supabase.from("user_roles").select("user_id, role").in("role", ["admin", "manager"]),
        ]);

        const userIds = new Set<string>();
        const recipients: RecipientUser[] = [];

        for (const o of (ownersRes.data ?? []) as any[]) {
          if (!o.user_id || o.user_id === user?.id || userIds.has(o.user_id)) continue;
          userIds.add(o.user_id);
          const name = `${o.first_name || ""} ${o.last_name || ""}`.trim() || "Homeowner";
          const ctx = [o.associations?.name, o.property_address].filter(Boolean).join(" • ");
          recipients.push({
            user_id: o.user_id,
            full_name: name,
            avatar_url: null,
            category: "homeowner",
            context: ctx,
          });
        }

        for (const b of (boardRes.data ?? []) as any[]) {
          if (!b.user_id || b.user_id === user?.id) continue;
          if (userIds.has(b.user_id)) {
            // Already added as owner; mark also as board member by appending context
            const existing = recipients.find((r) => r.user_id === b.user_id);
            if (existing) {
              existing.category = "board";
              existing.context = [existing.context, `Board • ${b.role || "Member"} (${b.associations?.name || ""})`.trim()]
                .filter(Boolean)
                .join(" | ");
            }
            continue;
          }
          userIds.add(b.user_id);
          recipients.push({
            user_id: b.user_id,
            full_name: null,
            avatar_url: null,
            category: "board",
            context: `Board • ${b.role || "Member"}${b.associations?.name ? ` (${b.associations.name})` : ""}`,
          });
        }

        const staffIds = Array.from(
          new Set((rolesRes.data ?? []).map((r: any) => r.user_id).filter((id: string) => id && id !== user?.id))
        );
        const missingStaffIds = staffIds.filter((id) => !userIds.has(id));
        for (const id of missingStaffIds) {
          userIds.add(id);
          recipients.push({ user_id: id, full_name: null, avatar_url: null, category: "staff", context: "Staff" });
        }

        // Hydrate names/avatars from profiles for everyone
        const allIds = Array.from(userIds);
        if (allIds.length > 0) {
          const { data: profiles } = await supabase
            .from("profiles")
            .select("user_id, full_name, avatar_url")
            .in("user_id", allIds);
          const pMap = new Map((profiles ?? []).map((p: any) => [p.user_id, p]));
          for (const r of recipients) {
            const p = pMap.get(r.user_id);
            if (p) {
              r.full_name = r.full_name || p.full_name;
              r.avatar_url = p.avatar_url;
            }
          }
        }

        recipients.sort((a, b) => (a.full_name || "").localeCompare(b.full_name || ""));
        setUsers(recipients);
        setLoading(false);
        return;
      }

      // Fallback: any profile
      const { data } = await supabase
        .from("profiles")
        .select("user_id, full_name, avatar_url")
        .neq("user_id", user?.id ?? "");
      setUsers((data ?? []).map((p) => ({ ...p, category: "staff" as const })));
      setLoading(false);
    };

    void loadUsers();
  }, [open, user, isBoardMember, isStaff]);

  const filtered = users.filter((u) => {
    if (tab !== "all" && u.category !== tab) return false;
    const q = search.toLowerCase();
    if (!q) return true;
    return (
      (u.full_name ?? "").toLowerCase().includes(q) ||
      (u.context ?? "").toLowerCase().includes(q)
    );
  });

  const showTabs = isStaff;

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button variant="ghost" size="icon" className="h-7 w-7">
          <PenSquare className="h-4 w-4" />
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>New Message</DialogTitle>
        </DialogHeader>
        <div className="space-y-3">
          <Input
            placeholder="Search recipients..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
          />
          {showTabs && (
            <div className="flex gap-1 text-xs">
              {([
                ["all", "All"],
                ["homeowner", "Homeowners"],
                ["board", "Board"],
                ["staff", "Staff"],
              ] as const).map(([key, label]) => (
                <button
                  key={key}
                  onClick={() => setTab(key)}
                  className={cn(
                    "px-2.5 py-1 rounded-md border border-border transition-colors",
                    tab === key ? "bg-primary text-primary-foreground border-primary" : "hover:bg-accent"
                  )}
                >
                  {label}
                </button>
              ))}
            </div>
          )}
          <ScrollArea className="h-72">
            {loading ? (
              <div className="flex justify-center py-4">
                <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
              </div>
            ) : (
              <div className="space-y-1">
                {filtered.map((u) => (
                  <button
                    key={u.user_id}
                    onClick={() => {
                      onSelectPartner(u.user_id, u.full_name || "Unknown User");
                      setOpen(false);
                    }}
                    className="w-full flex items-center gap-3 px-3 py-2 rounded-md hover:bg-accent transition-colors text-left"
                  >
                    <Avatar className="h-8 w-8">
                      <AvatarImage src={u.avatar_url ?? undefined} />
                      <AvatarFallback className="text-xs bg-primary/10 text-primary">
                        {getInitials(u.full_name || "?")}
                      </AvatarFallback>
                    </Avatar>
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <span className="text-sm font-medium truncate">{u.full_name || "Unknown User"}</span>
                        <Badge variant="outline" className="text-[10px] capitalize shrink-0">
                          {u.category === "board" ? "Board" : u.category}
                        </Badge>
                      </div>
                      {u.context && (
                        <p className="text-[11px] text-muted-foreground truncate">{u.context}</p>
                      )}
                    </div>
                  </button>
                ))}
                {filtered.length === 0 && !loading && (
                  <p className="text-sm text-muted-foreground text-center py-4">No recipients found</p>
                )}
              </div>
            )}
          </ScrollArea>
        </div>
      </DialogContent>
    </Dialog>
  );
}
