using System.Collections.Generic;
using System.Threading.Tasks;
using API.Data;
using API.DTOs.Dashboard;
using API.DTOs.SideNav;
using API.Extensions;
using API.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace API.Controllers;
#nullable enable
/// 
/// Responsible for anything that deals with Streams (SmartFilters, ExternalSource, DashboardStream, SideNavStream)
/// 
public class StreamController : BaseApiController
{
    private readonly IStreamService _streamService;
    private readonly IUnitOfWork _unitOfWork;
    private readonly ILogger _logger;
    public StreamController(IStreamService streamService, IUnitOfWork unitOfWork, ILogger logger)
    {
        _streamService = streamService;
        _unitOfWork = unitOfWork;
        _logger = logger;
    }
    /// 
    /// Returns the layout of the user's dashboard
    /// 
    /// 
    [HttpGet("dashboard")]
    public async Task>> GetDashboardLayout(bool visibleOnly = true)
    {
        return Ok(await _streamService.GetDashboardStreams(User.GetUserId(), visibleOnly));
    }
    /// 
    /// Return's the user's side nav
    /// 
    [HttpGet("sidenav")]
    public async Task>> GetSideNav(bool visibleOnly = true)
    {
        return Ok(await _streamService.GetSidenavStreams(User.GetUserId(), visibleOnly));
    }
    /// 
    /// Return's the user's external sources
    /// 
    [HttpGet("external-sources")]
    public async Task>> GetExternalSources()
    {
        return Ok(await _streamService.GetExternalSources(User.GetUserId()));
    }
    /// 
    /// Create an external Source
    /// 
    /// 
    /// 
    [HttpPost("create-external-source")]
    public async Task> CreateExternalSource(ExternalSourceDto dto)
    {
        // Check if a host and api key exists for the current user
        return Ok(await _streamService.CreateExternalSource(User.GetUserId(), dto));
    }
    /// 
    /// Updates an existing external source
    /// 
    /// 
    /// 
    [HttpPost("update-external-source")]
    public async Task> UpdateExternalSource(ExternalSourceDto dto)
    {
        // Check if a host and api key exists for the current user
        return Ok(await _streamService.UpdateExternalSource(User.GetUserId(), dto));
    }
    /// 
    /// Validates the external source by host is unique (for this user)
    /// 
    /// 
    /// 
    [HttpGet("external-source-exists")]
    public async Task> ExternalSourceExists(string host, string name, string apiKey)
    {
        return Ok(await _unitOfWork.AppUserExternalSourceRepository.ExternalSourceExists(User.GetUserId(), host, name, apiKey));
    }
    /// 
    /// Delete's the external source
    /// 
    /// 
    /// 
    [HttpDelete("delete-external-source")]
    public async Task ExternalSourceExists(int externalSourceId)
    {
        await _streamService.DeleteExternalSource(User.GetUserId(), externalSourceId);
        return Ok();
    }
    /// 
    /// Creates a Dashboard Stream from a SmartFilter and adds it to the user's dashboard as visible
    /// 
    /// 
    /// 
    [HttpPost("add-dashboard-stream")]
    public async Task> AddDashboard([FromQuery] int smartFilterId)
    {
        return Ok(await _streamService.CreateDashboardStreamFromSmartFilter(User.GetUserId(), smartFilterId));
    }
    /// 
    /// Updates the visibility of a dashboard stream
    /// 
    /// 
    /// 
    [HttpPost("update-dashboard-stream")]
    public async Task UpdateDashboardStream(DashboardStreamDto dto)
    {
        await _streamService.UpdateDashboardStream(User.GetUserId(), dto);
        return Ok();
    }
    /// 
    /// Updates the position of a dashboard stream
    /// 
    /// 
    /// 
    [HttpPost("update-dashboard-position")]
    public async Task UpdateDashboardStreamPosition(UpdateStreamPositionDto dto)
    {
        await _streamService.UpdateDashboardStreamPosition(User.GetUserId(), dto);
        return Ok();
    }
    /// 
    /// Creates a SideNav Stream from a SmartFilter and adds it to the user's sidenav as visible
    /// 
    /// 
    /// 
    [HttpPost("add-sidenav-stream")]
    public async Task> AddSideNav([FromQuery] int smartFilterId)
    {
        return Ok(await _streamService.CreateSideNavStreamFromSmartFilter(User.GetUserId(), smartFilterId));
    }
    /// 
    /// Creates a SideNav Stream from a SmartFilter and adds it to the user's sidenav as visible
    /// 
    /// 
    /// 
    [HttpPost("add-sidenav-stream-from-external-source")]
    public async Task> AddSideNavFromExternalSource([FromQuery] int externalSourceId)
    {
        return Ok(await _streamService.CreateSideNavStreamFromExternalSource(User.GetUserId(), externalSourceId));
    }
    /// 
    /// Updates the visibility of a dashboard stream
    /// 
    /// 
    /// 
    [HttpPost("update-sidenav-stream")]
    public async Task UpdateSideNavStream(SideNavStreamDto dto)
    {
        await _streamService.UpdateSideNavStream(User.GetUserId(), dto);
        return Ok();
    }
    /// 
    /// Updates the position of a dashboard stream
    /// 
    /// 
    /// 
    [HttpPost("update-sidenav-position")]
    public async Task UpdateSideNavStreamPosition(UpdateStreamPositionDto dto)
    {
        await _streamService.UpdateSideNavStreamPosition(User.GetUserId(), dto);
        return Ok();
    }
    [HttpPost("bulk-sidenav-stream-visibility")]
    public async Task BulkUpdateSideNavStream(BulkUpdateSideNavStreamVisibilityDto dto)
    {
        await _streamService.UpdateSideNavStreamBulk(User.GetUserId(), dto);
        return Ok();
    }
}