"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useConvex, useMutation } from "convex/react";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { api } from "@/lib/convex/api";
import { v4 as uuidv4 } from "uuid";

type GroupRow = {
  id: string;
  name: string;
  created_by: string;
  created_at: string;
  my_role: "owner" | "member";
};

type MemberRow = {
  userId: string;
  username: string | null;
  role: "owner" | "member";
  createdAt: string;
};

export interface GroupManagerDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  workspaceId: string;
}

export function GroupManagerDialog({ open, onOpenChange, workspaceId }: GroupManagerDialogProps) {
  const convex = useConvex();
  const createGroup = useMutation(api.groups.create);
  const removeGroup = useMutation(api.groups.remove);
  const inviteByUsername = useMutation(api.groupInvitations.inviteByUsername);
  const removeMember = useMutation(api.groupMembers.removeMember);
  const listMyInvitations = useCallback(async () => {
    const resp = await convex.query(api.groupInvitations.listMine, {});
    const rows = Array.isArray(resp) ? (resp as any[]) : [];
    return rows.map((r) => ({
      workspaceId: String(r.workspaceId),
      workspaceName: r.workspaceName ? String(r.workspaceName) : null,
      groupId: String(r.groupId),
      groupName: r.groupName ? String(r.groupName) : null,
      invitedByUserId: String(r.invitedByUserId ?? ""),
      invitedByUsername: r.invitedByUsername ? String(r.invitedByUsername) : null,
      createdAt: String(r.createdAt ?? ""),
      updatedAt: String(r.updatedAt ?? ""),
    }));
  }, [convex]);
  const acceptInvite = useMutation(api.groupInvitations.accept);
  const declineInvite = useMutation(api.groupInvitations.decline);

  const [groups, setGroups] = useState<GroupRow[]>([]);
  const [selectedGroupId, setSelectedGroupId] = useState<string>("");
  const [members, setMembers] = useState<MemberRow[]>([]);
  const [workspaces, setWorkspaces] = useState<Array<{ id: string; name: string; type: string }>>([]);
  const [selectedWorkspaceId, setSelectedWorkspaceId] = useState<string>(workspaceId);
  const [invitations, setInvitations] = useState<
    Array<{
      workspaceId: string;
      workspaceName: string | null;
      groupId: string;
      groupName: string | null;
      invitedByUserId: string;
      invitedByUsername: string | null;
      createdAt: string;
      updatedAt: string;
    }>
  >([]);

  const [newGroupName, setNewGroupName] = useState("");
  const [inviteUsername, setInviteUsername] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const selectedGroup = useMemo(
    () => groups.find((g) => g.id === selectedGroupId) ?? null,
    [groups, selectedGroupId],
  );

  const loadGroups = useCallback(async () => {
    if (!selectedWorkspaceId) return;
    const resp = await convex.query(api.groups.listMineByWorkspace, { workspaceId: selectedWorkspaceId });
    const rows = Array.isArray((resp as any)?.groups) ? ((resp as any).groups as any[]) : [];
    setGroups(
      rows.map((g) => ({
        id: String(g.id),
        name: String(g.name ?? ""),
        created_by: String(g.created_by ?? ""),
        created_at: String(g.created_at ?? ""),
        my_role: g.my_role === "owner" ? "owner" : "member",
      })),
    );
  }, [convex, selectedWorkspaceId]);

  const loadInvitations = useCallback(async () => {
    const rows = await listMyInvitations();
    setInvitations(rows);
  }, [listMyInvitations]);

  const loadMembers = useCallback(async (groupId: string) => {
    if (!groupId) {
      setMembers([]);
      return;
    }
    const resp = await convex.query(api.groupMembers.listByGroup, { groupId });
    const rows = Array.isArray(resp) ? (resp as any[]) : [];
    setMembers(
      rows.map((m) => ({
        userId: String(m.userId),
        username: m.username ? String(m.username) : null,
        role: m.role === "owner" ? "owner" : "member",
        createdAt: String(m.createdAt ?? ""),
      })),
    );
  }, [convex]);

  useEffect(() => {
    if (!open) return;
    setError(null);
    setLoading(true);
    void (async () => {
      try {
        const wsResp = await convex.query(api.workspaces.fetchWorkspaceSummaries, {});
        const wsRows = Array.isArray((wsResp as any)?.workspaces) ? ((wsResp as any).workspaces as any[]) : [];
        const normalized = wsRows.map((w) => ({
          id: String(w.id),
          name: String(w.name ?? ""),
          type: String(w.type ?? ""),
        }));
        setWorkspaces(normalized);

        const desired =
          workspaceId && normalized.some((w) => w.id === workspaceId)
            ? workspaceId
            : typeof (wsResp as any)?.activeWorkspaceId === "string" && (wsResp as any).activeWorkspaceId
              ? String((wsResp as any).activeWorkspaceId)
              : normalized[0]?.id ?? workspaceId;
        setSelectedWorkspaceId(desired);

        await Promise.all([loadInvitations()]);
      } catch (e: any) {
        setError(e?.message ?? "加载群组失败");
      } finally {
        setLoading(false);
      }
    })();
  }, [convex, loadInvitations, open, workspaceId]);

  useEffect(() => {
    if (!open) return;
    if (!selectedWorkspaceId) {
      setGroups([]);
      setSelectedGroupId("");
      setMembers([]);
      return;
    }
    setError(null);
    setLoading(true);
    void (async () => {
      try {
        await loadGroups();
        setSelectedGroupId("");
        setMembers([]);
      } catch (e: any) {
        setError(e?.message ?? "加载群组失败");
      } finally {
        setLoading(false);
      }
    })();
  }, [loadGroups, open, selectedWorkspaceId]);

  useEffect(() => {
    if (!open) return;
    void (async () => {
      try {
        await loadMembers(selectedGroupId);
      } catch (e: any) {
        setError(e?.message ?? "加载群组成员失败");
      }
    })();
  }, [loadMembers, open, selectedGroupId]);

  const handleCreateGroup = async () => {
    setError(null);
    const name = newGroupName.trim();
    if (!name) {
      setError("请输入群组名称");
      return;
    }
    if (!selectedWorkspaceId) {
      setError("请先选择一个工作空间");
      return;
    }
    setLoading(true);
    try {
      await createGroup({ id: uuidv4(), workspaceId: selectedWorkspaceId, name });
      setNewGroupName("");
      await loadGroups();
    } catch (e: any) {
      setError(e?.message ?? "创建群组失败");
    } finally {
      setLoading(false);
    }
  };

  const handleRemoveGroup = async (groupId: string) => {
    if (!groupId) return;
    if (!window.confirm("确认删除该群组吗？")) return;
    setError(null);
    setLoading(true);
    try {
      await removeGroup({ groupId });
      if (selectedGroupId === groupId) {
        setSelectedGroupId("");
        setMembers([]);
      }
      await loadGroups();
    } catch (e: any) {
      setError(e?.message ?? "删除群组失败");
    } finally {
      setLoading(false);
    }
  };

  const handleInvite = async () => {
    if (!selectedGroupId) {
      setError("请先选择一个群组");
      return;
    }
    if (selectedGroup?.my_role !== "owner") {
      setError("只有群主可以邀请成员");
      return;
    }
    setError(null);
    const username = inviteUsername.trim();
    if (!username) {
      setError("请输入用户名");
      return;
    }
    setLoading(true);
    try {
      await inviteByUsername({ groupId: selectedGroupId, username });
      setInviteUsername("");
      await loadInvitations();
    } catch (e: any) {
      setError(e?.message ?? "邀请失败");
    } finally {
      setLoading(false);
    }
  };

  const handleAcceptInvite = async (inv: { groupId: string; workspaceId: string }) => {
    setError(null);
    setLoading(true);
    try {
      await acceptInvite({ groupId: inv.groupId });
      await loadInvitations();
      setSelectedWorkspaceId(inv.workspaceId);
      window.alert("已接受邀请：已加入群组与工作空间。共享页面会出现在左侧「共享页面」面板。");
    } catch (e: any) {
      setError(e?.message ?? "接受邀请失败");
    } finally {
      setLoading(false);
    }
  };

  const handleDeclineInvite = async (groupId: string) => {
    setError(null);
    setLoading(true);
    try {
      await declineInvite({ groupId });
      await loadInvitations();
    } catch (e: any) {
      setError(e?.message ?? "拒绝邀请失败");
    } finally {
      setLoading(false);
    }
  };

  const handleRemoveMember = async (userId: string) => {
    if (!selectedGroupId) return;
    if (!window.confirm("确认移除该成员吗？")) return;
    setError(null);
    setLoading(true);
    try {
      await removeMember({ groupId: selectedGroupId, userId });
      await loadMembers(selectedGroupId);
    } catch (e: any) {
      setError(e?.message ?? "移除成员失败");
    } finally {
      setLoading(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-3xl">
        <DialogHeader>
          <DialogTitle>群组管理</DialogTitle>
        </DialogHeader>

        {error ? (
          <div className="rounded-md bg-red-50 px-3 py-2 text-sm text-red-700">{error}</div>
        ) : null}

        <div className="rounded-md border border-gray-200">
          <div className="border-b border-gray-200 px-3 py-2 text-sm font-medium text-gray-700">工作空间</div>
          <div className="p-3">
            <div className="flex min-w-0 items-center gap-2">
              <select
                className="h-10 min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap rounded-md border border-gray-200 bg-white px-3 text-sm text-gray-700"
                value={selectedWorkspaceId}
                onChange={(e) => setSelectedWorkspaceId(e.target.value)}
                disabled={loading}
              >
                {workspaces.length === 0 ? (
                  <option value={selectedWorkspaceId || ""}>暂无工作空间</option>
                ) : (
                  workspaces.map((w) => (
                    <option key={w.id} value={w.id}>
                      {w.name}（{w.type === "team" ? "团队" : "个人"}）
                    </option>
                  ))
                )}
              </select>
            </div>
            <div className="mt-2 text-xs text-gray-400">
              说明：工作空间切换功能暂时停用；这里的选择仅影响“群组管理”的展示与操作范围。
            </div>
          </div>
        </div>

        <div className="rounded-md border border-gray-200">
          <div className="border-b border-gray-200 px-3 py-2 text-sm font-medium text-gray-700">
            收到的邀请（{invitations.length}）
          </div>
          <div className="p-3">
            {invitations.length === 0 ? (
              <div className="text-sm text-gray-400">暂无邀请</div>
            ) : (
              <div className="space-y-2">
                {invitations.map((inv) => (
                  <div
                    key={`${inv.workspaceId}:${inv.groupId}`}
                    className="flex w-full min-w-0 items-center justify-between gap-2 rounded-md border border-gray-200 px-3 py-2 text-sm"
                  >
                    <div className="min-w-0 flex-1">
                      <div className="truncate">
                        群组：{inv.groupName ?? inv.groupId}
                        <span className="ml-2 text-xs text-gray-400">
                          工作空间：{inv.workspaceName ?? inv.workspaceId}
                        </span>
                      </div>
                      <div className="mt-0.5 text-xs text-gray-400">
                        邀请人：{inv.invitedByUsername ?? inv.invitedByUserId}
                      </div>
                    </div>
                    <div className="flex shrink-0 gap-2">
                      <Button className="h-8" disabled={loading} onClick={() => void handleAcceptInvite({ groupId: inv.groupId, workspaceId: inv.workspaceId })}>
                        接受
                      </Button>
                      <Button
                        variant="outline"
                        className="h-8"
                        disabled={loading}
                        onClick={() => void handleDeclineInvite(inv.groupId)}
                      >
                        拒绝
                      </Button>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>

        <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
          <div className="rounded-md border border-gray-200">
            <div className="border-b border-gray-200 px-3 py-2 text-sm font-medium text-gray-700">群组</div>
            <div className="p-3 space-y-2">
              <div className="flex gap-2">
                <Input
                  value={newGroupName}
                  onChange={(e) => setNewGroupName(e.target.value)}
                  placeholder="新群组名称"
                  disabled={loading}
                />
                <Button onClick={() => void handleCreateGroup()} disabled={loading}>
                  创建
                </Button>
              </div>

              <div className="max-h-60 overflow-auto rounded-md border border-gray-200">
                {groups.length === 0 ? (
                  <div className="px-3 py-3 text-sm text-gray-400">暂无群组</div>
                ) : (
                  (() => {
                    const owned = groups.filter((g) => g.my_role === "owner");
                    const joined = groups.filter((g) => g.my_role !== "owner");
                    const renderGroupRow = (g: GroupRow) => (
                      <div
                        key={g.id}
                        className={`flex items-center justify-between gap-2 px-3 py-2 text-sm hover:bg-gray-50 ${selectedGroupId === g.id ? "bg-blue-50" : ""}`}
                      >
                        <button
                          type="button"
                          className="min-w-0 flex-1 truncate text-left"
                          onClick={() => setSelectedGroupId(g.id)}
                        >
                          {g.name}
                          <span className="ml-2 text-xs text-gray-400">{g.my_role === "owner" ? "群主" : "成员"}</span>
                        </button>
                        {g.my_role === "owner" ? (
                          <Button
                            variant="outline"
                            className="h-8"
                            disabled={loading}
                            onClick={() => void handleRemoveGroup(g.id)}
                          >
                            删除
                          </Button>
                        ) : null}
                      </div>
                    );

                    return (
                      <div className="py-1">
                        <div className="px-3 py-2 text-xs font-medium text-gray-500">我创建的</div>
                        {owned.length === 0 ? (
                          <div className="px-3 pb-2 text-sm text-gray-400">暂无</div>
                        ) : (
                          owned.map(renderGroupRow)
                        )}
                        <div className="px-3 py-2 text-xs font-medium text-gray-500">我加入的</div>
                        {joined.length === 0 ? (
                          <div className="px-3 pb-2 text-sm text-gray-400">暂无</div>
                        ) : (
                          joined.map(renderGroupRow)
                        )}
                      </div>
                    );
                  })()
                )}
              </div>
            </div>
          </div>

          <div className="rounded-md border border-gray-200">
            <div className="border-b border-gray-200 px-3 py-2 text-sm font-medium text-gray-700">
              成员{selectedGroup ? `：${selectedGroup.name}` : ""}
            </div>
            <div className="p-3 space-y-2">
              <div className="flex gap-2">
                <Input
                  value={inviteUsername}
                  onChange={(e) => setInviteUsername(e.target.value)}
                  placeholder="输入用户名邀请"
                  disabled={loading || !selectedGroupId || selectedGroup?.my_role !== "owner"}
                />
                <Button onClick={() => void handleInvite()} disabled={loading}>
                  邀请
                </Button>
              </div>
              {selectedGroupId && selectedGroup?.my_role !== "owner" ? (
                <div className="text-xs text-gray-400">提示：只有群主可以邀请成员</div>
              ) : null}

              <div className="max-h-60 overflow-auto rounded-md border border-gray-200">
                {!selectedGroupId ? (
                  <div className="px-3 py-3 text-sm text-gray-400">请先选择一个群组</div>
                ) : members.length === 0 ? (
                  <div className="px-3 py-3 text-sm text-gray-400">暂无成员</div>
                ) : (
                  members.map((m) => (
                    <div
                      key={m.userId}
                      className="flex items-center justify-between gap-2 px-3 py-2 text-sm hover:bg-gray-50"
                    >
                      <div className="min-w-0 flex-1 truncate">
                        {m.username ?? m.userId}
                        <span className="ml-2 text-xs text-gray-400">
                          {m.role === "owner" ? "群主" : "成员"}
                        </span>
                      </div>
                      {m.role !== "owner" ? (
                        <Button
                          variant="outline"
                          className="h-8"
                          disabled={loading}
                          onClick={() => void handleRemoveMember(m.userId)}
                        >
                          移除
                        </Button>
                      ) : null}
                    </div>
                  ))
                )}
              </div>
            </div>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={loading}>
            关闭
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
