package com.gnx.telemedicine.controller;

import com.gnx.telemedicine.model.AccountingOfDisclosure;
import com.gnx.telemedicine.model.enums.DisclosureType;
import com.gnx.telemedicine.service.HipaaAccountingOfDisclosureService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.time.Instant;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/v3/hipaa/accounting")
@RequiredArgsConstructor
@Tag(name = "HIPAA Accounting of Disclosures", description = "HIPAA accounting of disclosures endpoints (45 CFR §164.528)")
@SecurityRequirement(name = "bearerAuth")
public class HipaaAccountingOfDisclosureController {

    private final HipaaAccountingOfDisclosureService disclosureService;

    @Operation(summary = "Log disclosure", description = "Log a PHI disclosure (HIPAA accounting of disclosures)")
    @PreAuthorize("hasAnyRole('DOCTOR', 'ADMIN')")
    @PostMapping("/log")
    public ResponseEntity<AccountingOfDisclosure> logDisclosure(
            @RequestParam @NotNull UUID patientId,
            @RequestParam @NotNull DisclosureType disclosureType,
            @RequestParam @NotNull String purpose,
            @RequestParam(required = false) String recipientName,
            @RequestParam(required = false) String recipientAddress,
            @RequestParam(required = false) String informationDisclosed,
            @RequestParam(required = false) UUID authorizedByUserId,
            Authentication authentication,
            HttpServletRequest request) {
        
        String userEmail = authentication.getName();
        AccountingOfDisclosure disclosure = disclosureService.logDisclosure(
                patientId, userEmail, disclosureType, purpose,
                recipientName, recipientAddress, informationDisclosed,
                authorizedByUserId, request);
        return ResponseEntity.ok(disclosure);
    }

    @Operation(summary = "Get disclosures by patient", description = "Get all disclosures for a patient (HIPAA patient right)")
    @PreAuthorize("hasAnyRole('PATIENT', 'DOCTOR', 'ADMIN')")
    @GetMapping("/patient/{patientId}")
    public ResponseEntity<List<AccountingOfDisclosure>> getDisclosuresByPatient(
            @PathVariable UUID patientId,
            Authentication authentication) {
        
        // Verify patient access
        List<AccountingOfDisclosure> disclosures = disclosureService.getDisclosuresByPatient(patientId);
        return ResponseEntity.ok(disclosures);
    }

    @Operation(summary = "Get disclosures by date range", description = "Get disclosures for a patient within a date range")
    @PreAuthorize("hasAnyRole('PATIENT', 'DOCTOR', 'ADMIN')")
    @GetMapping("/patient/{patientId}/range")
    public ResponseEntity<List<AccountingOfDisclosure>> getDisclosuresByDateRange(
            @PathVariable UUID patientId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant startDate,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant endDate,
            Authentication authentication) {
        
        List<AccountingOfDisclosure> disclosures = disclosureService.getDisclosuresByPatientAndDateRange(
                patientId, startDate, endDate);
        return ResponseEntity.ok(disclosures);
    }

    @Operation(summary = "Get disclosures by user", description = "Get all disclosures made by a user (Admin only)")
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/user")
    public ResponseEntity<List<AccountingOfDisclosure>> getDisclosuresByUser(
            @RequestParam String userEmail,
            Authentication authentication) {
        
        List<AccountingOfDisclosure> disclosures = disclosureService.getDisclosuresByUser(userEmail);
        return ResponseEntity.ok(disclosures);
    }
}

