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}` };
}

// Clinical Alert Interfaces
export interface ClinicalAlert {
  id: string;
  patientId: string;
  patientName?: string;
  doctorId?: string;
  doctorName?: string;
  alertType: 'DRUG_INTERACTION' | 'ALLERGY' | 'CONTRAINDICATION' | 'OVERDOSE_RISK' | 'DUPLICATE_THERAPY' | 'DOSE_ADJUSTMENT' | 'LAB_RESULT_ALERT' | 'VITAL_SIGN_ALERT' | 'COMPLIANCE_ALERT' | 'OTHER';
  severity: 'INFO' | 'WARNING' | 'CRITICAL';
  title: string;
  description: string;
  medicationName?: string;
  relatedPrescriptionId?: string;
  acknowledged: boolean;
  acknowledgedAt?: string;
  acknowledgedById?: string;
  acknowledgedByName?: string;
  createdAt: string;
  resolvedAt?: string;
  resolvedById?: string;
  resolvedByName?: string;
}

export interface ClinicalAlertRequest {
  patientId: string;
  alertType: 'DRUG_INTERACTION' | 'ALLERGY' | 'CONTRAINDICATION' | 'OVERDOSE_RISK' | 'DUPLICATE_THERAPY' | 'DOSE_ADJUSTMENT' | 'LAB_RESULT_ALERT' | 'VITAL_SIGN_ALERT' | 'COMPLIANCE_ALERT' | 'OTHER';
  severity: 'INFO' | 'WARNING' | 'CRITICAL';
  title: string;
  description: string;
  medicationName?: string;
  relatedPrescriptionId?: string;
}

// Critical Result Interfaces
export interface CriticalResult {
  id: string;
  labResultId: string;
  patientId: string;
  patientName?: string;
  doctorId: string;
  doctorName?: string;
  criticalityLevel: 'URGENT' | 'CRITICAL' | 'CRITICAL_PANIC';
  testName: string;
  resultValue?: string;
  referenceRange?: string;
  clinicalSignificance?: string;
  acknowledgmentRequired: boolean;
  acknowledged: boolean;
  acknowledgedAt?: string;
  acknowledgedById?: string;
  acknowledgedByName?: string;
  acknowledgmentMethod?: string;
  followUpRequired: boolean;
  followUpStatus?: string;
  notifiedAt?: string;
  createdAt: string;
}

export interface CriticalResultAcknowledgmentRequest {
  acknowledgmentMethod?: string;
  followUpStatus?: string;
}

// Sentinel Event Interfaces
export interface SentinelEvent {
  id: string;
  eventType: 'DEATH' | 'SURGICAL_ERROR' | 'MEDICATION_ERROR' | 'WRONG_PATIENT' | 'WRONG_SITE_SURGERY' | 'RAPE' | 'INFANT_ABDUCTION' | 'FALL' | 'RESTRAINT_DEATH' | 'TRANSFUSION_ERROR' | 'INFECTION_OUTBREAK' | 'OTHER';
  severity: 'SEVERE' | 'MODERATE' | 'MILD';
  patientId?: string;
  patientName?: string;
  doctorId?: string;
  doctorName?: string;
  appointmentId?: string;
  description: string;
  location?: string;
  occurredAt: string;
  reportedAt: string;
  reportedById: string;
  reportedByName?: string;
  status: 'REPORTED' | 'UNDER_INVESTIGATION' | 'RESOLVED' | 'CLOSED';
  investigationNotes?: string;
  rootCauseAnalysis?: string;
  correctiveAction?: string;
  resolvedAt?: string;
  resolvedById?: string;
  resolvedByName?: string;
  createdAt: string;
}

export interface SentinelEventRequest {
  eventType: 'DEATH' | 'SURGICAL_ERROR' | 'MEDICATION_ERROR' | 'WRONG_PATIENT' | 'WRONG_SITE_SURGERY' | 'RAPE' | 'INFANT_ABDUCTION' | 'FALL' | 'RESTRAINT_DEATH' | 'TRANSFUSION_ERROR' | 'INFECTION_OUTBREAK' | 'OTHER';
  severity: 'SEVERE' | 'MODERATE' | 'MILD';
  patientId?: string;
  doctorId?: string;
  appointmentId?: string;
  description: string;
  location?: string;
  occurredAt: string;
}

export interface SentinelEventUpdateRequest {
  status?: 'REPORTED' | 'UNDER_INVESTIGATION' | 'RESOLVED' | 'CLOSED';
  investigationNotes?: string;
  rootCauseAnalysis?: string;
  correctiveAction?: string;
}

// Duplicate Patient Interfaces
export interface DuplicatePatientRecord {
  id: string;
  primaryPatientId: string;
  primaryPatientName?: string;
  duplicatePatientId: string;
  duplicatePatientName?: string;
  matchScore: number;
  matchReasons: string[];
  status: 'PENDING' | 'CONFIRMED' | 'RESOLVED' | 'REJECTED';
  reviewedById?: string;
  reviewedByName?: string;
  reviewedAt?: string;
  reviewNotes?: string;
  createdAt: string;
}

export interface DuplicatePatientReviewRequest {
  status: 'PENDING' | 'CONFIRMED' | 'RESOLVED' | 'REJECTED';
  reviewNotes?: string;
}

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

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

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

  async createAlert(request: ClinicalAlertRequest): Promise<ClinicalAlert> {
    const res = await axios.post(`${BASE_URL}/api/v3/clinical-alerts`, request, { headers: authHeaders() });
    return res.data;
  }

  async acknowledgeAlert(alertId: string): Promise<ClinicalAlert> {
    const res = await axios.post(`${BASE_URL}/api/v3/clinical-alerts/${alertId}/acknowledge`, {}, { headers: authHeaders() });
    return res.data;
  }

  async resolveAlert(alertId: string): Promise<ClinicalAlert> {
    const res = await axios.post(`${BASE_URL}/api/v3/clinical-alerts/${alertId}/resolve`, {}, { headers: authHeaders() });
    return res.data;
  }

  async checkForDrugInteractions(patientId: string): Promise<void> {
    await axios.post(`${BASE_URL}/api/v3/clinical-alerts/check-interactions/${patientId}`, {}, { headers: authHeaders() });
  }

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

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

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

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

  async acknowledgeCriticalResult(resultId: string, request: CriticalResultAcknowledgmentRequest): Promise<CriticalResult> {
    const res = await axios.post(`${BASE_URL}/api/v3/critical-results/${resultId}/acknowledge`, request, { headers: authHeaders() });
    return res.data;
  }

  async getCriticalResultById(id: string): Promise<CriticalResult> {
    const res = await axios.get(`${BASE_URL}/api/v3/critical-results/${id}`, { headers: authHeaders() });
    return res.data;
  }

  // Sentinel Events
  async getAllSentinelEvents(): Promise<SentinelEvent[]> {
    const res = await axios.get(`${BASE_URL}/api/sentinel-events`, { headers: authHeaders() });
    return res.data;
  }

  async getSentinelEventsByStatus(status: 'REPORTED' | 'UNDER_INVESTIGATION' | 'RESOLVED' | 'CLOSED'): Promise<SentinelEvent[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/sentinel-events/status/${status}`, { headers: authHeaders() });
    return res.data;
  }

  async getActiveSentinelEvents(): Promise<SentinelEvent[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/sentinel-events/active`, { headers: authHeaders() });
    return res.data;
  }

  async getSentinelEventsByTimeRange(startDate: string, endDate: string): Promise<SentinelEvent[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/sentinel-events/time-range`, {
      params: { startDate, endDate },
      headers: authHeaders()
    });
    return res.data;
  }

  async reportSentinelEvent(request: SentinelEventRequest): Promise<SentinelEvent> {
    const res = await axios.post(`${BASE_URL}/api/sentinel-events`, request, { headers: authHeaders() });
    return res.data;
  }

  async updateSentinelEvent(eventId: string, request: SentinelEventUpdateRequest): Promise<SentinelEvent> {
    const res = await axios.put(`${BASE_URL}/api/v3/sentinel-events/${eventId}`, request, { headers: authHeaders() });
    return res.data;
  }

  async getSentinelEventById(id: string): Promise<SentinelEvent> {
    const res = await axios.get(`${BASE_URL}/api/v3/sentinel-events/${id}`, { headers: authHeaders() });
    return res.data;
  }

  // Duplicate Patients
  async getAllDuplicateRecords(): Promise<DuplicatePatientRecord[]> {
    const res = await axios.get(`${BASE_URL}/api/duplicate-patients`, { headers: authHeaders() });
    return res.data;
  }

  async getDuplicateRecordsByStatus(status: 'PENDING' | 'CONFIRMED' | 'RESOLVED' | 'REJECTED'): Promise<DuplicatePatientRecord[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/duplicate-patients/status/${status}`, { headers: authHeaders() });
    return res.data;
  }

  async getPendingDuplicateRecords(): Promise<DuplicatePatientRecord[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/duplicate-patients/pending`, { headers: authHeaders() });
    return res.data;
  }

  async getDuplicatesForPatient(patientId: string): Promise<DuplicatePatientRecord[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/duplicate-patients/patient/${patientId}`, { headers: authHeaders() });
    return res.data;
  }

  async reviewDuplicate(duplicateId: string, request: DuplicatePatientReviewRequest): Promise<DuplicatePatientRecord> {
    const res = await axios.post(`${BASE_URL}/api/v3/duplicate-patients/${duplicateId}/review`, request, { headers: authHeaders() });
    return res.data;
  }

  async getDuplicateRecordById(id: string): Promise<DuplicatePatientRecord> {
    const res = await axios.get(`${BASE_URL}/api/v3/duplicate-patients/${id}`, { headers: authHeaders() });
    return res.data;
  }

  async scanForDuplicates(): Promise<void> {
    await axios.post(`${BASE_URL}/api/v3/duplicate-patients/scan`, {}, { headers: authHeaders() });
  }
}

