"use client";

import { useEffect, useState, useTransition } from "react";
import { useShallow } from "zustand/react/shallow";
import {
  CreditCard,
  CheckCircle2,
  SearchCheck,
  ShieldOff,
  XCircle,
  FileLock2,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import { InlineSpinner } from "@/components/ui/loading-spinner";
import { validateKisProfile } from "@/features/settings/apis/kis-auth.api";
import {
  getRememberedKisValue,
  isKisRememberEnabled,
  setKisRememberEnabled,
  setRememberedKisValue,
} from "@/features/settings/lib/kis-remember-storage";
import { useKisRuntimeStore } from "@/features/settings/store/use-kis-runtime-store";
import { SettingsCard } from "./SettingsCard";

/**
 * @description 한국투자증권 계좌번호 검증 폼입니다.
 * @remarks UI 흐름: /settings -> 계좌번호 입력 -> 계좌 확인 버튼 -> validate-profile API -> store 반영 -> 대시보드 반영
 * @see app/api/kis/validate-profile/route.ts 계좌번호 검증 서버 라우트
 * @see features/settings/store/use-kis-runtime-store.ts 검증 성공값을 전역 상태에 저장합니다.
 */
export function KisProfileForm() {
  const {
    kisAccountNoInput,
    verifiedCredentials,
    hasHydrated,
    isKisVerified,
    isKisProfileVerified,
    verifiedAccountNo,
    setKisAccountNoInput,
    setVerifiedKisProfile,
    invalidateKisProfileVerification,
  } = useKisRuntimeStore(
    useShallow((state) => ({
      kisAccountNoInput: state.kisAccountNoInput,
      verifiedCredentials: state.verifiedCredentials,
      hasHydrated: state._hasHydrated,
      isKisVerified: state.isKisVerified,
      isKisProfileVerified: state.isKisProfileVerified,
      verifiedAccountNo: state.verifiedAccountNo,
      setKisAccountNoInput: state.setKisAccountNoInput,
      setVerifiedKisProfile: state.setVerifiedKisProfile,
      invalidateKisProfileVerification: state.invalidateKisProfileVerification,
    })),
  );

  const [statusMessage, setStatusMessage] = useState<string | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [isValidating, startValidateTransition] = useTransition();
  // [State] 계좌번호 입력값을 브라우저 재접속 후 자동 복원할지 여부
  const [rememberAccountNo, setRememberAccountNo] = useState(() =>
    isKisRememberEnabled("accountNo"),
  );

  useEffect(() => {
    if (!hasHydrated || kisAccountNoInput.trim()) {
      return;
    }

    // [Step 1] 세션 입력값이 비어 있을 때만 저장된 계좌번호를 복원합니다.
    const rememberedAccountNo = getRememberedKisValue("accountNo");
    if (rememberedAccountNo) {
      setKisAccountNoInput(rememberedAccountNo);
    }
  }, [hasHydrated, kisAccountNoInput, setKisAccountNoInput]);

  useEffect(() => {
    if (!hasHydrated) {
      return;
    }

    // [Step 2] 계좌 기억하기 체크 상태를 저장/해제합니다.
    setKisRememberEnabled("accountNo", rememberAccountNo);
  }, [hasHydrated, rememberAccountNo]);

  useEffect(() => {
    if (!hasHydrated || !rememberAccountNo) {
      return;
    }

    // [Step 2] 계좌번호 입력값이 바뀔 때 기억하기가 켜져 있으면 값을 갱신합니다.
    setRememberedKisValue("accountNo", kisAccountNoInput);
  }, [hasHydrated, rememberAccountNo, kisAccountNoInput]);

  /**
   * @description 계좌번호 인증을 해제하고 입력값을 비웁니다.
   * @see features/settings/store/use-kis-runtime-store.ts setKisAccountNoInput
   * @see features/settings/store/use-kis-runtime-store.ts invalidateKisProfileVerification
   */
  function handleDisconnectAccount() {
    setStatusMessage("계좌 인증을 해제했습니다.");
    setErrorMessage(null);
    setKisAccountNoInput("");
    invalidateKisProfileVerification();
  }

  function handleValidateProfile() {
    startValidateTransition(async () => {
      try {
        setStatusMessage(null);
        setErrorMessage(null);

        if (!verifiedCredentials || !isKisVerified) {
          throw new Error("먼저 앱키 연결을 완료해 주세요.");
        }

        const accountNo = kisAccountNoInput.trim();

        if (!accountNo) {
          throw new Error("계좌번호를 입력해 주세요.");
        }

        if (!isValidAccountNo(accountNo)) {
          throw new Error(
            "계좌번호 형식이 올바르지 않습니다. 8-2 형식(예: 12345678-01)으로 입력해 주세요.",
          );
        }

        const result = await validateKisProfile({
          ...verifiedCredentials,
          accountNo,
        });

        setVerifiedKisProfile({
          accountNo: result.account.normalizedAccountNo,
        });

        setStatusMessage(result.message);
      } catch (error) {
        invalidateKisProfileVerification();
        setErrorMessage(
          error instanceof Error
            ? error.message
            : "계좌 확인 중 오류가 발생했습니다.",
        );
      }
    });
  }

  return (
    <SettingsCard
      icon={CreditCard}
      title="한국투자증권 계좌 인증"
      description="앱키 연결 후 계좌번호를 검증하면 잔고/대시보드 기능을 사용할 수 있습니다."
      badge={
        isKisProfileVerified ? (
          <span className="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full bg-green-50 px-2 py-0.5 text-[11px] font-medium text-green-700 ring-1 ring-green-600/20 dark:bg-green-500/10 dark:text-green-400 dark:ring-green-500/30">
            <CheckCircle2 className="h-3 w-3" />
            인증 완료
          </span>
        ) : undefined
      }
      className={
        !isKisVerified ? "opacity-60 grayscale pointer-events-none" : undefined
      }
      footer={{
        actions: (
          <div className="flex flex-wrap gap-2">
            <Button
              type="button"
              onClick={handleValidateProfile}
              disabled={
                !isKisVerified || isValidating || !kisAccountNoInput.trim()
              }
              className="h-9 rounded-lg bg-brand-600 px-4 text-xs font-semibold text-white shadow-sm transition-all hover:bg-brand-700 hover:shadow disabled:opacity-50 disabled:shadow-none dark:bg-brand-600 dark:hover:bg-brand-500"
            >
              {isValidating ? (
                <span className="flex items-center gap-1.5">
                  <InlineSpinner className="h-3 w-3 text-white" />
                  확인 중
                </span>
              ) : (
                <span className="flex items-center gap-1.5">
                  <SearchCheck className="h-3.5 w-3.5" />
                  계좌 인증하기
                </span>
              )}
            </Button>
            <Button
              type="button"
              variant="outline"
              onClick={handleDisconnectAccount}
              disabled={!isKisProfileVerified && !kisAccountNoInput.trim()}
              className="h-9 rounded-lg border-zinc-200 bg-white px-4 text-xs text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-200"
            >
              <ShieldOff className="h-3.5 w-3.5" />
              계좌 인증 해제
            </Button>
          </div>
        ),
        status: (
          <div className="flex min-h-5 items-center justify-start sm:justify-end">
            {errorMessage && (
              <p className="animate-in fade-in slide-in-from-right-4 flex items-center gap-1.5 text-xs font-semibold text-red-500">
                <XCircle className="h-3.5 w-3.5" />
                {errorMessage}
              </p>
            )}
            {statusMessage && (
              <p className="animate-in fade-in slide-in-from-right-4 flex items-center gap-1.5 text-xs font-semibold text-brand-600 dark:text-brand-400">
                <CheckCircle2 className="h-3.5 w-3.5" />
                {statusMessage}
              </p>
            )}
            {!statusMessage && !errorMessage && !isKisVerified && (
              <p className="flex items-center gap-1.5 text-xs text-zinc-400 dark:text-zinc-600">
                <span className="h-1.5 w-1.5 rounded-full bg-zinc-300 dark:bg-zinc-700" />
                먼저 앱키 연결을 완료해 주세요
              </p>
            )}
            {!statusMessage && !errorMessage && isKisProfileVerified && (
              <p className="animate-in fade-in slide-in-from-right-4 flex items-center gap-1.5 text-xs font-medium text-zinc-500 dark:text-zinc-400">
                확인된 계좌: {maskAccountNo(verifiedAccountNo)}
              </p>
            )}
          </div>
        ),
      }}
    >
      <div className="space-y-4">
        {/* ========== ACCOUNT GUIDE ========== */}
        <section className="rounded-xl border border-zinc-200 bg-zinc-50/70 p-3 dark:border-zinc-800 dark:bg-zinc-900/30">
          <p className="flex items-center gap-1.5 text-xs font-semibold text-zinc-700 dark:text-zinc-200">
            <FileLock2 className="h-3.5 w-3.5 text-brand-500" />
            계좌번호 형식 안내
          </p>
          <p className="mt-1 text-xs leading-relaxed text-zinc-600 dark:text-zinc-300">
            8-2 형식으로 입력하세요. 예: <span className="font-medium">12345678-01</span>
          </p>
        </section>

        {/* ========== ACCOUNT NO INPUT ========== */}
        <div className="space-y-1.5">
          <Label
            htmlFor="kis-account-no"
            className="text-xs font-semibold text-zinc-600"
          >
            계좌번호
          </Label>
          <div className="group/input flex items-center overflow-hidden rounded-xl border border-zinc-200 bg-white transition-colors focus-within:border-brand-500 focus-within:ring-1 focus-within:ring-brand-500 dark:border-zinc-700 dark:bg-zinc-900/20">
            <div className="flex h-10 w-10 shrink-0 items-center justify-center border-r border-zinc-100 bg-zinc-50 text-zinc-400 group-focus-within/input:text-brand-500 dark:border-zinc-800 dark:bg-zinc-800/40">
              <CreditCard className="h-4 w-4" />
            </div>
            <Input
              id="kis-account-no"
              type="password"
              value={kisAccountNoInput}
              onChange={(e) => setKisAccountNoInput(e.target.value)}
              placeholder="계좌번호 (예: 12345678-01)"
              className="h-10 border-none bg-transparent px-3 text-sm shadow-none focus-visible:ring-0"
              autoComplete="off"
            />
          </div>
          <div className="flex items-center gap-2 pl-1 pt-0.5">
            <Checkbox
              id="remember-kis-account-no"
              checked={rememberAccountNo}
              onCheckedChange={(checked) =>
                setRememberAccountNo(checked === true)
              }
            />
            <Label
              htmlFor="remember-kis-account-no"
              className="cursor-pointer text-xs font-medium text-zinc-500 dark:text-zinc-300"
            >
              계좌번호 기억하기
            </Label>
          </div>
        </div>
      </div>
    </SettingsCard>
  );
}

/**
 * @description KIS 계좌번호(8-2) 입력 포맷을 검증합니다.
 * @param value 사용자 입력 계좌번호
 * @returns 형식 유효 여부
 * @see features/settings/components/KisProfileForm.tsx handleValidateProfile
 */
function isValidAccountNo(value: string) {
  const digits = value.replace(/\D/g, "");
  return digits.length === 10;
}

/**
 * @description 표시용 계좌번호를 마스킹 처리합니다.
 * @param value 계좌번호(8-2)
 * @returns 마스킹 계좌번호
 * @see features/settings/components/KisProfileForm.tsx 확인된 값 표시
 */
function maskAccountNo(value: string | null) {
  if (!value) return "-";
  const digits = value.replace(/\D/g, "");
  if (digits.length !== 10) return "********";
  return "********-**";
}
