"use client";

// Two-step login flow + auth state, exposed through React context.
//
// Step 1: POST {approagency}/auth/login  (auth, password, package_name) -> approoToken
// Step 2: POST {meditation}/auth/login-with-approo-v2?token=approoToken&package_name=...
//         (multipart: token, package_name) -> meditation bearer token
//
// The meditation token is persisted in localStorage and attached to every
// subsequent request by lib/api.ts.

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useState,
} from "react";
import { APPRO_BASE_URL, MEDITATION_BASE_URL, PACKAGE_NAME } from "./config";
import {
  ApiError,
  apiFetch,
  clearToken,
  getToken,
  setToken,
  toFormData,
} from "./api";

interface AuthState {
  token: string | null;
  ready: boolean; // hydrated from localStorage yet?
  login: (identifier: string, password: string) => Promise<void>;
  logout: () => void;
}

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

async function approAgencyLogin(
  identifier: string,
  password: string,
): Promise<string> {
  const res = await apiFetch<{ token?: string }>("/auth/login", {
    method: "POST",
    baseUrl: APPRO_BASE_URL,
    auth: false,
    body: toFormData({
      auth: identifier,
      password,
      package_name: PACKAGE_NAME,
    }),
  });
  if (!res?.token) {
    throw new ApiError("نام کاربری یا رمز عبور نادرست است.", 401, res);
  }
  return res.token;
}

async function meditationLogin(approoToken: string): Promise<string> {
  const res = await apiFetch<{ token?: string }>(
    "/auth/login-with-approo-v2",
    {
      method: "POST",
      baseUrl: MEDITATION_BASE_URL,
      auth: false,
      query: { token: approoToken, package_name: PACKAGE_NAME },
      body: toFormData({ token: approoToken, package_name: PACKAGE_NAME }),
    },
  );
  if (!res?.token) {
    throw new ApiError("ورود به سرویس مدیتیشن ناموفق بود.", 401, res);
  }
  return res.token;
}

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [token, setTokenState] = useState<string | null>(null);
  const [ready, setReady] = useState(false);

  useEffect(() => {
    setTokenState(getToken());
    setReady(true);
  }, []);

  const login = useCallback(async (identifier: string, password: string) => {
    const approoToken = await approAgencyLogin(identifier, password);
    const medToken = await meditationLogin(approoToken);
    setToken(medToken);
    setTokenState(medToken);
  }, []);

  const logout = useCallback(() => {
    clearToken();
    setTokenState(null);
  }, []);

  return (
    <AuthContext.Provider value={{ token, ready, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

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