"use client";

import { startTransition, useDeferredValue, useState, type FormEvent } from "react";
import { useRouter } from "next/navigation";
import type { KavenixAdminMemberDomainOption } from "@/lib/kavenix-admin";

type KavenixMemberCreateDialogProps = {
  domains: KavenixAdminMemberDomainOption[];
};

type CreateResponse = {
  error?: string;
  message?: string;
  ok?: boolean;
};

function CloseIcon({ className }: { className?: string }) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.8"
      strokeLinecap="round"
      strokeLinejoin="round"
      className={className}
      aria-hidden="true"
    >
      <path d="m7 7 10 10" />
      <path d="M17 7 7 17" />
    </svg>
  );
}

function PlusIcon({ className }: { className?: string }) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.8"
      strokeLinecap="round"
      strokeLinejoin="round"
      className={className}
      aria-hidden="true"
    >
      <path d="M12 5v14" />
      <path d="M5 12h14" />
    </svg>
  );
}

function planLabel(planStatus: KavenixAdminMemberDomainOption["planStatus"]) {
  if (planStatus === "growth") return "성장플랜";
  if (planStatus === "cancelled") return "해지 상태";
  return "무료 플랜";
}

export function KavenixMemberCreateDialog({ domains }: KavenixMemberCreateDialogProps) {
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [domainQuery, setDomainQuery] = useState("");
  const [selectedDomainId, setSelectedDomainId] = useState<number | null>(null);
  const [displayName, setDisplayName] = useState("");
  const [localPart, setLocalPart] = useState("");
  const [password, setPassword] = useState("");
  const [passwordConfirm, setPasswordConfirm] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const deferredDomainQuery = useDeferredValue(domainQuery.trim().toLowerCase());
  const selectedDomain = domains.find((domain) => domain.id === selectedDomainId) ?? null;
  const matchedDomains = domains
    .filter((domain) => {
      if (!deferredDomainQuery) return true;

      return [domain.domain, domain.companyName, domain.ownerEmail]
        .filter(Boolean)
        .some((value) => value.toLowerCase().includes(deferredDomainQuery));
    })
    .slice(0, 8);

  function resetForm() {
    setDomainQuery("");
    setSelectedDomainId(null);
    setDisplayName("");
    setLocalPart("");
    setPassword("");
    setPasswordConfirm("");
  }

  function closeDialog() {
    if (submitting) return;
    setOpen(false);
    resetForm();
  }

  async function submit(allowCancelledPlan: boolean) {
    if (!selectedDomain) {
      throw new Error("추가할 도메인을 선택해 주세요.");
    }

    const response = await fetch("/api/kavenix/members", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        allowCancelledPlan,
        displayName,
        domainId: selectedDomain.id,
        localPart,
        password,
      }),
    });
    const payload = await response.json().catch(() => ({})) as CreateResponse;

    if (response.ok && payload.ok) {
      return payload;
    }

    const error = new Error(payload.message || "사용자 추가에 실패했습니다.");
    (error as Error & { code?: string }).code = payload.error;
    throw error;
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();

    if (submitting) return;

    if (password !== passwordConfirm) {
      window.alert("비밀번호와 비밀번호 확인이 일치하지 않습니다.");
      return;
    }

    setSubmitting(true);

    try {
      let payload: CreateResponse;

      try {
        payload = await submit(false);
      } catch (error) {
        const code = (error as Error & { code?: string }).code;

        if (code !== "growth-plan-cancelled-confirmation-required") {
          throw error;
        }

        const confirmed = window.confirm(
          "현재 도메인은 해지 상태입니다.\n\n다음 청구일에는 대표 계정 외 모든 멤버의 사용이 중지됩니다. 그래도 사용자를 추가할까요?",
        );

        if (!confirmed) return;
        payload = await submit(true);
      }

      window.alert(payload.message || "사용자를 추가했습니다.");
      setOpen(false);
      resetForm();
      startTransition(() => router.refresh());
    } catch (error) {
      window.alert(error instanceof Error ? error.message : "사용자 추가에 실패했습니다.");
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <>
      <button
        type="button"
        onClick={() => setOpen(true)}
        className="om-btn-primary inline-flex h-10 items-center gap-1.5 rounded-[10px] px-4 text-[13px] shadow-none"
      >
        <PlusIcon className="h-4 w-4" />
        사용자 추가
      </button>

      {open ? (
        <div
          className="fixed inset-0 z-[100] flex items-end justify-center bg-[#102044]/25 p-0 backdrop-blur-[2px] sm:items-center sm:p-5"
          role="presentation"
          onMouseDown={(event) => {
            if (event.target === event.currentTarget) closeDialog();
          }}
        >
          <section
            role="dialog"
            aria-modal="true"
            aria-labelledby="kavenix-member-create-title"
            className="w-full max-w-[560px] rounded-t-[20px] bg-white shadow-[0_28px_80px_rgba(18,32,65,0.22)] sm:rounded-[18px]"
          >
            <div className="flex items-start justify-between gap-4 border-b border-[#edf1f6] px-4 py-4 sm:px-5">
              <div>
                <h2 id="kavenix-member-create-title" className="text-[17px] font-semibold tracking-[-0.04em] text-[#16233c]">
                  사용자 추가
                </h2>
                <p className="mt-1 text-[12px] leading-5 text-[#7183a2]">
                  성장플랜 도메인에만 추가할 수 있으며, 이번 추가는 즉시 청구되지 않습니다.
                </p>
              </div>
              <button
                type="button"
                onClick={closeDialog}
                aria-label="사용자 추가 닫기"
                className="inline-flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-full text-[#8492aa] transition-colors hover:bg-[#f4f7fc] hover:text-[#2f6df6]"
              >
                <CloseIcon className="h-4 w-4" />
              </button>
            </div>

            <form onSubmit={handleSubmit} className="space-y-4 px-4 py-5 sm:px-5">
              <label className="block">
                <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">도메인</span>
                <input
                  value={selectedDomain ? selectedDomain.domain : domainQuery}
                  onChange={(event) => {
                    setSelectedDomainId(null);
                    setDomainQuery(event.target.value);
                  }}
                  onFocus={() => {
                    if (selectedDomain) {
                      setSelectedDomainId(null);
                      setDomainQuery(selectedDomain.domain);
                    }
                  }}
                  placeholder="도메인, 회사명 또는 대표 이메일 검색"
                  className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] text-[#1a2943] outline-none transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                />
                <div className="mt-2 max-h-[188px] overflow-y-auto rounded-[10px] border border-[#e3eaf6] bg-white p-1.5">
                  {matchedDomains.length > 0 ? (
                    matchedDomains.map((domain) => {
                      const selected = selectedDomainId === domain.id;

                      return (
                        <button
                          key={domain.id}
                          type="button"
                          onClick={() => {
                            setSelectedDomainId(domain.id);
                            setDomainQuery(domain.domain);
                          }}
                          className={`flex w-full cursor-pointer items-center justify-between gap-3 rounded-[8px] px-3 py-2.5 text-left transition-colors ${
                            selected
                              ? "bg-[#edf4ff] text-[#2f6df6]"
                              : "text-[#354865] hover:bg-[#f7faff]"
                          }`}
                        >
                          <span className="min-w-0">
                            <span className="block truncate text-[13px] font-semibold">{domain.domain}</span>
                            <span className="mt-0.5 block truncate text-[12px] text-[#7b8ca8]">
                              {domain.companyName || domain.ownerEmail}
                            </span>
                          </span>
                          <span className={`shrink-0 text-[12px] font-semibold ${selected ? "text-[#2f6df6]" : "text-[#8190a8]"}`}>
                            {planLabel(domain.planStatus)}
                          </span>
                        </button>
                      );
                    })
                  ) : (
                    <p className="px-3 py-3 text-[13px] text-[#7b8ca8]">일치하는 도메인이 없습니다.</p>
                  )}
                </div>
              </label>

              <div className="grid gap-4 sm:grid-cols-2">
                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">이름</span>
                  <input
                    required
                    value={displayName}
                    maxLength={191}
                    onChange={(event) => setDisplayName(event.target.value)}
                    autoComplete="name"
                    placeholder="표시 이름"
                    className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] text-[#1a2943] outline-none transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                  />
                </label>
                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">메일 아이디</span>
                  <div className="flex h-11 items-center rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 focus-within:border-[#bcd1ff]">
                    <input
                      required
                      value={localPart}
                      maxLength={64}
                      onChange={(event) => setLocalPart(event.target.value.toLowerCase())}
                      autoCapitalize="none"
                      autoComplete="username"
                      placeholder="name"
                      className="min-w-0 flex-1 bg-transparent text-[14px] text-[#1a2943] outline-none placeholder:text-[#97a7c2]"
                    />
                    <span className="ml-1 shrink-0 text-[12px] text-[#7b8ca8]">
                      @{selectedDomain?.domain ?? "도메인"}
                    </span>
                  </div>
                </label>
              </div>

              <div className="grid gap-4 sm:grid-cols-2">
                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">비밀번호</span>
                  <input
                    required
                    type="password"
                    value={password}
                    onChange={(event) => setPassword(event.target.value)}
                    autoComplete="new-password"
                    className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] text-[#1a2943] outline-none transition-colors focus:border-[#bcd1ff]"
                  />
                </label>
                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">비밀번호 확인</span>
                  <input
                    required
                    type="password"
                    value={passwordConfirm}
                    onChange={(event) => setPasswordConfirm(event.target.value)}
                    autoComplete="new-password"
                    className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] text-[#1a2943] outline-none transition-colors focus:border-[#bcd1ff]"
                  />
                </label>
              </div>

              <p className="text-[12px] leading-5 text-[#7284a4]">
                다음 자동결제 시점에는 해당 도메인의 활성 팀 인원 수를 기준으로 요금이 산정됩니다.
              </p>

              <div className="flex items-center justify-end gap-2 border-t border-[#edf1f6] pt-4">
                <button
                  type="button"
                  disabled={submitting}
                  onClick={closeDialog}
                  className="om-btn-secondary h-10 rounded-[10px] px-4 text-[13px] text-[#344767] shadow-none disabled:cursor-not-allowed disabled:opacity-60"
                >
                  취소
                </button>
                <button
                  type="submit"
                  disabled={submitting || !selectedDomain}
                  className="om-btn-primary h-10 rounded-[10px] px-4 text-[13px] shadow-none disabled:cursor-not-allowed disabled:opacity-60"
                >
                  {submitting ? "추가 중..." : "사용자 추가"}
                </button>
              </div>
            </form>
          </section>
        </div>
      ) : null}
    </>
  );
}
