using System;
using System.ComponentModel.DataAnnotations;
using Jellyfin.Api.Constants;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Jellyfin.Api.Controllers
{
    /// 
    /// Devices Controller.
    /// 
    [Authorize(Policy = Policies.RequiresElevation)]
    public class DevicesController : BaseJellyfinApiController
    {
        private readonly IDeviceManager _deviceManager;
        private readonly IAuthenticationRepository _authenticationRepository;
        private readonly ISessionManager _sessionManager;
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Instance of  interface.
        /// Instance of  interface.
        /// Instance of  interface.
        public DevicesController(
            IDeviceManager deviceManager,
            IAuthenticationRepository authenticationRepository,
            ISessionManager sessionManager)
        {
            _deviceManager = deviceManager;
            _authenticationRepository = authenticationRepository;
            _sessionManager = sessionManager;
        }
        /// 
        /// Get Devices.
        /// 
        /// Gets or sets a value indicating whether [supports synchronize].
        /// Gets or sets the user identifier.
        /// Devices retrieved.
        /// An  containing the list of devices.
        [HttpGet]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult> GetDevices([FromQuery] bool? supportsSync, [FromQuery] Guid? userId)
        {
            var deviceQuery = new DeviceQuery { SupportsSync = supportsSync, UserId = userId ?? Guid.Empty };
            return _deviceManager.GetDevices(deviceQuery);
        }
        /// 
        /// Get info for a device.
        /// 
        /// Device Id.
        /// Device info retrieved.
        /// Device not found.
        /// An  containing the device info on success, or a  if the device could not be found.
        [HttpGet("Info")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult GetDeviceInfo([FromQuery, Required] string id)
        {
            var deviceInfo = _deviceManager.GetDevice(id);
            if (deviceInfo == null)
            {
                return NotFound();
            }
            return deviceInfo;
        }
        /// 
        /// Get options for a device.
        /// 
        /// Device Id.
        /// Device options retrieved.
        /// Device not found.
        /// An  containing the device info on success, or a  if the device could not be found.
        [HttpGet("Options")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult GetDeviceOptions([FromQuery, Required] string id)
        {
            var deviceInfo = _deviceManager.GetDeviceOptions(id);
            if (deviceInfo == null)
            {
                return NotFound();
            }
            return deviceInfo;
        }
        /// 
        /// Update device options.
        /// 
        /// Device Id.
        /// Device Options.
        /// Device options updated.
        /// Device not found.
        /// A  on success, or a  if the device could not be found.
        [HttpPost("Options")]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult UpdateDeviceOptions(
            [FromQuery, Required] string id,
            [FromBody, Required] DeviceOptions deviceOptions)
        {
            var existingDeviceOptions = _deviceManager.GetDeviceOptions(id);
            if (existingDeviceOptions == null)
            {
                return NotFound();
            }
            _deviceManager.UpdateDeviceOptions(id, deviceOptions);
            return NoContent();
        }
        /// 
        /// Deletes a device.
        /// 
        /// Device Id.
        /// Device deleted.
        /// Device not found.
        /// A  on success, or a  if the device could not be found.
        [HttpDelete]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult DeleteDevice([FromQuery, Required] string id)
        {
            var existingDevice = _deviceManager.GetDevice(id);
            if (existingDevice == null)
            {
                return NotFound();
            }
            var sessions = _authenticationRepository.Get(new AuthenticationInfoQuery { DeviceId = id }).Items;
            foreach (var session in sessions)
            {
                _sessionManager.Logout(session);
            }
            return NoContent();
        }
    }
}