import { Injectable } from '@angular/core';
import axios from 'axios';
import { UserService } from './user.service';
import { LoggerService } from './logger.service';
import { BASE_URL, getBaseUrl } from '../config/api.config';

const TOKEN_KEY = 'jwtToken';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  constructor(
    private userService: UserService,
    private logger: LoggerService
  ) {}

  async login(email: string, password: string, code?: string, deviceFingerprint?: string): Promise<{ token: string; requires2FA?: boolean }> {
    try {
      const baseUrl = getBaseUrl();
      this.logger.debug('[AuthService] Login attempt:', { baseUrl, origin: window.location.origin, protocol: window.location.protocol });
      const response = await axios.post(`${baseUrl}/api/v3/auth/login`, { 
        email, 
        password, 
        code: code || null, 
        deviceFingerprint: deviceFingerprint || null 
      }, {
        withCredentials: true // Enable CORS credentials
      });
      const token = response.data?.token ?? response.data?.jwt ?? response.data?.accessToken;
      if (!token) throw new Error('No token returned');
      localStorage.setItem(TOKEN_KEY, token);
      // Clear user cache on login to force refresh
      this.userService.clearUserCache();
      return { token };
    } catch (error: any) {
      const errorData = error?.response?.data || {};
      const errorMessage = (errorData.message || errorData.error || '').toLowerCase();
      const statusCode = error?.response?.status;
      
      // Log for debugging
      this.logger.error('[AuthService] Login error:', error, { 
        status: statusCode, 
        message: errorData.message || errorData.error,
        errorCode: error?.code,
        requestUrl: error?.config?.url
      });
      
      // Check if 2FA is required (when no code provided)
      // Backend returns 400 with "2FA code required"
      if ((errorMessage.includes('2fa') && errorMessage.includes('code') && errorMessage.includes('required')) ||
          (errorMessage.includes('2fa') && statusCode === 400 && !code)) {
        this.logger.debug('2FA required detected, returning requires2FA: true');
        return { token: '', requires2FA: true };
      }
      
      // If invalid 2FA code, don't reset requires2FA - let the component handle it
      // Just throw the error so the component can display it
      if ((errorMessage.includes('invalid') && errorMessage.includes('2fa')) || 
          (errorMessage.includes('2fa') && statusCode === 401 && code)) {
        // Keep requires2FA state, just throw the error
        throw error;
      }
      
      throw error;
    }
  }

  async logout(): Promise<void> {
    const token = this.getToken();
    
    // Call logout endpoint to set status to OFFLINE (if we have a token)
    if (token) {
      try {
        await axios.post(`${getBaseUrl()}/api/v3/auth/logout`, {}, {
          headers: { Authorization: `Bearer ${token}` },
          withCredentials: true
        });
      } catch (error: any) {
        // Ignore 401 errors (token may already be invalid) or network errors
        // Still proceed with local logout cleanup
        if (error?.response?.status !== 401) {
          this.logger.warn('Error calling logout endpoint:', error);
        }
      }
    }
    
    // Clear local storage and cache
    localStorage.removeItem(TOKEN_KEY);
    this.userService.clearUserCache();
  }

  getToken(): string | null {
    return localStorage.getItem(TOKEN_KEY);
  }

  isAuthenticated(): boolean {
    return !!this.getToken();
  }

  async forgotPassword(email: string): Promise<{ message: string }> {
    try {
      const baseUrl = getBaseUrl();
      const response = await axios.post(`${baseUrl}/api/v3/auth/forgot-password`, { 
        email 
      });
      return response.data;
    } catch (error: any) {
      this.logger.error('[AuthService] Forgot password error:', error);
      throw error;
    }
  }

  async resetPassword(token: string, newPassword: string, confirmPassword: string): Promise<{ message: string }> {
    try {
      const baseUrl = getBaseUrl();
      const response = await axios.post(`${baseUrl}/api/v3/auth/reset-password`, { 
        token,
        newPassword,
        confirmPassword
      });
      return response.data;
    } catch (error: any) {
      this.logger.error('[AuthService] Reset password error:', error);
      throw error;
    }
  }
}
