import { Injectable } from '@angular/core';
import axios from 'axios';

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

function authHeaders() {
  const token = localStorage.getItem('jwtToken');
  return { Authorization: `Bearer ${token}` };
}

export interface Prescription {
  id: string;
  patientId: string;
  patientName?: string;
  doctorId: string;
  doctorName?: string;
  appointmentId?: string;
  medicationName: string;
  medicationCode?: string;
  dosage: string;
  frequency: string;
  quantity: number;
  refills: number;
  instructions?: string;
  startDate: string;
  endDate?: string;
  status: 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'DISCONTINUED';
  pharmacyName?: string;
  pharmacyAddress?: string;
  pharmacyPhone?: string;
  prescriptionNumber: string;
  ePrescriptionSent?: boolean;
  ePrescriptionSentAt?: string;
  createdAt: string;
}

export interface PrescriptionRequest {
  patientId: string;
  doctorId: string;
  appointmentId?: string;
  medicationName: string;
  medicationCode?: string;
  dosage: string;
  frequency: string;
  quantity: number;
  refills: number;
  instructions?: string;
  startDate: string;
  endDate?: string;
  pharmacyName?: string;
  pharmacyAddress?: string;
  pharmacyPhone?: string;
}

export interface MedicationIntakeLog {
  id: string;
  prescriptionId: string;
  medicationName?: string;
  takenAt: string;
  scheduledTime: string;
  wasTaken: boolean;
  notes?: string;
}

export interface MedicationIntakeLogRequest {
  prescriptionId: string;
  scheduledTime: string;
  wasTaken: boolean;
  notes?: string;
}

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

  async getPrescriptionsByDoctorId(doctorId: string): Promise<Prescription[]> {
    try {
      const res = await axios.get(`${BASE_URL}/api/v3/prescriptions/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 prescriptions');
      }
      throw error;
    }
  }

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

  async getPrescriptionsByPatientIdAndStatus(patientId: string, status: 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'DISCONTINUED'): Promise<Prescription[]> {
    try {
      const res = await axios.get(`${BASE_URL}/api/v3/prescriptions/patient/${patientId}/status/${status}`, { headers: authHeaders() });
      return res.data;
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: You can only view prescriptions for your own patients');
      }
      throw error;
    }
  }

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

  async getPrescriptionById(id: string): Promise<Prescription> {
    try {
      const res = await axios.get(`${BASE_URL}/api/v3/prescriptions/${id}`, { headers: authHeaders() });
      return res.data;
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: You can only view prescriptions for your own patients');
      }
      throw error;
    }
  }

  async getPrescriptionByNumber(prescriptionNumber: string): Promise<Prescription> {
    const res = await axios.get(`${BASE_URL}/api/v3/prescriptions/number/${prescriptionNumber}`, { headers: authHeaders() });
    return res.data;
  }

  async createPrescription(request: PrescriptionRequest): Promise<Prescription> {
    try {
      const res = await axios.post(`${BASE_URL}/api/prescriptions`, request, { headers: authHeaders() });
      return res.data;
    } catch (error: any) {
      if (error?.response?.status === 403) {
        throw new Error('Access denied: You can only create prescriptions for yourself');
      }
      if (error?.response?.status === 400 && error?.response?.data?.message) {
        throw new Error(error.response.data.message);
      }
      throw error;
    }
  }

  async updatePrescriptionStatus(id: string, status: 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'DISCONTINUED'): Promise<Prescription> {
    // Backend expects status as a query parameter, not in the request body
    const res = await axios.patch(`${BASE_URL}/api/v3/prescriptions/${id}/status?status=${status}`, {}, { headers: authHeaders() });
    return res.data;
  }

  async markEPrescriptionSent(id: string): Promise<Prescription> {
    const res = await axios.post(`${BASE_URL}/api/v3/prescriptions/${id}/mark-sent`, {}, { headers: authHeaders() });
    return res.data;
  }

  async updatePrescription(id: string, request: PrescriptionRequest): Promise<Prescription> {
    const res = await axios.put(`${BASE_URL}/api/v3/prescriptions/${id}`, request, { headers: authHeaders() });
    return res.data;
  }

  async deletePrescription(id: string): Promise<void> {
    await axios.delete(`${BASE_URL}/api/v3/prescriptions/${id}`, { headers: authHeaders() });
  }

  // Medication Intake Logs
  async createMedicationIntakeLog(request: MedicationIntakeLogRequest): Promise<MedicationIntakeLog> {
    const res = await axios.post(`${BASE_URL}/api/medication-intake-logs`, request, { headers: authHeaders() });
    return res.data;
  }

  async getMedicationIntakeLogsByPrescriptionId(prescriptionId: string): Promise<MedicationIntakeLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/medication-intake-logs/prescription/${prescriptionId}`, { headers: authHeaders() });
    return res.data;
  }

  async getMedicationIntakeLogsByPatientId(patientId: string): Promise<MedicationIntakeLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/medication-intake-logs/patient/${patientId}`, { headers: authHeaders() });
    return res.data;
  }

  async getMissedDoses(prescriptionId: string): Promise<MedicationIntakeLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/medication-intake-logs/prescription/${prescriptionId}/missed`, { headers: authHeaders() });
    return res.data;
  }

  async getAdherenceRate(prescriptionId: string): Promise<number> {
    const res = await axios.get(`${BASE_URL}/api/v3/medication-intake-logs/prescription/${prescriptionId}/adherence`, { headers: authHeaders() });
    return res.data.adherenceRate || 0;
  }

  async markDoseAsTaken(logId: string): Promise<MedicationIntakeLog> {
    const res = await axios.patch(`${BASE_URL}/api/v3/medication-intake-logs/${logId}/mark-taken`, {}, { headers: authHeaders() });
    return res.data;
  }

  async getIntakeLogById(logId: string): Promise<MedicationIntakeLog> {
    const res = await axios.get(`${BASE_URL}/api/v3/medication-intake-logs/${logId}`, { headers: authHeaders() });
    return res.data;
  }
}

