import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { AlertTriangle, FolderTree, Loader2, Search } from "lucide-react";
import * as React from "react";
import { Button } from "../../../components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "../../../components/ui/dialog";
import { Input } from "../../../components/ui/input";
import { ScrollArea } from "../../../components/ui/scroll-area";
import { toast } from "../../../components/ui/use-toast";
import {
  bulkUpdateUsers,
  fetchAllTenants,
  fetchGroups,
  type UserSummary,
} from "../../../lib/adminApi";
import { t } from "../../../lib/i18n";

type UserSchemaField = {
  key: string;
  label: string;
  required?: boolean;
};

interface UserBulkMoveGroupModalProps {
  userIds: string[];
  selectedUsers?: UserSummary[];
  onSuccess?: () => void;
}

export function UserBulkMoveGroupModal({
  userIds,
  selectedUsers = [],
  onSuccess,
}: UserBulkMoveGroupModalProps) {
  const [open, setOpen] = React.useState(false);
  const [selectedTenantSlug, setSelectedTenantSlug] =
    React.useState<string>("");
  const [selectedGroupName, setSelectedGroupName] = React.useState<string>("");
  const [searchTerm, setSearchTerm] = React.useState("");
  const [acknowledgeWarning, setAcknowledgeWarning] = React.useState(false);

  const _queryClient = useQueryClient();

  const { data: tenantsData } = useQuery({
    queryKey: ["tenants", "all"],
    queryFn: () => fetchAllTenants(),
    enabled: open,
  });
  const tenants = tenantsData?.items ?? [];

  const selectedTenant = React.useMemo(
    () => tenants.find((t) => t.slug === selectedTenantSlug),
    [tenants, selectedTenantSlug],
  );
  const selectedTenantId = selectedTenant?.id ?? "";

  const { data: groups, isLoading: isGroupsLoading } = useQuery({
    queryKey: ["tenant-groups", selectedTenantId],
    queryFn: () => fetchGroups(selectedTenantId),
    enabled: open && !!selectedTenantId,
  });

  const schemaWarnings = React.useMemo(() => {
    if (!selectedTenant || selectedUsers.length === 0) return null;

    const targetSchema =
      (selectedTenant.config?.userSchema as UserSchemaField[]) || [];
    const targetSchemaKeys = new Set(targetSchema.map((f) => f.key));
    const requiredKeys = targetSchema
      .filter((f) => f.required)
      .map((f) => f.key);

    const missingRequiredFields = new Set<string>();
    const incompatibleFields = new Set<string>();

    for (const user of selectedUsers) {
      const userMeta = user.metadata || {};

      // 1. Check for missing required fields
      for (const key of requiredKeys) {
        if (
          userMeta[key] === undefined ||
          userMeta[key] === null ||
          userMeta[key] === ""
        ) {
          missingRequiredFields.add(key);
        }
      }

      // 2. Check for fields that exist in user metadata but not in the target schema (data loss)
      for (const key of Object.keys(userMeta)) {
        if (!targetSchemaKeys.has(key)) {
          incompatibleFields.add(key);
        }
      }
    }

    if (missingRequiredFields.size === 0 && incompatibleFields.size === 0) {
      return null;
    }

    return {
      missing: Array.from(missingRequiredFields),
      incompatible: Array.from(incompatibleFields),
    };
  }, [selectedTenant, selectedUsers]);

  const mutation = useMutation({
    mutationFn: bulkUpdateUsers,
    onSuccess: () => {
      toast.success(
        t(
          "msg.admin.users.bulk.move_success",
          "사용자들의 부서가 이동되었습니다.",
        ),
      );
      setOpen(false);
      onSuccess?.();
    },
    onError: (error: AxiosError<{ error?: string }>) => {
      toast.error(t("msg.admin.users.bulk.move_error", "부서 이동 실패"), {
        description: error.response?.data?.error || error.message,
      });
    },
  });

  const handleMove = () => {
    if (!selectedTenantSlug) return;
    mutation.mutate({
      userIds,
      tenantSlug: selectedTenantSlug,
      department: selectedGroupName, // can be empty for "No Department"
    });
  };

  const filteredGroups = React.useMemo(() => {
    if (!groups) return [];
    if (!searchTerm) return groups;
    return groups.filter((g) =>
      g.name.toLowerCase().includes(searchTerm.toLowerCase()),
    );
  }, [groups, searchTerm]);

  return (
    <Dialog
      open={open}
      onOpenChange={(val) => {
        setOpen(val);
        if (!val) {
          setSelectedTenantSlug("");
          setSelectedGroupName("");
          setAcknowledgeWarning(false);
          setSearchTerm("");
        }
      }}
    >
      <DialogTrigger asChild>
        <Button
          variant="ghost"
          size="sm"
          className="text-background hover:bg-background/10 h-8"
        >
          {t("ui.admin.users.bulk.move_group", "부서 이동")}
        </Button>
      </DialogTrigger>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>
            {t("ui.admin.users.bulk.move_title", "사용자 부서 이동")}
          </DialogTitle>
          <DialogDescription>
            {t(
              "msg.admin.users.bulk.move_description",
              "선택한 {{count}}명의 사용자를 이동할 테넌트와 부서를 선택하세요.",
              { count: userIds.length },
            )}
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-4">
          <div className="space-y-2">
            <label className="text-sm font-medium">
              {t("ui.admin.users.create.form.tenant", "테넌트 선택")}
            </label>
            <select
              id="bulk-move-target-tenant"
              name="bulk-move-target-tenant"
              className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
              value={selectedTenantSlug}
              onChange={(e) => {
                setSelectedTenantSlug(e.target.value);
                setSelectedGroupName("");
                setAcknowledgeWarning(false);
              }}
            >
              <option value="">{t("ui.common.select", "선택하세요...")}</option>
              {tenants.map((t) => (
                <option key={t.id} value={t.slug}>
                  {t.name} ({t.slug})
                </option>
              ))}
            </select>
          </div>

          {selectedTenantSlug && (
            <div className="space-y-2">
              <label className="text-sm font-medium">
                {t("ui.admin.users.bulk.select_group", "부서 선택")}
              </label>
              <div className="relative">
                <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
                <Input
                  placeholder={t("ui.common.search", "검색...")}
                  className="pl-9 h-9"
                  value={searchTerm}
                  onChange={(e) => setSearchTerm(e.target.value)}
                />
              </div>
              <ScrollArea className="h-[200px] rounded-md border p-2">
                <div className="space-y-1">
                  <button
                    type="button"
                    onClick={() => setSelectedGroupName("")}
                    className={`flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm transition ${
                      selectedGroupName === ""
                        ? "bg-primary text-primary-foreground"
                        : "hover:bg-muted"
                    }`}
                  >
                    <FolderTree size={14} />
                    {t("ui.admin.users.bulk.no_department", "(부서 없음)")}
                  </button>
                  {isGroupsLoading ? (
                    <div className="flex justify-center py-4">
                      <Loader2 className="animate-spin text-muted-foreground" />
                    </div>
                  ) : (
                    filteredGroups.map((group) => (
                      <button
                        key={group.id}
                        type="button"
                        onClick={() => setSelectedGroupName(group.name)}
                        className={`flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm transition ${
                          selectedGroupName === group.name
                            ? "bg-primary text-primary-foreground"
                            : "hover:bg-muted"
                        }`}
                      >
                        <FolderTree size={14} />
                        {group.name}
                      </button>
                    ))
                  )}
                </div>
              </ScrollArea>
            </div>
          )}

          {schemaWarnings && (
            <div className="rounded-lg border border-destructive/20 bg-destructive/10 p-3 space-y-2 mt-4 text-sm">
              <div className="flex items-center gap-2 text-destructive font-semibold">
                <AlertTriangle size={16} />
                {t("ui.admin.users.bulk.schema_warning", "스키마 호환성 경고")}
              </div>
              <div className="text-destructive/80 text-xs">
                {schemaWarnings.missing.length > 0 && (
                  <p>
                    {t(
                      "msg.admin.users.bulk.schema_missing",
                      "대상 테넌트의 필수 필드가 누락되어 있습니다:",
                    )}{" "}
                    <strong>{schemaWarnings.missing.join(", ")}</strong>
                  </p>
                )}
                {schemaWarnings.incompatible.length > 0 && (
                  <p>
                    {t(
                      "msg.admin.users.bulk.schema_incompatible",
                      "대상 테넌트 스키마에 없는 필드는 유실될 수 있습니다:",
                    )}{" "}
                    <strong>{schemaWarnings.incompatible.join(", ")}</strong>
                  </p>
                )}
              </div>
              <label className="flex items-center gap-2 cursor-pointer mt-2 pt-2 border-t border-destructive/10">
                <input
                  id="bulk-move-acknowledge-warning"
                  name="bulk-move-acknowledge-warning"
                  type="checkbox"
                  checked={acknowledgeWarning}
                  onChange={(e) => setAcknowledgeWarning(e.target.checked)}
                  className="w-4 h-4 rounded border-gray-300 text-destructive focus:ring-destructive"
                />
                <span className="font-medium text-destructive/90">
                  {t(
                    "ui.admin.users.bulk.acknowledge_warning",
                    "경고를 확인했으며 계속 진행합니다.",
                  )}
                </span>
              </label>
            </div>
          )}
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => setOpen(false)}>
            {t("ui.common.cancel", "취소")}
          </Button>
          <Button
            onClick={handleMove}
            disabled={
              !selectedTenantSlug ||
              mutation.isPending ||
              (!!schemaWarnings && !acknowledgeWarning)
            }
          >
            {mutation.isPending && (
              <Loader2 size={16} className="mr-2 animate-spin" />
            )}
            {t("ui.admin.users.bulk.do_move", "이동 실행")}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
