using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Silk_Road_Api.Models;
using Silk_Road_Api.Repositories;
using Silk_Road_Api.Services;
using Timer = System.Timers.Timer;
using System.Net.WebSockets;
using System.Text;
using Microsoft.AspNetCore.Http.HttpResults;
using Silk_Road_Api.ViewModels;

namespace Silk_Road_Api.Controllers;

[ApiController]
[Route("[controller]")]
public class DrugController : ControllerBase
{
    private readonly IDrugService _drugService;

    public DrugController(IDrugService drugService)
    {
        _drugService = drugService;
    }


    [HttpGet("get-drugs", Name = "GetDrugs")]
    public async Task<IActionResult> GetDrugs([FromQuery] SearchInput searchInput)
    {
        var drugs = await _drugService.GetDrugs(this, searchInput);
        return Ok(drugs);
    }

    [HttpGet("get-drug/{id}", Name = "GetDrug")]
    public async Task<IActionResult> GetDrug(int id)
    {
        var drug = await _drugService.GetDrug(this,id);
        if (drug == null)
        {
            return NotFound();
        }
        return Ok(drug);
    }

    [HttpPost("add-drug", Name = "AddDrug")]
    public async Task<IActionResult> AddDrug([FromBody] DrugViewModel drug)
    {
        if (await _drugService.AddDrug(this,drug))
            return Ok();
        return BadRequest();
    }

    [HttpPut("update-drug", Name = "UpdateDrug")]
    public async Task<IActionResult> UpdateDrug([FromBody] DrugViewModel drug)
    {
        if (await _drugService.UpdateDrug(this, drug))
            return Ok();
        return BadRequest();
    }

    [HttpDelete("delete-drug/{id}", Name = "DeleteDrug")]
    public async Task<IActionResult> DeleteDrug(int id)
    {
        if (await _drugService.DeleteDrug(this, id))
            return Ok();
        return BadRequest();
    }

    [Route("/ws")]
    [ApiExplorerSettings(IgnoreApi = true)]
    public async Task Get()
    {
        if (HttpContext.WebSockets.IsWebSocketRequest)
        {
            using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
            var timer = new Timer(5000);
            timer.Elapsed += async (sender, e) =>
            {
                await SendMessage(webSocket, timer);
            };
            timer.Start();
            while (webSocket.State == WebSocketState.Open)
            {
                await Task.Delay(1000);
                var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(new byte[1024]), CancellationToken.None);
                if (result.MessageType == WebSocketMessageType.Close)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Done", CancellationToken.None);
                    timer.Stop();
                }
            }

        }
        else
        {
            HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
        }
    }

    [HttpGet("get-chart-data", Name = "GetChartData")]
    public async Task<IActionResult> GetChartData()
    {
        var chartData = await _drugService.GetChartData();
        return Ok(chartData);
    }

    private async Task SendMessage(WebSocket webSocket, Timer timer)
    {
        _drugService.GenerateDrugs();
        if (webSocket.State == WebSocketState.Open)
        {
            var buffer = Encoding.UTF8.GetBytes("Drugs generated");
            await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), WebSocketMessageType.Text, true, CancellationToken.None);
        }
    }
}
