using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using LittleShop.DTOs;
using LittleShop.Services;

namespace LittleShop.Controllers;

[ApiController]
[Route("api/[controller]")]
public class BotsController : ControllerBase
{
    private readonly IBotService _botService;
    private readonly IBotMetricsService _metricsService;
    private readonly ILogger<BotsController> _logger;

    public BotsController(
        IBotService botService,
        IBotMetricsService metricsService,
        ILogger<BotsController> logger)
    {
        _botService = botService;
        _metricsService = metricsService;
        _logger = logger;
    }

    // Bot Registration and Authentication
    [HttpPost("register")]
    [AllowAnonymous]
    public async Task<ActionResult<BotRegistrationResponseDto>> RegisterBot([FromBody] BotRegistrationDto dto)
    {
        try
        {
            var result = await _botService.RegisterBotAsync(dto);
            return Ok(result);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to register bot");
            return BadRequest("Failed to register bot");
        }
    }

    [HttpPost("authenticate")]
    [AllowAnonymous]
    public async Task<ActionResult<BotDto>> AuthenticateBot([FromBody] BotAuthenticateDto dto)
    {
        var bot = await _botService.AuthenticateBotAsync(dto.BotKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        return Ok(bot);
    }

    // Bot Settings
    [HttpGet("settings")]
    public async Task<ActionResult<Dictionary<string, object>>> GetBotSettings()
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var settings = await _botService.GetBotSettingsAsync(bot.Id);
        return Ok(settings);
    }

    [HttpPut("settings")]
    public async Task<IActionResult> UpdateBotSettings([FromBody] UpdateBotSettingsDto dto)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var success = await _botService.UpdateBotSettingsAsync(bot.Id, dto);
        if (!success)
            return NotFound("Bot not found");

        return NoContent();
    }

    // Heartbeat
    [HttpPost("heartbeat")]
    public async Task<IActionResult> RecordHeartbeat([FromBody] BotHeartbeatDto dto)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        await _botService.RecordHeartbeatAsync(bot.Id, dto);
        return Ok();
    }

    [HttpPut("platform-info")]
    public async Task<IActionResult> UpdatePlatformInfo([FromBody] UpdatePlatformInfoDto dto)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var success = await _botService.UpdatePlatformInfoAsync(bot.Id, dto);
        if (!success)
            return NotFound("Bot not found");

        return NoContent();
    }

    // Metrics
    [HttpPost("metrics")]
    public async Task<ActionResult<BotMetricDto>> RecordMetric([FromBody] CreateBotMetricDto dto)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var metric = await _metricsService.RecordMetricAsync(bot.Id, dto);
        return Ok(metric);
    }

    [HttpPost("metrics/batch")]
    public async Task<IActionResult> RecordMetricsBatch([FromBody] BotMetricsBatchDto dto)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var success = await _metricsService.RecordMetricsBatchAsync(bot.Id, dto);
        if (!success)
            return BadRequest("Failed to record metrics");

        return Ok();
    }

    // Sessions
    [HttpPost("sessions/start")]
    public async Task<ActionResult<BotSessionDto>> StartSession([FromBody] CreateBotSessionDto dto)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var session = await _metricsService.StartSessionAsync(bot.Id, dto);
        return Ok(session);
    }

    [HttpPut("sessions/{sessionId}")]
    public async Task<IActionResult> UpdateSession(Guid sessionId, [FromBody] UpdateBotSessionDto dto)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var success = await _metricsService.UpdateSessionAsync(sessionId, dto);
        if (!success)
            return NotFound("Session not found");

        return NoContent();
    }

    [HttpPost("sessions/{sessionId}/end")]
    public async Task<IActionResult> EndSession(Guid sessionId)
    {
        var botKey = Request.Headers["X-Bot-Key"].ToString();
        if (string.IsNullOrEmpty(botKey))
            return Unauthorized("Bot key required");

        var bot = await _botService.GetBotByKeyAsync(botKey);
        if (bot == null)
            return Unauthorized("Invalid bot key");

        var success = await _metricsService.EndSessionAsync(sessionId);
        if (!success)
            return NotFound("Session not found");

        return NoContent();
    }

    // Admin endpoints (require Bearer authentication)
    [HttpGet]
    [Authorize(AuthenticationSchemes = "Bearer", Roles = "Admin")]
    public async Task<ActionResult> GetAllBots()
    {
        var bots = await _botService.GetAllBotsAsync();
        return Ok(bots);
    }

    [HttpGet("{id}")]
    [Authorize(AuthenticationSchemes = "Bearer", Roles = "Admin")]
    public async Task<ActionResult<BotDto>> GetBot(Guid id)
    {
        var bot = await _botService.GetBotByIdAsync(id);
        if (bot == null)
            return NotFound();

        return Ok(bot);
    }

    [HttpGet("{id}/metrics")]
    [Authorize(AuthenticationSchemes = "Bearer", Roles = "Admin")]
    public async Task<ActionResult> GetBotMetrics(Guid id, [FromQuery] DateTime? startDate, [FromQuery] DateTime? endDate)
    {
        var metrics = await _metricsService.GetBotMetricsAsync(id, startDate, endDate);
        return Ok(metrics);
    }

    [HttpGet("{id}/metrics/summary")]
    [Authorize(AuthenticationSchemes = "Bearer", Roles = "Admin")]
    public async Task<ActionResult<BotMetricsSummaryDto>> GetMetricsSummary(Guid id, [FromQuery] DateTime? startDate, [FromQuery] DateTime? endDate)
    {
        var summary = await _metricsService.GetMetricsSummaryAsync(id, startDate, endDate);
        return Ok(summary);
    }

    [HttpGet("{id}/sessions")]
    [Authorize(AuthenticationSchemes = "Bearer", Roles = "Admin")]
    public async Task<ActionResult> GetBotSessions(Guid id, [FromQuery] bool activeOnly = false)
    {
        var sessions = await _metricsService.GetBotSessionsAsync(id, activeOnly);
        return Ok(sessions);
    }

    [HttpDelete("{id}")]
    [Authorize(AuthenticationSchemes = "Bearer", Roles = "Admin")]
    public async Task<IActionResult> DeleteBot(Guid id)
    {
        var success = await _botService.DeleteBotAsync(id);
        if (!success)
            return NotFound();

        return NoContent();
    }
}