using Microsoft.AspNetCore.Mvc;
using SimpleLIS.DTO;
using SimpleLIS.Services;
using SimpleLIS.Models;
using AutoMapper;
using System.Text.Json;

namespace SimpleLIS.Controllers;

[ApiController]
[Route("api/hl7")]
public class HL7Controller : ControllerBase
{
    private readonly MessageService msgService;
    private readonly PatientService ptService;
    private readonly IMapper _mapper;

    public HL7Controller(
        MessageService messageService, 
        PatientService patientService, 
        IMapper mapper)
    {
        msgService = messageService;
        ptService = patientService;
        _mapper = mapper;
    }

[HttpPost("process")]
public async Task<IActionResult> ProcessHL7Message([FromBody] JsonElement payload)
{
    try
    {
        var patient = new Patient
        {
            HL7PatientId = payload.GetProperty("hl7PatientId").GetString(),
            LastName = payload.GetProperty("lastName").GetString(),
            FirstName = payload.GetProperty("firstName").GetString(),
            DateOfBirth = payload.GetProperty("dateOfBirth").GetDateTime(),
            Gender = payload.GetProperty("gender").GetString(),
            Messages = new List<Message>()
        };

        var existingPatient = await ptService.GetPatientByNameAndDOB(
            patient.FirstName!, 
            patient.LastName!, 
            patient.DateOfBirth
        );

        patient = existingPatient ?? await ptService.CreatePatientAsync(patient);
        var message = new Message
        {
            ControlId = payload.GetProperty("controlId").GetString() ?? string.Empty,
            MessageType = payload.GetProperty("messageType").GetString()?? string.Empty,
            SendingApp = payload.GetProperty("sendingApp").GetString(),
            SendingFacility = payload.GetProperty("sendingFacility").GetString(),
            ReceivingApp = payload.GetProperty("receivingApp").GetString(),
            ReceivingFacility = payload.GetProperty("receivingFacility").GetString(),
            Timestamp = payload.GetProperty("timestamp").GetDateTime(),
            Version = payload.GetProperty("version").GetString(),
            PatientId = patient.PatientId,
            Patient = patient,
            Observations = new List<Observation>()
        };

        var observationsArray = payload.GetProperty("observations");
        foreach (var obsElement in observationsArray.EnumerateArray())
        {
            var observation = new Observation
            {
                ObservationCode = obsElement.GetProperty("ObservationCode").GetString()?? string.Empty,
                ObservationValue = obsElement.GetProperty("ObservationValue").GetString()?? string.Empty,
                Units = obsElement.GetProperty("Units").GetString(),
                AbnormalFlag = obsElement.GetProperty("AbnormalFlag").GetString(),
                ResultStatus = obsElement.GetProperty("ResultStatus").GetString() ?? "F",
                Message = message
            };
            message.Observations.Add(observation);
        }

        var createdMessage = await msgService.CreateMessageAsync(message);
        
        return Ok(new { 
            message = _mapper.Map<MessageDTO>(createdMessage),
            patient = _mapper.Map<PatientDTO>(patient)
        });
    }
    catch (Exception ex)
    {
        return BadRequest(new { error = ex.Message + (ex.InnerException?.Message ?? "") });
    }
}
}
