"use client";

import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { KeyRound, Save } from "lucide-react";

import { Button } from "@/components/ui/button";
import {
  ACCOUNT_TYPE_LABELS,
  ACCOUNT_TYPES,
  ACTIVATE_STATUS_LABELS,
  ACTIVATE_STATUSES,
} from "@/lib/constants";
import { formatDate, formatDateTime, toDatetimeLocal } from "@/lib/utils";
import type { MaestroDetail } from "@/lib/maestros";

type MaestroEditFormProps = {
  maestro: MaestroDetail["maestro"];
  playerCount: number;
};

const paidAccountTypeOptions = [
  ACCOUNT_TYPES.BASIC_20,
  ACCOUNT_TYPES.STANDARD_50,
  ACCOUNT_TYPES.PRO_100,
  ACCOUNT_TYPES.SCHOOL_500,
  ACCOUNT_TYPES.SCHOOL_1000,
] as const;

const activateStatusOptions = [
  ACTIVATE_STATUSES.PENDING,
  ACTIVATE_STATUSES.TRIAL,
  ACTIVATE_STATUSES.ACTIVE,
  ACTIVATE_STATUSES.CANCELED,
] as const;

const inputClass =
  "h-9 w-full rounded-md border bg-background px-3 text-sm outline-none transition-colors focus:border-ring focus:ring-3 focus:ring-ring/30 disabled:opacity-50";

