/**
 * ============================================
 * AUTH CONTEXT (Customer State Management)
 * ============================================
 * 
 * FOR SHOPWARE DEVELOPERS:
 * In Shopware Twig, the customer is available via `context.customer`.
 * In React, we use "Context" - same pattern as the CartContext.
 * 
 * This replaces: AccountService, account templates, login/register
 */

'use client';

import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
import {
  Customer,
  login as apiLogin,
  logout as apiLogout,
  register as apiRegister,
  getCustomerProfile,
  getContextToken,
} from './shopware-api';

const LOGGED_IN_KEY = 'sw-customer-logged-in';

interface AuthContextType {
  customer: Customer | null;
  isLoggedIn: boolean;
  isLoading: boolean;
  login: (email: string, password: string) => Promise<void>;
  logout: () => Promise<void>;
  register: (data: RegisterData) => Promise<void>;
  refreshCustomer: () => Promise<void>;
}

export interface RegisterData {
  email: string;
  password: string;
  firstName: string;
  lastName: string;
  salutationId: string;
  storefrontUrl: string;
  accountType?: 'private' | 'business';
  vatIds?: string[];
  billingAddress: {
    street: string;
    zipcode: string;
    city: string;
    countryId: string;
    company?: string;
    department?: string;
  };
}

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

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [customer, setCustomer] = useState<Customer | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  const isLoggedIn = !!customer;

  // Check if customer is already logged in on mount.
  // Only calls /account/customer when the user has previously logged in —
  // avoids 403 errors from guest context tokens.
  const refreshCustomer = useCallback(async () => {
    try {
      const token = getContextToken();
      const isLoggedIn = localStorage.getItem(LOGGED_IN_KEY);
      if (token && isLoggedIn) {
        const profile = await getCustomerProfile();
        setCustomer(profile);
      }
    } catch {
      // Session expired — user needs to log in again
      localStorage.removeItem(LOGGED_IN_KEY);
      setCustomer(null);
    } finally {
      setIsLoading(false);
    }
  }, []);

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

  const login = useCallback(async (email: string, password: string) => {
    setIsLoading(true);
    try {
      await apiLogin(email, password);
      localStorage.setItem(LOGGED_IN_KEY, '1');
      const profile = await getCustomerProfile();
      setCustomer(profile);
    } catch (error) {
      localStorage.removeItem(LOGGED_IN_KEY);
      setCustomer(null);
      throw error;
    } finally {
      setIsLoading(false);
    }
  }, []);

  const logout = useCallback(async () => {
    setIsLoading(true);
    try {
      await apiLogout();
    } catch {
      // Logout may fail if session already expired, that's fine
    } finally {
      localStorage.removeItem(LOGGED_IN_KEY);
      setCustomer(null);
      setIsLoading(false);
    }
  }, []);

  const register = useCallback(async (data: RegisterData) => {
    setIsLoading(true);
    try {
      await apiRegister(data);
      localStorage.setItem(LOGGED_IN_KEY, '1');
      // After registration, customer is auto-logged in (Shopware default)
      const profile = await getCustomerProfile();
      setCustomer(profile);
    } catch (error) {
      localStorage.removeItem(LOGGED_IN_KEY);
      throw error;
    } finally {
      setIsLoading(false);
    }
  }, []);

  return (
    <AuthContext.Provider
      value={{
        customer,
        isLoggedIn,
        isLoading,
        login,
        logout,
        register,
        refreshCustomer,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

/**
 * useAuth() hook - use this in any component to access customer/auth state
 * 
 * Example:
 *   const { customer, isLoggedIn, login, logout } = useAuth();
 */
export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
}
