import { useState, useEffect, useRef, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { FiX, FiSearch, FiTrash2, FiLogOut, FiUpload, FiShield, FiShieldOff } from "react-icons/fi";
import { useQueryClient } from "@tanstack/react-query";
import type { Chat } from "@/api/generated/private/models/chat";
import { ChatTypeEnum } from "@/api/generated/private/models/chatTypeEnum";
import {
  getApiSocialChatsListQueryKey,
  getApiSocialChatsRetrieveQueryKey,
  useApiSocialChatsDestroy,
} from "@/api/generated/private/chat/chat";
import { useApiAccountUsersList } from "@/api/generated/private/account/account";
import type { CustomUser } from "@/api/generated/private/models";
import { useAuth } from "@/hooks/useAuth";
import { canManageChat } from "@/hooks/usePermissions";
import { privateApi } from "@/api/privateClient";
import Avatar from "@/components/ui/Avatar";
import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input";
import Spinner from "@/components/ui/Spinner";
import FormErrorBanner from "@/components/ui/FormErrorBanner";

interface MemberDetail {
  id: number;
  username: string;
  avatar: string | null;
}

type ChatWithDetails = Chat & { members_detail?: MemberDetail[] };

interface Props {
  chat: ChatWithDetails;
  open: boolean;
  onClose: () => void;
}

export default function ChatSettingsModal({ chat, open, onClose }: Props) {
  const { t } = useTranslation("social");
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const isGroup = chat.chat_type === ChatTypeEnum.GROUP;
  const canManage = canManageChat(user, chat);
  const isOwner = chat.owner === user?.id;
  const members = chat.members_detail ?? [];

  // --- Info section state ---
  const [name, setName] = useState(chat.name ?? "");
  const [iconFile, setIconFile] = useState<File | null>(null);
  const [iconPreview, setIconPreview] = useState<string | null>(null);
  const [savingInfo, setSavingInfo] = useState(false);

  // --- Add member section ---
  const [memberQuery, setMemberQuery] = useState("");
  const [debouncedMemberQuery, setDebouncedMemberQuery] = useState("");
  const [showDropdown, setShowDropdown] = useState(false);
  const searchRef = useRef<HTMLDivElement>(null);

  // --- Confirm leave/delete ---
  const [confirmAction, setConfirmAction] = useState<"leave" | "delete" | null>(null);

  const [error, setError] = useState<string | null>(null);
  const [pendingUserId, setPendingUserId] = useState<number | null>(null);

  const invalidateChat = useCallback(() => {
    void queryClient.invalidateQueries({ queryKey: getApiSocialChatsRetrieveQueryKey(String(chat.id)) });
    void queryClient.invalidateQueries({ queryKey: getApiSocialChatsListQueryKey() });
  }, [queryClient, chat.id]);

  // Debounce member search
  useEffect(() => {
    const timer = setTimeout(() => setDebouncedMemberQuery(memberQuery.trim()), 300);
    return () => clearTimeout(timer);
  }, [memberQuery]);

  // Close dropdown on outside click
  useEffect(() => {
    function handler(e: MouseEvent) {
      if (searchRef.current && !searchRef.current.contains(e.target as Node)) {
        setShowDropdown(false);
      }
    }
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  // Close on Escape
  useEffect(() => {
    if (!open) return;
    const handler = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", handler);
    return () => window.removeEventListener("keydown", handler);
  }, [open, onClose]);

  // Sync name state when chat changes
  useEffect(() => { setName(chat.name ?? ""); }, [chat.name]);

  const { data: searchData, isLoading: searchLoading } = useApiAccountUsersList(
    debouncedMemberQuery.length >= 2 ? { username: debouncedMemberQuery } : undefined,
    { query: { enabled: debouncedMemberQuery.length >= 2 } },
  );
  const searchResults = (searchData?.results ?? []).filter(
    (u) => !chat.members?.includes(u.id),
  );

  const { mutate: destroyChat, isPending: destroying } = useApiSocialChatsDestroy({
    mutation: {
      onSuccess: async () => {
        await queryClient.invalidateQueries({ queryKey: getApiSocialChatsListQueryKey() });
        onClose();
        navigate("/social/chats");
      },
      onError: () => setError(t("chat.settings.deleteError")),
    },
  });

  function handleIconChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    setIconFile(file);
    setIconPreview(URL.createObjectURL(file));
  }

  async function handleSaveInfo() {
    setSavingInfo(true);
    setError(null);
    try {
      const fd = new FormData();
      if (name.trim() !== (chat.name ?? "")) fd.append("name", name.trim());
      if (iconFile) fd.append("icon", iconFile);
      if ([...fd.keys()].length === 0) return;
      await privateApi.patch(`/api/social/chats/${chat.id}/`, fd);
      invalidateChat();
      setIconFile(null);
    } catch {
      setError(t("chat.settings.saveError"));
    } finally {
      setSavingInfo(false);
    }
  }

  async function handleAddMember(u: CustomUser) {
    setError(null);
    setPendingUserId(u.id);
    try {
      await privateApi.post(`/api/social/chats/${chat.id}/members/add/`, { user_id: u.id });
      invalidateChat();
      setMemberQuery("");
      setShowDropdown(false);
    } catch {
      setError(t("chat.settings.addMemberError"));
    } finally {
      setPendingUserId(null);
    }
  }

  async function handleRemoveMember(userId: number) {
    setError(null);
    setPendingUserId(userId);
    try {
      await privateApi.post(`/api/social/chats/${chat.id}/members/remove/`, { user_id: userId });
      invalidateChat();
    } catch {
      setError(t("chat.settings.removeMemberError"));
    } finally {
      setPendingUserId(null);
    }
  }

  async function handleToggleModerator(userId: number) {
    setError(null);
    const isMod = chat.moderators?.includes(userId) ?? false;
    const url = isMod
      ? `/api/social/chats/${chat.id}/moderators/remove/`
      : `/api/social/chats/${chat.id}/moderators/add/`;
    setPendingUserId(userId);
    try {
      await privateApi.post(url, { user_id: userId });
      invalidateChat();
    } catch {
      setError(t("chat.settings.modError"));
    } finally {
      setPendingUserId(null);
    }
  }

  async function handleLeave() {
    if (!user) return;
    setError(null);
    try {
      await privateApi.post(`/api/social/chats/${chat.id}/members/remove/`, { user_id: user.id });
      await queryClient.invalidateQueries({ queryKey: getApiSocialChatsListQueryKey() });
      onClose();
      navigate("/social/chats");
    } catch {
      setError(t("chat.settings.leaveError"));
    }
  }

  if (!open) return null;

  const infoChanged = name.trim() !== (chat.name ?? "") || iconFile !== null;

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center p-4"
      role="dialog"
      aria-modal="true"
      aria-label={t("chat.settings.title")}
    >
      <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onClose} />

      <div className="relative z-10 w-full max-w-md rounded-2xl border border-brand-lines/20 bg-brand-gradient shadow-2xl max-h-[90vh] flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between border-b border-brand-lines/15 px-5 py-4 shrink-0">
          <h2 className="text-base font-semibold text-brand-text">{t("chat.settings.title")}</h2>
          <button
            type="button"
            onClick={onClose}
            className="inline-flex h-7 w-7 items-center justify-center rounded-full text-brand-text/60 hover:bg-brand-lines/15 hover:text-brand-text transition-colors"
            aria-label={t("chat.settings.close")}
          >
            <FiX size={16} />
          </button>
        </div>

        {/* Scrollable body */}
        <div className="overflow-y-auto flex-1">
          {/* ── Chat info ── */}
          <section className="px-5 py-5 space-y-4 border-b border-brand-lines/10">
            <div className="flex items-center gap-4">
              {/* Icon */}
              {isGroup && canManage ? (
                <label className="relative cursor-pointer group shrink-0">
                  <Avatar
                    name={chat.name ?? ""}
                    src={iconPreview ?? chat.icon ?? undefined}
                    size={56}
                  />
                  <span className="absolute inset-0 flex items-center justify-center rounded-full bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity">
                    <FiUpload size={16} className="text-white" />
                  </span>
                  <input
                    type="file"
                    accept="image/*"
                    className="sr-only"
                    onChange={handleIconChange}
                  />
                </label>
              ) : (
                <Avatar
                  name={chat.name ?? ""}
                  src={chat.icon ?? undefined}
                  size={56}
                  className="shrink-0"
                />
              )}

              {/* Name */}
              <div className="flex-1 min-w-0">
                {isGroup && canManage ? (
                  <Input
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    placeholder={t("chat.settings.namePlaceholder")}
                    maxLength={255}
                  />
                ) : (
                  <p className="text-sm font-semibold text-brand-text truncate">{chat.name}</p>
                )}
                <p className="text-xs text-brand-text/50 mt-0.5">
                  {isGroup ? t("chat.settings.typeGroup") : t("chat.settings.typeDM")}
                  {" · "}
                  {t("chat.settings.memberCount", { count: members.length })}
                </p>
              </div>
            </div>

            {isGroup && canManage && (
              <Button
                type="button"
                variant="primary"
                size="sm"
                disabled={!infoChanged || savingInfo}
                loading={savingInfo}
                onClick={() => void handleSaveInfo()}
              >
                {t("chat.settings.saveInfo")}
              </Button>
            )}
          </section>

          {/* ── Members ── */}
          <section className="px-5 py-4 space-y-3 border-b border-brand-lines/10">
            <h3 className="text-xs font-semibold uppercase tracking-wider text-brand-text/50">
              {t("chat.settings.membersTitle")}
            </h3>

            {/* Add member (GROUP + canManage only) */}
            {isGroup && canManage && (
              <div ref={searchRef} className="relative">
                <div className="relative">
                  <FiSearch className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-brand-text/40" size={14} />
                  <input
                    value={memberQuery}
                    onChange={(e) => { setMemberQuery(e.target.value); setShowDropdown(true); }}
                    onFocus={() => memberQuery.length >= 2 && setShowDropdown(true)}
                    placeholder={t("chat.settings.addMemberPlaceholder")}
                    className="w-full rounded-xl border border-brand-lines/25 bg-brand-bgLight/40 py-2 pl-8 pr-3 text-sm text-brand-text placeholder:text-brand-text/40 focus:border-brand-accent focus:outline-none focus:ring-2 focus:ring-brand-accent/30"
                  />
                </div>
                {showDropdown && debouncedMemberQuery.length >= 2 && (
                  <div
                    className="absolute left-0 right-0 top-full z-50 mt-1 max-h-44 overflow-y-auto rounded-xl border border-brand-lines/20 shadow-xl"
                    style={{ backgroundColor: "var(--c-background)" }}
                  >
                    {searchLoading && (
                      <div className="flex justify-center py-3"><Spinner size={16} /></div>
                    )}
                    {!searchLoading && searchResults.length === 0 && (
                      <p className="px-4 py-3 text-sm text-brand-text/50">{t("chat.settings.noUsers")}</p>
                    )}
                    {searchResults.map((u) => (
                      <button
                        key={u.id}
                        type="button"
                        disabled={pendingUserId === u.id}
                        onClick={() => void handleAddMember(u)}
                        className="flex w-full items-center gap-3 px-4 py-2 text-left hover:bg-brand-lines/10 transition-colors disabled:opacity-50"
                      >
                        <Avatar name={u.username} src={u.avatar ?? undefined} size={26} />
                        <span className="text-sm text-brand-text">{u.username}</span>
                        {pendingUserId === u.id && <Spinner size={14} className="ml-auto" />}
                      </button>
                    ))}
                  </div>
                )}
              </div>
            )}

            {/* Member list */}
            <div className="space-y-1">
              {members.map((m) => {
                const isMod = chat.moderators?.includes(m.id) ?? false;
                const isThisOwner = chat.owner === m.id;
                const isMe = user?.id === m.id;
                const isPending = pendingUserId === m.id;

                return (
                  <div key={m.id} className="flex items-center gap-3 rounded-xl px-2 py-2 hover:bg-brand-lines/8 transition-colors">
                    <Avatar name={m.username} src={m.avatar ?? undefined} size={32} />
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-1.5 min-w-0">
                        <span className="text-sm font-medium text-brand-text truncate">{m.username}</span>
                        {isThisOwner && (
                          <span className="shrink-0 rounded-full bg-yellow-400/15 px-1.5 py-0.5 text-[10px] font-semibold text-yellow-400">
                            {t("chat.settings.roleOwner")}
                          </span>
                        )}
                        {!isThisOwner && isMod && (
                          <span className="shrink-0 rounded-full bg-brand-accent/15 px-1.5 py-0.5 text-[10px] font-semibold text-brand-accent">
                            {t("chat.settings.roleMod")}
                          </span>
                        )}
                      </div>
                    </div>

                    {/* Actions — shown only to canManage, not for owner, not for self (except leave is elsewhere) */}
                    {canManage && !isThisOwner && !isMe && (
                      <div className="flex items-center gap-1 shrink-0">
                        {isPending ? (
                          <Spinner size={14} />
                        ) : (
                          <>
                            {/* Toggle mod (owner only) */}
                            {isOwner && (
                              <button
                                type="button"
                                title={isMod ? t("chat.settings.removeMod") : t("chat.settings.makeMod")}
                                onClick={() => void handleToggleModerator(m.id)}
                                className="inline-flex h-7 w-7 items-center justify-center rounded-full text-brand-text/50 hover:bg-brand-lines/15 hover:text-brand-accent transition-colors"
                              >
                                {isMod ? <FiShieldOff size={13} /> : <FiShield size={13} />}
                              </button>
                            )}
                            {/* Remove member */}
                            <button
                              type="button"
                              title={t("chat.settings.removeMember")}
                              onClick={() => void handleRemoveMember(m.id)}
                              className="inline-flex h-7 w-7 items-center justify-center rounded-full text-brand-text/50 hover:bg-red-500/15 hover:text-red-400 transition-colors"
                            >
                              <FiX size={13} />
                            </button>
                          </>
                        )}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          </section>

          {/* ── Danger zone ── */}
          <section className="px-5 py-4 space-y-2">
            <FormErrorBanner message={error} />

            {confirmAction ? (
              <div className="rounded-xl border border-red-500/20 bg-red-500/5 p-4 space-y-3">
                <p className="text-sm text-brand-text">
                  {confirmAction === "leave" ? t("chat.settings.confirmLeave") : t("chat.settings.confirmDelete")}
                </p>
                <div className="flex gap-2">
                  <Button
                    type="button"
                    variant="danger"
                    size="sm"
                    loading={destroying}
                    onClick={() => {
                      if (confirmAction === "leave") void handleLeave();
                      else destroyChat({ id: String(chat.id) });
                    }}
                  >
                    {t("chat.settings.confirm")}
                  </Button>
                  <Button type="button" variant="ghost" size="sm" onClick={() => setConfirmAction(null)}>
                    {t("chat.settings.cancel")}
                  </Button>
                </div>
              </div>
            ) : (
              <div className="flex flex-col gap-2">
                {!isOwner && (
                  <button
                    type="button"
                    onClick={() => setConfirmAction("leave")}
                    className="flex items-center gap-2 rounded-xl px-3 py-2.5 text-sm text-red-400 hover:bg-red-500/10 transition-colors w-full"
                  >
                    <FiLogOut size={15} />
                    {t("chat.settings.leave")}
                  </button>
                )}
                {canManage && (
                  <button
                    type="button"
                    onClick={() => setConfirmAction("delete")}
                    className="flex items-center gap-2 rounded-xl px-3 py-2.5 text-sm text-red-400 hover:bg-red-500/10 transition-colors w-full"
                  >
                    <FiTrash2 size={15} />
                    {t("chat.settings.delete")}
                  </button>
                )}
              </div>
            )}
          </section>
        </div>
      </div>
    </div>
  );
}
