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

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

function authHeaders(logger?: LoggerService) {
  const token = localStorage.getItem('jwtToken');
  if (!token || token === 'null' || token === 'undefined') {
    if (logger) {
      logger.error('JWT token is missing or invalid');
    }
    throw new Error('Authentication required. Please login again.');
  }
  return { Authorization: `Bearer ${token}` };
}

export interface HipaaAuditLog {
  id: string;
  userId: string;
  userName?: string;
  actionType: 'VIEW' | 'CREATE' | 'UPDATE' | 'DELETE' | 'EXPORT' | 'PRINT' | 'DOWNLOAD';
  resourceType: string;
  resourceId?: string;
  patientId?: string;
  ipAddress?: string;
  userAgent?: string;
  success: boolean;
  failureReason?: string;
  details?: any;
  timestamp: string;
}

export interface PhiAccessLog {
  id: string;
  userId: string;
  userName?: string;
  patientId: string;
  patientName?: string;
  accessType: 'Treatment' | 'Payment' | 'Operations' | 'Authorization';
  accessedFields: string[];
  purpose: string;
  ipAddress?: string;
  userAgent?: string;
  timestamp: string;
}

export interface BreachNotification {
  id: string;
  breachType: 'UNAUTHORIZED_ACCESS' | 'DISCLOSURE' | 'LOSS' | 'THEFT';
  description: string;
  affectedPatientsCount: number;
  mitigationSteps: string;
  status: 'INVESTIGATING' | 'CONTAINED' | 'RESOLVED' | 'REPORTED';
  incidentDate?: string; // ISO date string (YYYY-MM-DD)
  discoveryDate?: string; // ISO date string (YYYY-MM-DD)
  reportedAt?: string;
  createdAt: string;
}

export interface BreachNotificationRequest {
  breachType: 'UNAUTHORIZED_ACCESS' | 'DISCLOSURE' | 'LOSS' | 'THEFT';
  description: string;
  affectedPatientsCount: number;
  mitigationSteps: string;
  incidentDate: string; // ISO date string (YYYY-MM-DD)
  discoveryDate: string; // ISO date string (YYYY-MM-DD)
}

@Injectable({ providedIn: 'root' })
export class HipaaAuditService {
  constructor(private logger: LoggerService) {}

  async getHipaaAuditLogsByPatientId(patientId: string): Promise<HipaaAuditLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/hipaa/patient/${patientId}`, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async getHipaaAuditLogsByUserId(userId: string): Promise<HipaaAuditLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/hipaa/user/${userId}`, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async getPhiAccessLogsByPatientId(patientId: string): Promise<PhiAccessLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/phi-access/patient/${patientId}`, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async getPhiAccessLogsByUserId(userId: string): Promise<PhiAccessLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/phi-access/user/${userId}`, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async getPhiAccessLogsByPatientIdAndDateRange(patientId: string, startDate: string, endDate: string): Promise<PhiAccessLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/phi-access/patient/${patientId}/date-range`, {
      params: { startDate, endDate },
      headers: authHeaders(this.logger)
    });
    return res.data;
  }

  async getHipaaAuditLogsByPatientIdAndDateRange(patientId: string, startDate: string, endDate: string): Promise<HipaaAuditLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/hipaa/patient/${patientId}/date-range`, {
      params: { startDate, endDate },
      headers: authHeaders(this.logger)
    });
    return res.data;
  }

  async getHipaaAuditLogsByResource(resourceType: string, resourceId: string): Promise<HipaaAuditLog[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/hipaa/resource/${resourceType}/${resourceId}`, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async getAccessCount(patientId: string, since: string): Promise<number> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/hipaa/patient/${patientId}/access-count`, {
      params: { since },
      headers: authHeaders(this.logger)
    });
    return res.data;
  }

  // Breach Notifications (Admin only)
  async getBreachNotifications(): Promise<BreachNotification[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/breaches`, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async getBreachNotificationById(id: string): Promise<BreachNotification> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/breaches/${id}`, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async createBreachNotification(request: BreachNotificationRequest): Promise<BreachNotification> {
    const res = await axios.post(`${BASE_URL}/api/v3/audit/breaches`, request, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async updateBreachNotificationStatus(id: string, status: 'INVESTIGATING' | 'CONTAINED' | 'RESOLVED' | 'REPORTED'): Promise<BreachNotification> {
    const res = await axios.patch(`${BASE_URL}/api/v3/audit/breaches/${id}/status?status=${status}`, {}, { headers: authHeaders(this.logger) });
    return res.data;
  }

  async getBreachNotificationsByStatus(status: 'INVESTIGATING' | 'CONTAINED' | 'RESOLVED' | 'REPORTED'): Promise<BreachNotification[]> {
    const res = await axios.get(`${BASE_URL}/api/v3/audit/breaches/status/${status}`, { headers: authHeaders(this.logger) });
    return res.data;
  }
}

