import { Injectable } from '@angular/core';
import axios from 'axios';
import { LoggerService } from './logger.service';

import { BASE_URL } from '../config/api.config';

function authHeaders() {
  const token = localStorage.getItem('jwtToken');
  // Return headers even if token is missing - let server handle 401 response
  if (!token || token === 'null' || token === 'undefined') {
    // Note: Logger service not available in function scope, using console.warn for critical auth issues
    // This is acceptable as it's a critical security-related warning
    return { Authorization: 'Bearer ' }; // Empty token, server will return 401
  }
  
  // Check if token is expired (basic check for logging only - don't remove token, let server validate)
  try {
    const payload = JSON.parse(atob(token.split('.')[1]));
    const expiration = payload.exp * 1000; // Convert to milliseconds
    const now = Date.now();
    if (expiration < now) {
      // Token expired - server will handle validation
    }
  } catch (e) {
    // If we can't decode, still send it - let server validate
    // Silent failure - server will handle validation
  }
  
  return { Authorization: `Bearer ${token}` };
}

export interface Appointment {
  id?: string;
  patientId?: string;
  patientFirstName: string;
  patientLastName: string;
  doctorId?: string;
  doctorFirstName: string;
  doctorLastName: string;
  scheduledDate: string;
  scheduledTime: string;
  durationInMinutes: number;
  status: 'SCHEDULED' | 'CANCELLED' | 'CONFIRMED' | 'COMPLETED';
}

export interface AppointmentRequest {
  patientId: string;
  doctorId: string;
  scheduledDate: string;
  scheduledTime: string;
  durationMinutes: number; // Changed from durationInMinutes to match backend DTO
}

@Injectable({ providedIn: 'root' })
export class AppointmentService {
  constructor(private logger: LoggerService) {}
  async getAppointmentsByPatientId(patientId: string): Promise<Appointment[]> {
    try {
      const res = await axios.get(`${BASE_URL}/api/v3/appointments/patient/${patientId}`, { headers: authHeaders() });
      return res.data;
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: You can only view appointments for your own patients');
      }
      throw error;
    }
  }

  async getAppointmentsByDoctorId(doctorId: string): Promise<Appointment[]> {
    try {
      const res = await axios.get(`${BASE_URL}/api/v3/appointments/doctor/${doctorId}`, { headers: authHeaders() });
      return res.data;
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: You can only view your own appointments');
      }
      throw error;
    }
  }

  async createAppointment(request: AppointmentRequest): Promise<Appointment> {
    try {
      const res = await axios.post(`${BASE_URL}/api/v3/appointments`, request, { headers: authHeaders() });
      return res.data;
    } catch (error: any) {
      this.logger.error('Appointment creation error:', error, { 
        status: error?.response?.status, 
        data: error?.response?.data 
      });
      
      // Handle 401 Unauthorized - token expired or invalid
      if (error?.response?.status === 401) {
        // Extract error message from response
        const errorMsg = error?.response?.data?.message || 
                        error?.response?.data?.error ||
                        'Authentication failed. Please refresh the page (F5) or log in again.';
        throw new Error(errorMsg);
      }
      throw error;
    }
  }

  async cancelAppointment(appointmentId: string): Promise<Appointment> {
    const res = await axios.patch(`${BASE_URL}/api/v3/appointments/${appointmentId}/cancel`, {}, { headers: authHeaders() });
    return res.data;
  }

  async confirmAppointment(appointmentId: string): Promise<Appointment> {
    try {
      const res = await axios.patch(`${BASE_URL}/api/v3/appointments/${appointmentId}/confirm`, {}, { headers: authHeaders() });
      return res.data;
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: Only doctors can confirm appointments');
      }
      throw error;
    }
  }

  async completeAppointment(appointmentId: string): Promise<Appointment> {
    const res = await axios.patch(`${BASE_URL}/api/v3/appointments/${appointmentId}/complete`, {}, { headers: authHeaders() });
    return res.data;
  }

  async getAvailableTimeSlots(doctorId: string, date: string, durationMinutes?: number): Promise<string[]> {
    const params = durationMinutes ? `?durationMinutes=${durationMinutes}` : '';
    const res = await axios.get(`${BASE_URL}/api/v3/appointments/available-slots/${doctorId}/${date}${params}`, { headers: authHeaders() });
    return res.data;
  }

  async deleteAppointment(appointmentId: string): Promise<void> {
    try {
      await axios.delete(`${BASE_URL}/api/v3/appointments/${appointmentId}`, { headers: authHeaders() });
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: You can only delete your own appointments');
      }
      throw error;
    }
  }

  async removePatientFromHistory(patientId: string): Promise<void> {
    try {
      await axios.post(`${BASE_URL}/api/v3/appointments/doctor/remove-patient/${patientId}`, {}, { headers: authHeaders() });
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: Only doctors can remove patients from history');
      }
      throw error;
    }
  }

  async removeDoctorFromHistory(doctorId: string): Promise<void> {
    try {
      await axios.post(`${BASE_URL}/api/v3/appointments/patient/remove-doctor/${doctorId}`, {}, { headers: authHeaders() });
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: Only patients can remove doctors from history');
      }
      throw error;
    }
  }
}

