using adas_core.Application.Services.Interfaces;
using adas_core.Authentication.Attributes;
using adas_core.Domain.Enums;
using adas_core.Domain.Models.DTO;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;

namespace adas_core.Controllers;

[Route("device")]
[ApiController]
public class DeviceController : ControllerBase
{
    private readonly IDeviceService _deviceService;

    public DeviceController(IDeviceService deviceService)
    {
        _deviceService = deviceService;
    }

    /// <summary>
    /// Creates a new device based on the provided device data.
    /// Returns a conflict response when the creation result is null, indicating the device could not be created.
    /// </summary>
    /// <param name="device">The device data transfer object containing the information of the device to be created.</param>
    /// <returns>An IActionResult containing the created device on success, or a Conflict response if the creation fails.</returns>
    [HttpPost("add")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task<IActionResult> CreateDevice([FromBody] DeviceDto device)
    {
        var result = await _deviceService.Create(device);
        if (result is null) Conflict("Unable to create device");
        return Ok(result);
    }

    /// <summary>
    /// Deletes a device by its identifier. Validates the ID format, returning BadRequest for invalid IDs, and returns Conflict if the deletion cannot be completed.
    /// </summary>
    /// <param name="id">The string representation of the device's ObjectId to delete.</param>
    /// <returns>An IActionResult indicating the outcome of the delete operation.</returns>
    [HttpDelete("delete/{id}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task<IActionResult> CreateDevice(string id)
    {
        if (!ObjectId.TryParse(id, out ObjectId deviceId)) return BadRequest("Invalid device Id");
        var result = await _deviceService.Delete(deviceId);
        if (result is false) Conflict("Unable to delete device");
        return Ok(result);
    }

    /// <summary>
    /// Updates an existing device with the provided data. Returns a conflict response if the update operation produces no result, otherwise returns the updated device.
    /// </summary>
    /// <param name="device">The device data transfer object containing the updated device information.</param>
    /// <returns>An <see cref="IActionResult"/> containing the updated device on success, or a <see cref="ConflictResult"/> when the update returns null.</returns>
    [HttpPut("edit")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task<IActionResult> EditDevice([FromBody] DeviceDto device)
    {
        var result = await _deviceService.Update(device);
        if (result is null) Conflict("Unable to update device");
        return Ok(result);
    }

    /// <summary>
    /// Handles an incoming device event submitted by an authorized client.
    /// Delegates processing to the device service and returns a conflict response when the device cannot be created.
    /// </summary>
    /// <param name="device">The device payload received in the request body to be processed as an event.</param>
    /// <returns>An <see cref="IActionResult"/> that returns <see cref="OkResult"/> on successful processing, or <see cref="ConflictResult"/> with a message when the service cannot create the device.</returns>
    [HttpPost("event")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task<IActionResult> ReceiveEventDevice([FromBody] DeviceDto device)
    {
        var result = await _deviceService.ReceiveEvent(device);
        if (result is null) Conflict("Unable to create device");
        return Ok();
    }
}