import { useMutation, useQuery } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
  ChevronDown,
  ChevronRight,
  Plus,
  RefreshCw,
  Shield,
  Trash2,
  UserMinus,
  UserPlus,
  Users,
} from "lucide-react";
import type React from "react";
import { useState } from "react";
import { useParams } from "react-router-dom";
import { toast } from "sonner";
import { Badge } from "../../../components/ui/badge";
import { Button } from "../../../components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "../../../components/ui/card";
import { Input } from "../../../components/ui/input";
import { Label } from "../../../components/ui/label";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "../../../components/ui/table";
import {
  type GroupSummary,
  addGroupMember,
  createGroup,
  deleteGroup,
  fetchGroups,
  removeGroupMember,
} from "../../../lib/adminApi";
import { t } from "../../../lib/i18n";

type UserGroupNode = GroupSummary & { children: UserGroupNode[] };

function buildGroupTree(groups: GroupSummary[]): UserGroupNode[] {
  const nodeMap = new Map<string, UserGroupNode>();
  const rootNodes: UserGroupNode[] = [];

  for (const group of groups) {
    nodeMap.set(group.id, { ...group, children: [] });
  }

  for (const group of groups) {
    const node = nodeMap.get(group.id);
    if (!node) continue;

    if (group.parentId && nodeMap.has(group.parentId)) {
      const parent = nodeMap.get(group.parentId);
      if (parent) {
        parent.children.push(node);
      }
    } else {
      rootNodes.push(node);
    }
  }

  const sortNodes = (nodes: UserGroupNode[]) => {
    nodes.sort((a, b) => a.name.localeCompare(b.name));
    for (const node of nodes) {
      sortNodes(node.children);
    }
  };
  sortNodes(rootNodes);

  return rootNodes;
}

interface UserGroupTreeNodeProps {
  node: UserGroupNode;
  level: number;
  onSelect: (groupId: string) => void;
  selectedGroupId: string | null;
  onDelete: (groupId: string, groupName: string) => void;
  onAddSubGroup: (parentId: string) => void;
}

const UserGroupTreeNode: React.FC<UserGroupTreeNodeProps> = ({
  node,
  level,
  onSelect,
  selectedGroupId,
  onDelete,
  onAddSubGroup,
}) => {
  const [isExpanded, setIsExpanded] = useState(true);
  const hasChildren = node.children && node.children.length > 0;

  return (
    <>
      <TableRow
        key={node.id}
        className={`cursor-pointer transition-colors hover:bg-muted/50 ${
          selectedGroupId === node.id ? "bg-primary/5" : ""
        }`}
        onClick={() => onSelect(node.id)}
      >
        <TableCell style={{ paddingLeft: `${1 + level * 2}rem` }}>
          <div className="flex items-center gap-2">
            {hasChildren && (
              <Button
                variant="ghost"
                size="icon"
                className="h-6 w-6"
                onClick={(e) => {
                  e.stopPropagation();
                  setIsExpanded(!isExpanded);
                }}
              >
                {isExpanded ? (
                  <ChevronDown size={16} />
                ) : (
                  <ChevronRight size={16} />
                )}
              </Button>
            )}
            {!hasChildren && <div className="w-6" />}
            <Users size={14} className="text-muted-foreground" />
            <span className="font-semibold">{node.name}</span>
            <Badge variant="outline" className="text-xs">
              {node.unitType || "Team"}
            </Badge>
          </div>
        </TableCell>
        <TableCell className="text-center">
          <Badge variant="secondary">{node.members?.length || 0}</Badge>
        </TableCell>
        <TableCell className="text-right">
          <Button
            variant="ghost"
            size="sm"
            onClick={(e) => {
              e.stopPropagation();
              onAddSubGroup(node.id);
            }}
          >
            <Plus size={14} className="mr-1" />
            {t("ui.admin.groups.add_unit", "하위 조직 추가")}
          </Button>
          <Button
            variant="ghost"
            size="sm"
            onClick={(e) => {
              e.stopPropagation();
              onDelete(node.id, node.name);
            }}
          >
            <Trash2 size={14} className="text-destructive" />
          </Button>
        </TableCell>
      </TableRow>
      {isExpanded &&
        hasChildren &&
        node.children.map((child) => (
          <UserGroupTreeNode
            key={child.id}
            node={child}
            level={level + 1}
            onSelect={onSelect}
            selectedGroupId={selectedGroupId}
            onDelete={onDelete}
            onAddSubGroup={onAddSubGroup}
          />
        ))}
    </>
  );
};

