import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { ArrowLeft, ClipboardCopy, Loader2, Save } from "lucide-react";
import * as React from "react";
import { useForm } from "react-hook-form";
import { Link, useNavigate } from "react-router-dom";
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 {
  type UserCreateRequest,
  type UserCreateResponse,
  createUser,
  fetchTenant,
  fetchTenants,
  fetchMe,
} from "../../lib/adminApi";
import { t } from "../../lib/i18n";

type UserSchemaField = {
  key: string;
  label?: string;
  type?: "text" | "number" | "boolean" | "date";
  required?: boolean;
  adminOnly?: boolean;
  validation?: string;
};

type UserFormValues = UserCreateRequest & { metadata: Record<string, unknown> };

function UserCreatePage() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [error, setError] = React.useState<string | null>(null);
  const [generatedPassword, setGeneratedPassword] = React.useState<
    string | null
  >(null);
  const [createdEmail, setCreatedEmail] = React.useState<string | null>(null);
  const [autoPassword, setAutoPassword] = React.useState(true);

  const { data: tenantsData } = useQuery({
    queryKey: ["tenants", { limit: 100 }],
    queryFn: () => fetchTenants(100, 0),
  });
  const tenants = tenantsData?.items ?? [];

  const { data: profile } = useQuery({
    queryKey: ["me"],
    queryFn: fetchMe,
  });

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    formState: { errors },
  } = useForm<UserFormValues>({
    defaultValues: {
      email: "",
      password: "",
      name: "",
      phone: "",
      role: "user",
      companyCode: "",
      department: "",
      position: "",
      jobTitle: "",
      metadata: {},
    },
  });

  // Lock company for tenant_admin
  React.useEffect(() => {
    const p = profile as any;
    if (p?.role === "tenant_admin" && p.companyCode) {
      setValue("companyCode", p.companyCode);
    }
  }, [profile, setValue]);

  const selectedCompanyCode = watch("companyCode");
  const selectedTenant = tenants.find((t) => t.slug === selectedCompanyCode);

  const selectedTenantId = selectedTenant?.id ?? "";

  const { data: tenantDetail } = useQuery({
    queryKey: ["tenant", selectedTenantId],
    queryFn: () => fetchTenant(selectedTenantId),
    enabled: selectedTenantId.length > 0,
  });

  const userSchema: UserSchemaField[] = Array.isArray(
    tenantDetail?.config?.userSchema,
  )
    ? (tenantDetail?.config?.userSchema as UserSchemaField[])
    : [];

  const registerMetadata = (field: UserSchemaField) =>
    register(`metadata.${field.key}` as `metadata.${string}`, {
      required: field.required
        ? t(
            "msg.admin.users.create.form.field_required",
            "{{label}}은(는) 필수입니다.",
            {
              label: field.label || field.key,
            },
          )
        : false,
      pattern: field.validation
        ? {
            value: new RegExp(field.validation),
            message: t(
              "msg.admin.users.create.form.field_invalid",
              "{{label}} 형식이 올바르지 않습니다.",
              { label: field.label || field.key },
            ),
          }
        : undefined,
    });

  const mutation = useMutation({
    mutationFn: createUser,
    onSuccess: (data: UserCreateResponse) => {
      queryClient.invalidateQueries({ queryKey: ["users"] });
      if (data.initialPassword) {
        setGeneratedPassword(data.initialPassword);
        setCreatedEmail(data.email);
        return;
      }
      navigate("/users");
    },
    onError: (err: AxiosError<{ error?: string }>) => {
      setError(
        err.response?.data?.error ||
          t("msg.admin.users.create.error", "사용자 생성에 실패했습니다."),
      );
    },
  });

  const onSubmit = (data: UserFormValues) => {
    setError(null);
    setGeneratedPassword(null);
    setCreatedEmail(null);

    const payload = { ...data };

    if (autoPassword) {
      payload.password = "";
    } else if (!data.password) {
      setError(
        t(
          "msg.admin.users.create.password_required",
          "비밀번호를 입력하거나 자동 생성을 사용해 주세요.",
        ),
      );
      return;
    }

    mutation.mutate(payload);
  };

  const onCopyPassword = async () => {
    if (!generatedPassword) return;
    try {
      await navigator.clipboard.writeText(generatedPassword);
    } catch (_) {
      // ignore
    }
  };

  return (
    <div className="max-w-3xl space-y-8">
      <header className="flex flex-wrap items-center justify-between gap-4">
        <div className="space-y-2">
          <h2 className="text-3xl font-semibold">
            {t("ui.admin.users.create.title", "사용자 추가")}
          </h2>
        </div>
        <Button variant="ghost" asChild>
          <Link to="/users">
            <ArrowLeft size={16} className="mr-2" />
            {t("ui.admin.users.create.back", "목록으로 돌아가기")}
          </Link>
        </Button>
      </header>

      {generatedPassword && (
        <Card>
          <CardHeader>
            <CardTitle>
              {t(
                "ui.admin.users.create.password_generated.title",
                "초기 비밀번호 생성 완료",
              )}
            </CardTitle>
            <CardDescription>
              {createdEmail
                ? t(
                    "msg.admin.users.create.password_generated.with_email",
                    "{{email}} 계정의 초기 비밀번호입니다.",
                    { email: createdEmail },
                  )
                : t(
                    "msg.admin.users.create.password_generated.default",
                    "초기 비밀번호가 생성되었습니다.",
                  )}
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="flex flex-wrap items-center gap-3 rounded-md border border-dashed px-4 py-3">
              <span className="font-mono text-sm">{generatedPassword}</span>
              <Button size="sm" variant="outline" onClick={onCopyPassword}>
                <ClipboardCopy className="mr-2 h-4 w-4" />
                {t("ui.common.copy", "복사")}
              </Button>
            </div>
            <div className="flex justify-end">
              <Button onClick={() => navigate("/users")}>
                {t("ui.admin.users.create.go_list", "목록으로 이동")}
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      <Card>
        <CardHeader>
          <CardTitle>
            {t("ui.admin.users.create.account.title", "계정 정보")}
          </CardTitle>
          <CardDescription>
            {t(
              "msg.admin.users.create.account.subtitle",
              "새로운 사용자를 시스템에 등록합니다.",
            )}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
            {error && (
              <div className="rounded-md bg-destructive/15 p-3 text-sm text-destructive">
                {error}
              </div>
            )}

            <div className="space-y-2">
              <Label htmlFor="email">
                {t("ui.admin.users.create.form.email", "이메일")}
              </Label>
              <Input
                id="email"
                placeholder={t(
                  "ui.admin.users.create.form.email_placeholder",
                  "user@example.com",
                )}
                {...register("email", {
                  required: t(
                    "msg.admin.users.create.form.email_required",
                    "이메일은 필수입니다.",
                  ),
                })}
              />
              {errors.email && (
                <p className="text-xs text-destructive">
                  {errors.email.message}
                </p>
              )}
            </div>

            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label htmlFor="password">
                  {t("ui.admin.users.create.form.password", "비밀번호")}
                </Label>
                <label className="flex items-center gap-2 text-xs text-muted-foreground">
                  <input
                    type="checkbox"
                    checked={autoPassword}
                    onChange={(event) => setAutoPassword(event.target.checked)}
                  />
                  {t("ui.admin.users.create.form.auto_password", "자동 생성")}
                </label>
              </div>
              <Input
                id="password"
                type="password"
                placeholder={t(
                  "ui.admin.users.create.form.password_placeholder",
                  "********",
                )}
                disabled={autoPassword}
                {...register("password")}
              />
              <p className="text-xs text-muted-foreground">
                {autoPassword
                  ? t(
                      "msg.admin.users.create.form.password_auto_help",
                      "비워두면 시스템이 초기 비밀번호를 자동 생성합니다.",
                    )
                  : t(
                      "msg.admin.users.create.form.password_manual_help",
                      "초기 비밀번호를 직접 설정합니다.",
                    )}
              </p>
            </div>

            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="name">
                  {t("ui.admin.users.create.form.name", "이름")}
                </Label>
                <Input
                  id="name"
                  placeholder={t(
                    "ui.admin.users.create.form.name_placeholder",
                    "홍길동",
                  )}
                  {...register("name", {
                    required: t(
                      "msg.admin.users.create.form.name_required",
                      "이름은 필수입니다.",
                    ),
                  })}
                />
                {errors.name && (
                  <p className="text-xs text-destructive">
                    {errors.name.message}
                  </p>
                )}
              </div>

              <div className="space-y-2">
                <Label htmlFor="phone">
                  {t("ui.admin.users.create.form.phone", "전화번호")}
                </Label>
                <Input
                  id="phone"
                  placeholder={t(
                    "ui.admin.users.create.form.phone_placeholder",
                    "010-1234-5678",
                  )}
                  {...register("phone")}
                />
              </div>
            </div>

            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="companyCode">
                  {t("ui.admin.users.create.form.tenant", "테넌트 (Tenant)")}
                </Label>

                <div className="relative">
                  <select
                    id="companyCode"
                    className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
                    {...register("companyCode")}
                    disabled={(profile as any)?.role === "tenant_admin"}
                  >
                    <option value="">
                      {t(
                        "ui.admin.users.create.form.tenant_global",
                        "시스템 전역 (소속 없음)",
                      )}
                    </option>

                    {tenants.map((t) => (
                      <option key={t.id} value={t.slug}>
                        {t.name} ({t.slug})
                      </option>
                    ))}
                  </select>
                </div>
              </div>

              <div className="space-y-2">
                <Label htmlFor="department">
                  {t("ui.admin.users.create.form.department", "부서")}
                </Label>

                <Input
                  id="department"
                  placeholder={t(
                    "ui.admin.users.create.form.department_placeholder",
                    "개발팀",
                  )}
                  {...register("department")}
                />
              </div>
            </div>

            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="position">
                  {t("ui.admin.users.create.form.position", "직급")}
                </Label>

                <Input
                  id="position"
                  placeholder={t(
                    "ui.admin.users.create.form.position_placeholder",
                    "수석/책임/선임",
                  )}
                  {...register("position")}
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="jobTitle">
                  {t("ui.admin.users.create.form.job_title", "직무")}
                </Label>

                <Input
                  id="jobTitle"
                  placeholder={t(
                    "ui.admin.users.create.form.job_title_placeholder",
                    "프론트엔드 개발",
                  )}
                  {...register("jobTitle")}
                />
              </div>
            </div>

            {userSchema.length > 0 && (
              <div className="border-t pt-4">
                <h3 className="mb-4 text-sm font-medium text-muted-foreground">
                  {t(
                    "ui.admin.users.create.custom_fields.title",
                    "테넌트 확장 정보 (Custom Fields)",
                  )}
                </h3>

                <div className="grid gap-4 md:grid-cols-2">
                  {userSchema.map((field) => (
                    <div key={field.key} className="space-y-2">
                      <Label htmlFor={`metadata.${field.key}`}>
                        {field.label}
                        {field.required && (
                          <span className="ml-1 text-destructive">*</span>
                        )}
                        {field.adminOnly && (
                          <span className="ml-2 text-[10px] bg-blue-500/10 text-blue-500 px-1.5 py-0.5 rounded uppercase font-bold tracking-tighter">
                            Admin Only
                          </span>
                        )}
                      </Label>

                      <Input
                        id={`metadata.${field.key}`}
                        type={
                          field.type === "number"
                            ? "number"
                            : field.type === "date"
                              ? "date"
                              : field.type === "boolean"
                                ? "checkbox"
                                : "text"
                        }
                        className={
                          field.type === "boolean" ? "w-auto h-auto" : ""
                        }
                        {...registerMetadata(field)}
                      />
                      {errors.metadata?.[field.key] && (
                        <p className="text-xs text-destructive">
                          {
                            (errors.metadata[field.key] as { message?: string })
                              ?.message
                          }
                        </p>
                      )}
                    </div>
                  ))}
                </div>
              </div>
            )}

            <div className="space-y-2">
              <Label htmlFor="role">
                {t("ui.admin.users.create.form.role", "역할 (Role)")}
              </Label>
              <div className="relative">
                <select
                  id="role"
                  className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
                  {...register("role")}
                >
                  <option value="user">
                    {t("ui.admin.role.user", "TENANT MEMBER")}
                  </option>
                  <option value="tenant_admin">
                    {t("ui.admin.role.tenant_admin", "TENANT ADMIN")}
                  </option>
                  <option value="rp_admin">
                    {t("ui.admin.role.rp_admin", "RP ADMIN")}
                  </option>
                  <option value="super_admin">
                    {t("ui.admin.role.super_admin", "SUPER ADMIN")}
                  </option>
                </select>
              </div>
              <p className="text-xs text-muted-foreground">
                {t(
                  "msg.admin.users.create.form.role_help",
                  "시스템 접근 권한을 결정합니다.",
                )}
              </p>
            </div>

            <div className="flex justify-end gap-4">
              <Button
                type="button"
                variant="outline"
                onClick={() => navigate("/users")}
              >
                {t("ui.common.cancel", "취소")}
              </Button>
              <Button type="submit" disabled={mutation.isPending}>
                {mutation.isPending && (
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                )}
                <Save className="mr-2 h-4 w-4" />
                {t("ui.admin.users.create.submit", "사용자 생성")}
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}

export default UserCreatePage;
