'use client';

import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { authApi } from '@/lib/api';
import { tokenUtils } from '@/lib/auth-token';

export interface User {
  id: number;
  email: string;
  first_name: string;
  last_name: string;
  role: string;
  phone?: string;
  avatar_url?: string;
  agency_id?: number;
  developer_id?: number;
  rera_permit_number?: string;
  brn?: string;
  orn?: string;
  status?: string;
}

interface AuthContextType {
  user: User | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  login: (emailOrData: any, password?: string) => Promise<void>;
  register: (data: RegisterData) => Promise<void>;
  logout: () => Promise<void>;
  refreshUser: () => Promise<void>;
}

interface RegisterData {
  email: string;
  password: string;
  first_name: string;
  last_name: string;
  phone?: string;
  role: string;
  rera_permit_number?: string;
  brn?: string;
  orn?: string;
  agency_id?: number;
}

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

// Cookie helpers — middleware reads 'access_token' cookie for SSR route protection
function setCookie(name: string, value: string, days = 30) {
  if (typeof document === 'undefined') return;
  const expires = new Date(Date.now() + days * 864e5).toUTCString();
  const maxAge = days * 24 * 60 * 60;
  document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; max-age=${maxAge}; path=/; SameSite=Lax`;
}

function deleteCookie(name: string) {
  if (typeof document === 'undefined') return;
  document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; SameSite=Lax`;
}

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    checkAuth();
  }, []);

  const checkAuth = async () => {
    const token = tokenUtils.get();
    if (token) {
      try {
        const response = await authApi.me();
        const userData = response.data.data;
        // Flatten nested professional fields for convenience
        setUser({
          id: userData.id,
          email: userData.email,
          first_name: userData.first_name,
          last_name: userData.last_name,
          role: userData.role,
          phone: userData.phone,
          avatar_url: userData.avatar_url,
          agency_id: userData.professional?.agency?.id,
          developer_id: userData.professional?.developer?.id,
          rera_permit_number: userData.professional?.rera_permit,
          brn: userData.professional?.brn,
          status: userData.status,
        });
      } catch (err: any) {
        // Only clear tokens if the response explicitly indicates an invalid/expired token (401)
        if (err.response?.status === 401) {
          tokenUtils.clear();
        }
      }
    }
    setIsLoading(false);
  };

  const login = async (emailOrData: any, password?: string) => {
    let userData: any;
    let accessToken: string;
    let refreshToken: string;

    if (typeof emailOrData === 'object' && emailOrData !== null) {
      const data = emailOrData;
      const tokens = data.tokens || data;
      accessToken = data.access_token || tokens?.accessToken;
      refreshToken = data.refresh_token || tokens?.refreshToken;
      userData = data.user;
    } else {
      const response = await authApi.login(emailOrData, password!);
      const data = response.data.data;
      const tokens = data.tokens || data;
      accessToken = data.access_token || tokens?.accessToken;
      refreshToken = data.refresh_token || tokens?.refreshToken;
      userData = data.user;
    }

    tokenUtils.save(accessToken);
    localStorage.setItem('refresh_token', refreshToken);

    setUser({
      id: userData.id,
      email: userData.email,
      first_name: userData.first_name,
      last_name: userData.last_name,
      role: userData.role,
      agency_id: userData.agency_id || userData.professional?.agency?.id,
      developer_id: userData.developer_id || userData.professional?.developer?.id,
    });
  };

  const register = async (data: RegisterData) => {
    const response = await authApi.register(data);
    const { tokens, user: userData } = response.data.data;

    const accessToken = tokens?.accessToken || response.data.data.access_token;
    const refreshToken = tokens?.refreshToken || response.data.data.refresh_token;

    tokenUtils.save(accessToken);
    localStorage.setItem('refresh_token', refreshToken);

    setUser({
      id: userData.id,
      email: userData.email,
      first_name: userData.first_name,
      last_name: userData.last_name,
      role: userData.role,
    });
  };

  const logout = async () => {
    try {
      await authApi.logout();
    } catch {
      // Ignore logout errors
    }
    tokenUtils.clear();
    setUser(null);
  };

  const refreshUser = async () => {
    try {
      const response = await authApi.me();
      const userData = response.data.data;
      setUser({
        id: userData.id,
        email: userData.email,
        first_name: userData.first_name,
        last_name: userData.last_name,
        role: userData.role,
        phone: userData.phone,
        avatar_url: userData.avatar_url,
        agency_id: userData.professional?.agency?.id,
        developer_id: userData.professional?.developer?.id,
        rera_permit_number: userData.professional?.rera_permit,
        brn: userData.professional?.brn,
        status: userData.status,
      });
    } catch (err: any) {
      if (err.response?.status === 401) {
        setUser(null);
      }
    }
  };

  return (
    <AuthContext.Provider
      value={{
        user,
        isLoading,
        isAuthenticated: !!user,
        login,
        register,
        logout,
        refreshUser,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
}
