import React, { createContext, useState, useEffect, useContext } from "react";
import { api } from "../utils/api";
import { AuthorModel } from "../types/models";
import { AuthContextModel } from "../types/contexts";
import { useAuth as useBaseAuth } from "../../../auth/src";

const AuthContext = createContext<AuthContextModel | undefined>(undefined);

export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const { currentUser: authUser, logout } = useBaseAuth();
  const [currentUser, setCurrentUser] = useState<AuthorModel | null>(null);
  const [authors, setAuthors] = useState<AuthorModel[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  /**
   * Hydrate application-level currentUser
   */
  const hydrateCurrentUser = async () => {
    if (!authUser) return;

    try {
      setLoading(true);
      setError(null);

      const res = await api.get<AuthorModel>("/authors/me");

      /**
       * Explicit precedence:
       * Auth service is source of truth for inherited fields
       */
      const fullUser: AuthorModel = {
        ...res.data,
        username: authUser.username,
        email: authUser.email,
        is_active: authUser.is_active,
      };

      setCurrentUser(fullUser);
    } catch (err) {
      console.error("Failed to hydrate current user:", err);
      logout();
    } finally {
      setLoading(false);
    }
  };

  /** 🔹 Fetch all authors (JWT handled by api interceptor) */
  const refreshAuthors = async () => {
    try {
      setLoading(true);
      setError(null);

      const res = await api.get<AuthorModel[]>('/authors');
      setAuthors(res.data);
    } catch (err: any) {
      console.error('Failed to fetch authors:', err);
      setError(err.response?.data?.detail || 'Failed to fetch authors');
    } finally {
      setLoading(false);
    }
  };

  /** 🔹 Update current user (full model) */
  const updateProfile = async (userData: AuthorModel) => {
    if (!userData._id) {
      console.error('updateProfile called without _id');
      return;
    }
    try {
      setLoading(true);
      setError(null);

      const res = await api.put<AuthorModel>(`/authors/${userData._id}`, userData);
      setCurrentUser(res.data);
      return res.data;
    } catch (err: any) {
      console.error('Profile update failed:', err);
      setError(err.response?.data?.detail || 'Failed to update profile');
    } finally {
      setLoading(false);
    }
  };

  /**
   * React strictly to auth lifecycle
   */
  useEffect(() => {
    if (authUser) {
      hydrateCurrentUser();
    } else {
      setCurrentUser(null);
      setAuthors([]);
      setError(null);
    }
  }, [authUser]);

  return (
    <AuthContext.Provider
      value={{
        currentUser,
        authors,
        loading,
        error,

        refreshAuthors,
        updateProfile,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = (): AuthContextModel => {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used inside AuthProvider');
  return ctx;
};