export function MaestroEditForm({ maestro, playerCount }: MaestroEditFormProps) {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const [isSaving, setIsSaving] = useState(false);
  const [isResettingPassword, setIsResettingPassword] = useState(false);

  const [name, setName] = useState(maestro.name);
  const [email, setEmail] = useState(maestro.email);
  const [activateStatus, setActivateStatus] = useState(maestro.activateStatus);
  const [accountType, setAccountType] = useState(maestro.accountType);
  const [availableActivateDateTime, setAvailableActivateDateTime] = useState(
    toDatetimeLocal(maestro.availableActivateDateTime)
  );
  const [allowEditEnterCode, setAllowEditEnterCode] = useState(
    maestro.allowEditEnterCode
  );

  const [errorMessage, setErrorMessage] = useState("");
  const [successMessage, setSuccessMessage] = useState("");

  const isDisabled = isSaving || isPending || isResettingPassword;

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

    if (!window.confirm("마에스트로 정보를 저장하시겠습니까?")) return;

    setIsSaving(true);
    setErrorMessage("");
    setSuccessMessage("");

    try {
      const response = await fetch(`/api/maestros/${maestro.maestroID}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name,
          email,
          activateStatus,
          accountType,
          availableActivateDateTime,
          allowEditEnterCode,
        }),
      });

      const body = (await response.json().catch(() => null)) as {
        changed?: boolean;
        message?: string;
      } | null;

      if (!response.ok) {
        throw new Error(body?.message ?? "저장에 실패했습니다.");
      }

      if (body?.changed) {
        setSuccessMessage("저장 완료");
        startTransition(() => {
          router.refresh();
        });
      } else {
        setSuccessMessage("변경 사항이 없습니다.");
      }
    } catch (error) {
      setErrorMessage(
        error instanceof Error ? error.message : "저장에 실패했습니다."
      );
    } finally {
      setIsSaving(false);
    }
  }

  async function handleResetPassword() {
    if (
      !window.confirm(
        `${maestro.name} 계정의 비밀번호를 123456으로 초기화 하시겠습니까?`
      )
    )
      return;

    setIsResettingPassword(true);
    setErrorMessage("");
    setSuccessMessage("");

    try {
      const response = await fetch(
        `/api/maestros/${maestro.maestroID}/reset-password`,
        { method: "POST" }
      );

      const body = (await response.json().catch(() => null)) as {
        message?: string;
      } | null;

      if (!response.ok) {
        throw new Error(body?.message ?? "암호 초기화에 실패했습니다.");
      }

      setSuccessMessage("암호 초기화 완료");
    } catch (error) {
      setErrorMessage(
        error instanceof Error ? error.message : "암호 초기화에 실패했습니다."
      );
    } finally {
      setIsResettingPassword(false);
    }
  }

  return (
    <form onSubmit={(e) => void handleSubmit(e)} className="mt-4 space-y-5">
      <div className="grid gap-x-8 gap-y-4 text-sm md:grid-cols-2 xl:grid-cols-3">
        <FormField label="이름">
          <input
            className={inputClass}
            disabled={isDisabled}
            maxLength={50}
            onChange={(e) => setName(e.target.value)}
            required
            type="text"
            value={name}
          />
        </FormField>

        <FormField label="이메일">
          <input
            className={inputClass}
            disabled={isDisabled}
            maxLength={50}
            onChange={(e) => setEmail(e.target.value)}
            required
            type="email"
            value={email}
          />
        </FormField>

        <FormField label="상태">
          <select
            className={inputClass}
            disabled={isDisabled}
            onChange={(e) => setActivateStatus(Number(e.target.value))}
            value={activateStatus}
          >
            {activateStatusOptions.map((s) => (
              <option key={s} value={s}>
                {ACTIVATE_STATUS_LABELS[s]}
              </option>
            ))}
          </select>
        </FormField>

        <FormField label="계정 유형">
          <select
            className={inputClass}
            disabled={isDisabled}
            onChange={(e) => setAccountType(Number(e.target.value))}
            value={accountType}
          >
            {paidAccountTypeOptions.map((t) => (
              <option key={t} value={t}>
                {ACCOUNT_TYPE_LABELS[t]}
              </option>
            ))}
          </select>
        </FormField>

        <FormField label="사용 가능일">
          <input
            className={inputClass}
            disabled={isDisabled}
            onChange={(e) => setAvailableActivateDateTime(e.target.value)}
            required
            type="datetime-local"
            value={availableActivateDateTime}
          />
        </FormField>

        <FormField label="입장코드 수정">
          <select
            className={inputClass}
            disabled={isDisabled}
            onChange={(e) => setAllowEditEnterCode(Number(e.target.value))}
            value={allowEditEnterCode}
          >
            <option value={1}>허용</option>
            <option value={0}>비허용</option>
          </select>
        </FormField>
      </div>

      <div className="grid gap-x-8 gap-y-3 border-t pt-4 text-sm md:grid-cols-2 xl:grid-cols-3">
        <ReadOnlyItem
          label="약관 동의일"
          value={formatDateTime(maestro.acceptClausesDateTime)}
        />
        <ReadOnlyItem
          label="DB 학생 수"
          value={playerCount.toLocaleString()}
        />
        <ReadOnlyItem
          label="PlayerCount"
          value={maestro.playerCount.toLocaleString()}
        />
        <ReadOnlyItem
          label="체험 MaestroID"
          value={maestro.maestroTestID?.toString() ?? "-"}
        />
        <ReadOnlyItem
          label="사용 가능일 (현재)"
          value={formatDate(maestro.availableActivateDateTime)}
        />
      </div>

      <div className="flex items-center gap-3">
        <Button disabled={isDisabled} size="sm" type="submit">
          <Save aria-hidden="true" className="size-4" />
          저장
        </Button>
        <Button
          disabled={isDisabled}
          onClick={() => void handleResetPassword()}
          size="sm"
          type="button"
          variant="outline"
        >
          <KeyRound aria-hidden="true" className="size-4" />
          암호 초기화
        </Button>
        {successMessage ? (
          <p className="text-sm text-green-700 dark:text-green-400">
            {successMessage}
          </p>
        ) : null}
        {errorMessage ? (
          <p className="text-sm text-destructive">{errorMessage}</p>
        ) : null}
      </div>
    </form>
  );
}

function FormField({
  label,
  children,
}: {
  label: string;
  children: React.ReactNode;
}) {
  return (
    <label className="space-y-1.5">
      <span className="text-xs font-medium text-muted-foreground">{label}</span>
      {children}
    </label>
  );
}

function ReadOnlyItem({ label, value }: { label: string; value: string }) {
  return (
    <div>
      <dt className="text-xs font-medium text-muted-foreground">{label}</dt>
      <dd className="mt-1 font-medium">{value}</dd>
    </div>
  );
}