export function TenantUserGroupsTab() {
  const params = useParams<{ tenantId: string }>();
  const tenantId = params.tenantId ?? "";

  const [newGroupName, setNewGroupName] = useState("");
  const [newGroupDesc, setNewGroupNameDesc] = useState("");
  const [newGroupUnitType, setNewGroupUnitType] = useState("Team");
  const [newGroupParentId, setNewGroupParentId] = useState<string | null>(null);

  const [selectedGroupId, setSelectedGroupId] = useState<string | null>(null);

  const groupsQuery = useQuery({
    queryKey: ["groups", tenantId],
    queryFn: () => fetchGroups(tenantId),
    enabled: !!tenantId,
  });

  const createMutation = useMutation({
    mutationFn: () =>
      createGroup(tenantId, {
        name: newGroupName,
        description: newGroupDesc,
        unitType: newGroupUnitType,
        parentId: newGroupParentId || undefined,
      }),
    onSuccess: () => {
      toast.success(
        t(
          "msg.admin.groups.list.create_success",
          "그룹이 성공적으로 생성되었습니다.",
        ),
      );
      groupsQuery.refetch();
      setNewGroupName("");
      setNewGroupNameDesc("");
      setNewGroupUnitType("Team");
      setNewGroupParentId(null);
    },
    onError: (error: AxiosError<{ error?: string }>) => {
      toast.error(t("msg.admin.groups.list.create_error", "그룹 생성 실패"), {
        description: error.response?.data?.error || error.message,
      });
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => deleteGroup(tenantId, id),
    onSuccess: () => {
      toast.success(
        t("msg.admin.groups.list.delete_success", "그룹이 삭제되었습니다."),
      );
      groupsQuery.refetch();
      if (
        selectedGroupId &&
        selectedGroupId === deleteMutation.variables
      ) {
        setSelectedGroupId(null);
      }
    },
    onError: (error: AxiosError<{ error?: string }>) => {
      toast.error(t("msg.common.error", "그룹 삭제 실패"), {
        description: error.response?.data?.error || error.message,
      });
    },
  });

  const addMemberMutation = useMutation({
    mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) =>
      addGroupMember(tenantId, groupId, userId),
    onSuccess: () => {
      toast.success(
        t("msg.admin.groups.members.add_success", "멤버가 추가되었습니다."),
      );
      groupsQuery.refetch();
    },
    onError: (error: AxiosError<{ error?: string }>) => {
      toast.error(t("msg.common.error", "오류 발생"), {
        description: error.response?.data?.error || error.message,
      });
    },
  });

  const removeMemberMutation = useMutation({
    mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) =>
      removeGroupMember(tenantId, groupId, userId),
    onSuccess: () => {
      toast.success(
        t("msg.admin.groups.members.remove_success", "멤버가 제거되었습니다."),
      );
      groupsQuery.refetch();
    },
    onError: (error: AxiosError<{ error?: string }>) => {
      toast.error(t("msg.common.error", "오류 발생"), {
        description: error.response?.data?.error || error.message,
      });
    },
  });

  const groupTree = groupsQuery.data ? buildGroupTree(groupsQuery.data) : [];

  const handleAddSubGroup = (parentId: string) => {
    setNewGroupParentId(parentId);
  };

  const handleDeleteGroup = (groupId: string, groupName: string) => {
    if (
      window.confirm(
        t(
          "msg.admin.groups.list.delete_confirm",
          `그룹 "{{name}}"을(를) 삭제하시겠습니까?`,
          { name: groupName },
        ),
      )
    ) {
      deleteMutation.mutate(groupId);
    }
  };

  const handleAddMember = (groupId: string) => {
    const userId = window.prompt(
      t(
        "msg.admin.groups.prompt.user_id",
        "추가할 사용자의 UUID를 입력하세요:",
      ),
    );
    if (userId) {
      addMemberMutation.mutate({ groupId, userId });
    }
  };

  const currentGroup = groupsQuery.data?.find((g) => g.id === selectedGroupId);

  return (
    <div className="space-y-6 mt-6">
      <div className="grid gap-6 md:grid-cols-3">
        <Card className="bg-[var(--color-panel)] md:col-span-1 border-primary/20">
          <CardHeader>
            <CardTitle className="text-lg flex items-center gap-2">
              <Plus size={18} />{" "}
              {t("ui.admin.groups.create.title", "새 그룹 생성")}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-1">
              <Label htmlFor="name">
                {t("ui.admin.groups.form.name_label", "그룹 이름")}
              </Label>
              <Input
                id="name"
                value={newGroupName}
                onChange={(e) => setNewGroupName(e.target.value)}
              />
            </div>
            <div className="space-y-1">
              <Label htmlFor="unitType">
                {t("ui.admin.groups.form.unit_level_label", "조직 단위 레벨")}
              </Label>
              <Input
                id="unitType"
                value={newGroupUnitType}
                onChange={(e) => setNewGroupUnitType(e.target.value)}
              />
            </div>
            <div className="space-y-1">
              <Label htmlFor="parentId">
                {t("ui.admin.groups.form.parent_label", "상위 그룹 (선택)")}
              </Label>
              <select
                id="parentId"
                className="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm"
                value={newGroupParentId || ""}
                onChange={(e) => setNewGroupParentId(e.target.value || null)}
              >
                <option value="">
                  {t("ui.admin.groups.form.parent_none", "없음 (최상위)")}
                </option>
                {groupsQuery.data?.map((group) => (
                  <option key={group.id} value={group.id}>
                    {group.name}
                  </option>
                ))}
              </select>
            </div>
            <div className="space-y-1">
              <Label htmlFor="desc">
                {t("ui.admin.groups.form.desc_label", "설명")}
              </Label>
              <Input
                id="desc"
                value={newGroupDesc}
                onChange={(e) => setNewGroupNameDesc(e.target.value)}
              />
            </div>
            <Button
              className="w-full"
              onClick={() => createMutation.mutate()}
              disabled={!newGroupName || createMutation.isPending}
            >
              {t("ui.admin.groups.form.submit", "생성하기")}
            </Button>
          </CardContent>
        </Card>

        <Card className="bg-[var(--color-panel)] md:col-span-2">
          <CardHeader className="flex flex-row items-center justify-between">
            <div>
              <CardTitle>
                {t("ui.admin.groups.list.title", "User Groups")}
              </CardTitle>
              <CardDescription>
                {t(
                  "msg.admin.groups.list.subtitle",
                  "이 테넌트에 정의된 사용자 그룹 목록입니다.",
                )}
              </CardDescription>
            </div>
            <Button
              variant="ghost"
              size="sm"
              onClick={() => groupsQuery.refetch()}
            >
              <RefreshCw size={14} />
            </Button>
          </CardHeader>
          <CardContent>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>
                    {t("ui.admin.groups.table.name", "NAME")}
                  </TableHead>
                  <TableHead className="text-center">
                    {t("ui.admin.groups.table.members", "MEMBERS")}
                  </TableHead>
                  <TableHead className="text-right">
                    {t("ui.admin.groups.table.actions", "ACTIONS")}
                  </TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {groupsQuery.isLoading && (
                  <TableRow>
                    <TableCell colSpan={3}>
                      {t("msg.admin.groups.list.loading", "로딩 중...")}
                    </TableCell>
                  </TableRow>
                )}
                {!groupsQuery.isLoading && groupTree.length === 0 && (
                  <TableRow>
                    <TableCell
                      colSpan={3}
                      className="text-center py-8 text-muted-foreground"
                    >
                      {t(
                        "msg.admin.groups.list.empty",
                        "아직 등록된 그룹이 없습니다.",
                      )}
                    </TableCell>
                  </TableRow>
                )}
                {groupTree.map((node) => (
                  <UserGroupTreeNode
                    key={node.id}
                    node={node}
                    level={0}
                    onSelect={setSelectedGroupId}
                    selectedGroupId={selectedGroupId}
                    onDelete={handleDeleteGroup}
                    onAddSubGroup={handleAddSubGroup}
                  />
                ))}
              </TableBody>
            </Table>
          </CardContent>
        </Card>
      </div>

      {currentGroup && (
        <Card className="bg-[var(--color-panel)] border-t-4 border-t-primary">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Shield size={18} className="text-primary" />{" "}
              {t("msg.admin.groups.members.title", "[{{name}}] 멤버 관리", {
                name: currentGroup.name,
              })}
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="flex justify-end mb-4">
              <Button
                size="sm"
                onClick={() => handleAddMember(currentGroup.id)}
                disabled={addMemberMutation.isPending}
              >
                <UserPlus size={14} className="mr-1" />{" "}
                {t("ui.common.add", "멤버 추가")}
              </Button>
            </div>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>
                    {t("ui.admin.groups.members.table.name", "이름")}
                  </TableHead>
                  <TableHead>
                    {t("ui.admin.groups.members.table.email", "이메일")}
                  </TableHead>
                  <TableHead className="text-right">
                    {t("ui.admin.groups.members.table.remove", "제거")}
                  </TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {currentGroup.members?.length === 0 && (
                  <TableRow>
                    <TableCell
                      colSpan={3}
                      className="text-center py-4 text-muted-foreground"
                    >
                      {t("msg.admin.groups.members.empty", "멤버가 없습니다.")}
                    </TableCell>
                  </TableRow>
                )}
                {currentGroup.members?.map((user) => (
                  <TableRow key={user.id}>
                    <TableCell className="font-medium">{user.name}</TableCell>
                    <TableCell className="text-muted-foreground">
                      {user.email}
                    </TableCell>
                    <TableCell className="text-right">
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() =>
                          removeMemberMutation.mutate({
                            groupId: currentGroup.id,
                            userId: user.id,
                          })
                        }
                        disabled={removeMemberMutation.isPending}
                      >
                        <UserMinus size={14} className="text-destructive" />
                      </Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </CardContent>
        </Card>
      )}
    </div>
  );
}

export default TenantUserGroupsTab;
