using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using SimpleLIS.DTO;
using SimpleLIS.Models;
using SimpleLIS.Services;

namespace SimpleLIS.Controllers;

[ApiController]
[Route("api/patients")]
public class PatientsController : ControllerBase
{
    private readonly PatientService _patientService;
    private readonly IMapper _mapper;

    public PatientsController(PatientService patientService, IMapper mapper)
    {
        _patientService = patientService;
        _mapper = mapper;
    }

    // POST: api/Patients
    [HttpPost]
    public async Task<IActionResult> CreatePatient([FromBody] PatientDTO patientDto)
    {
        if (!ModelState.IsValid) return BadRequest(ModelState);

        var patient = _mapper.Map<Patient>(patientDto);
        var createdPatient = await _patientService.CreatePatientAsync(patient);

        var createdPatientDto = _mapper.Map<PatientDTO>(createdPatient);
        return Ok(createdPatientDto);
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetPatient(int id)
    {
        var patient = await _patientService.GetPatientByIdAsync(id);
        if (patient == null) return NotFound();

        var patientDto = _mapper.Map<PatientDTO>(patient);
        return Ok(patientDto);
    }

    [HttpGet("{id}/observations")]
    public async Task<IActionResult> GetPatientObservationById(string id){
        List<Observation> observations;
        if(int.TryParse(id, out int patientId))
            observations = await _patientService.GetPatientObservationById(patientId);
        else
            observations = await _patientService.GetPatientObservationByHL7PatientId(id);
        return Ok(_mapper.Map<List<ObservationDTO>>(observations));
    }

    [HttpGet]
    public async Task<IActionResult> ListPatients()
    {
        var patients = await _patientService.ListPatientsAsync();
        var patientsDto = _mapper.Map<IEnumerable<PatientDTO>>(patients);

        return Ok(patientsDto);
    }

    [HttpPut("{id}")]
    public async Task<IActionResult> UpdatePatient(int id, [FromBody] PatientDTO patientDto)
    {
        if (!ModelState.IsValid) return BadRequest(ModelState);

        if (!await _patientService.PatientExistsAsync(id))
        {
            return NotFound();
        }

        var patient = _mapper.Map<Patient>(patientDto);
        patient.PatientId = id;

        var updatedPatient = await _patientService.UpdatePatientAsync(patient);
        var updatedPatientDto = _mapper.Map<PatientDTO>(updatedPatient);

        return Ok(updatedPatientDto);
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> DeletePatient(int id)
    {
        var deleted = await _patientService.DeletePatientAsync(id);
        if (!deleted) return NotFound();

        return NoContent();
    }
}
