"use client";

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import {
  clearUser,
  ensureThresholdReachedAt,
  loadUser,
  saveUser,
  sumOrders,
  type MockOrder,
  type UserSession,
} from "@/lib/auth-types";
import { SPEND_THRESHOLD_USD } from "@/lib/quiz-rules";
import { ApiError, setApiAuthToken } from "@/lib/api";
import { loginWithPassword } from "@/lib/auth-api";
import { isRegisterPasswordValid } from "@/lib/password-rules";
import { registerWithEmail } from "@/lib/register-api";
import { fetchCustomUserInfo } from "@/lib/user-info-api";

type AuthContextValue = {
  user: UserSession | null;
  isReady: boolean;
  login: (
    email: string,
    password: string,
  ) => Promise<{ ok: boolean; error?: string; message?: string }>;
  register: (input: {
    country: string;
    email: string;
    password: string;
    name: string;
    code: string;
  }) => Promise<{ ok: boolean; error?: string; message?: string }>;
  logout: () => void;
  updateProfile: (
    patch: Partial<Pick<UserSession, "name" | "phone" | "identity" | "scholarship">>,
  ) => void;
  addMockOrder: (order: Omit<MockOrder, "id" | "createdAt">) => void;
  /** 本地演示：将门槛达成时间设为 181 天前，用于验证问答解锁 */
  demoUnlockQuizCountdown: () => void;
};

const AuthContext = createContext<AuthContextValue | null>(null);

function newUserSession(
  email: string,
  name: string,
  seedOrders: MockOrder[] = [],
): UserSession {
  const thresholdReachedAt = ensureThresholdReachedAt(seedOrders, null);
  return {
    email,
    name,
    phone: "",
    identity: "",
    thresholdReachedAt,
    orders: seedOrders,
    scholarship: {},
  };
}

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<UserSession | null>(null);
  const [isReady, setIsReady] = useState(false);
  useEffect(() => {
    /* eslint-disable react-hooks/set-state-in-effect -- hydrate once from localStorage after mount */
    setUser(loadUser());
    setIsReady(true);
    /* eslint-enable react-hooks/set-state-in-effect */
  }, []);

  const persist = useCallback((next: UserSession | null) => {
    setUser(next);
    if (next) saveUser(next);
    else clearUser();
  }, []);

  const login = useCallback(
    async (email: string, password: string) => {
      if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
        return { ok: false, error: "invalid_email" };
      }
      try {
        const { token, displayName } = await loginWithPassword(
          email.trim(),
          password,
        );
        if (token) setApiAuthToken(token);
        const base = newUserSession(email.trim(), displayName);
        try {
          const info = await fetchCustomUserInfo();
          persist({
            ...base,
            email: info.email || base.email,
            name: info.name || base.name,
            phone: info.phone || base.phone,
            identity: info.identity || base.identity,
          });
        } catch {
          persist(base);
        }
        return { ok: true };
      } catch (e) {
        const message = e instanceof ApiError ? e.message : "登录失败";
        return { ok: false, error: "api", message };
      }
    },
    [persist],
  );

  const register = useCallback(
    async (input: {
      country: string;
      email: string;
      password: string;
      name: string;
      code: string;
    }) => {
      if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input.email)) {
        return { ok: false, error: "invalid_email" };
      }
      if (!isRegisterPasswordValid(input.password)) {
        return { ok: false, error: "weak_password" };
      }
      if (!input.code.trim()) {
        return { ok: false, error: "invalid_code" };
      }
      if (!input.country.trim()) {
        return { ok: false, error: "country_required" };
      }
      try {
        const { token } = await registerWithEmail({
          country: input.country.trim(),
          name: input.name.trim() || "学员",
          email: input.email.trim(),
          emailCode: input.code.trim(),
          password: input.password,
        });
        if (token) setApiAuthToken(token);
        const base = newUserSession(input.email.trim(), input.name.trim() || "学员");
        try {
          const info = await fetchCustomUserInfo();
          persist({
            ...base,
            email: info.email || base.email,
            name: info.name || base.name,
            phone: info.phone || base.phone,
            identity: info.identity || base.identity,
          });
        } catch {
          persist(base);
        }
        return { ok: true };
      } catch (e) {
        const message = e instanceof ApiError ? e.message : "注册失败";
        return { ok: false, error: "api", message };
      }
    },
    [persist],
  );

  const logout = useCallback(() => {
    setApiAuthToken(null);
    persist(null);
  }, [persist]);

  const updateProfile = useCallback(
    (
      patch: Partial<
        Pick<UserSession, "name" | "phone" | "identity" | "scholarship">
      >,
    ) => {
      if (!user) return;
      persist({
        ...user,
        ...patch,
        name: patch.name ?? user.name,
        phone: patch.phone ?? user.phone,
        identity: patch.identity ?? user.identity,
        scholarship: { ...user.scholarship, ...patch.scholarship },
      });
    },
    [user, persist],
  );

  const addMockOrder = useCallback(
    (order: Omit<MockOrder, "id" | "createdAt">) => {
      if (!user) return;
      const nextOrder: MockOrder = {
        ...order,
        id: `ord_${Date.now()}`,
        createdAt: new Date().toISOString(),
      };
      const orders = [...user.orders, nextOrder];
      const thresholdReachedAt = ensureThresholdReachedAt(
        orders,
        user.thresholdReachedAt,
      );
      persist({
        ...user,
        orders,
        thresholdReachedAt,
      });
    },
    [user, persist],
  );

  const demoUnlockQuizCountdown = useCallback(() => {
    if (!user) return;
    let orders = user.orders;
    if (sumOrders(orders) < SPEND_THRESHOLD_USD) {
      orders = [
        ...orders,
        {
          id: `ord_demo_${Date.now()}`,
          amount: SPEND_THRESHOLD_USD,
          createdAt: new Date().toISOString(),
          title: "演示订单（验证问答解锁）",
        },
      ];
    }
    const past = new Date();
    past.setDate(past.getDate() - 181);
    persist({
      ...user,
      orders,
      thresholdReachedAt: past.toISOString(),
    });
  }, [user, persist]);

  const value = useMemo<AuthContextValue>(
    () => ({
      user,
      isReady,
      login,
      register,
      logout,
      updateProfile,
      addMockOrder,
      demoUnlockQuizCountdown,
    }),
    [
      user,
      isReady,
      login,
      register,
      logout,
      updateProfile,
      addMockOrder,
      demoUnlockQuizCountdown,
    ],
  );

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth must be used within AuthProvider");
  return ctx;
}
