import React, { createContext, useContext, useMemo, useState } from "react";
import { API_URL } from "./api";

const AuthCtx = createContext(null);

function loadStorage() {
  try {
    return JSON.parse(localStorage.getItem("nexapg_auth") || "null");
  } catch {
    return null;
  }
}

export function AuthProvider({ children }) {
  const initial = loadStorage();
  const [tokens, setTokens] = useState(initial?.tokens || null);
  const [me, setMe] = useState(initial?.me || null);

  const persist = (nextTokens, nextMe) => {
    if (nextTokens && nextMe) {
      localStorage.setItem("nexapg_auth", JSON.stringify({ tokens: nextTokens, me: nextMe }));
    } else {
      localStorage.removeItem("nexapg_auth");
    }
  };

  const refresh = async () => {
    if (!tokens?.refreshToken) return null;
    const res = await fetch(`${API_URL}/auth/refresh`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ refresh_token: tokens.refreshToken }),
    });
    if (!res.ok) {
      setTokens(null);
      setMe(null);
      persist(null, null);
      return null;
    }
    const data = await res.json();
    const nextTokens = { accessToken: data.access_token, refreshToken: data.refresh_token };
    setTokens(nextTokens);
    persist(nextTokens, me);
    return nextTokens;
  };

  const login = async (email, password) => {
    const res = await fetch(`${API_URL}/auth/login`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, password }),
    });
    if (!res.ok) throw new Error("Login failed");
    const data = await res.json();
    const nextTokens = { accessToken: data.access_token, refreshToken: data.refresh_token };
    const meRes = await fetch(`${API_URL}/me`, {
      headers: { Authorization: `Bearer ${nextTokens.accessToken}` },
    });
    if (!meRes.ok) throw new Error("Could not load user profile");
    const profile = await meRes.json();
    setTokens(nextTokens);
    setMe(profile);
    persist(nextTokens, profile);
  };

  const logout = async () => {
    try {
      if (tokens?.accessToken) {
        await fetch(`${API_URL}/auth/logout`, {
          method: "POST",
          headers: { Authorization: `Bearer ${tokens.accessToken}` },
        });
      }
    } finally {
      setTokens(null);
      setMe(null);
      persist(null, null);
    }
  };

  const value = useMemo(() => ({ tokens, me, login, logout, refresh }), [tokens, me]);
  return <AuthCtx.Provider value={value}>{children}</AuthCtx.Provider>;
}

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