using System;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using LittleShop.DTOs;
using LittleShop.Enums;
using LittleShop.Services;

namespace LittleShop.Areas.Admin.Controllers;

[Area("Admin")]
[Authorize(Policy = "AdminOnly")]
public class BotsController : Controller
{
    private readonly IBotService _botService;
    private readonly IBotMetricsService _metricsService;
    private readonly ITelegramBotManagerService _telegramManager;
    private readonly ILogger<BotsController> _logger;

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

    // GET: Admin/Bots
    public async Task<IActionResult> Index()
    {
        var bots = await _botService.GetAllBotsAsync();
        return View(bots);
    }

    // GET: Admin/Bots/Details/5
    public async Task<IActionResult> Details(Guid id)
    {
        var bot = await _botService.GetBotByIdAsync(id);
        if (bot == null)
            return NotFound();

        // Get metrics summary for the last 30 days
        var metricsSummary = await _metricsService.GetMetricsSummaryAsync(id, DateTime.UtcNow.AddDays(-30), DateTime.UtcNow);
        ViewData["MetricsSummary"] = metricsSummary;

        // Get active sessions
        var activeSessions = await _metricsService.GetBotSessionsAsync(id, activeOnly: true);
        ViewData["ActiveSessions"] = activeSessions;

        return View(bot);
    }

    // GET: Admin/Bots/Create
    public IActionResult Create()
    {
        return View(new BotRegistrationDto());
    }

    // GET: Admin/Bots/Wizard
    public IActionResult Wizard()
    {
        return View(new BotWizardDto());
    }

    // POST: Admin/Bots/Wizard
    [HttpPost]
    // [ValidateAntiForgeryToken] // Temporarily disabled for testing
    public async Task<IActionResult> Wizard(BotWizardDto dto)
    {
        _logger.LogInformation("Wizard POST received - BotName: '{BotName}', BotUsername: '{BotUsername}'", dto.BotName, dto.BotUsername);
        
        if (!ModelState.IsValid)
        {
            _logger.LogWarning("Validation failed");
            foreach (var error in ModelState)
            {
                _logger.LogWarning("Field {Field}: {Errors}", error.Key, string.Join(", ", error.Value.Errors.Select(e => e.ErrorMessage)));
            }
            return View(dto);
        }

        // Generate BotFather commands
        var commands = GenerateBotFatherCommands(dto);
        ViewData["BotFatherCommands"] = commands;
        ViewData["ShowCommands"] = true;
        
        _logger.LogInformation("Generated BotFather commands successfully for bot '{BotName}'", dto.BotName);
        
        return View(dto);
    }

    // POST: Admin/Bots/CompleteWizard
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> CompleteWizard(BotWizardDto dto)
    {
        if (string.IsNullOrEmpty(dto.BotToken))
        {
            ModelState.AddModelError("BotToken", "Bot token is required");
            ViewData["BotFatherCommands"] = GenerateBotFatherCommands(dto);
            ViewData["ShowCommands"] = true;
            return View("Wizard", dto);
        }

        // Validate token first
        if (!await ValidateTelegramToken(dto.BotToken))
        {
            ModelState.AddModelError("BotToken", "Invalid bot token");
            ViewData["BotFatherCommands"] = GenerateBotFatherCommands(dto);
            ViewData["ShowCommands"] = true;
            return View("Wizard", dto);
        }

        // Create the bot
        var registrationDto = new BotRegistrationDto
        {
            Name = dto.BotName,
            Description = dto.Description,
            Type = BotType.Telegram,
            Version = "1.0.0",
            PersonalityName = dto.PersonalityName,
            InitialSettings = new Dictionary<string, object>
            {
                ["telegram"] = new { botToken = dto.BotToken },
                ["personality"] = new { name = dto.PersonalityName }
            }
        };

        try
        {
            var result = await _botService.RegisterBotAsync(registrationDto);
            
            // Add bot to Telegram manager
            var telegramAdded = await _telegramManager.AddBotAsync(result.BotId, dto.BotToken);
            
            if (telegramAdded)
            {
                TempData["Success"] = $"Bot '{result.Name}' created successfully and is now running on Telegram!";
            }
            else
            {
                TempData["Warning"] = $"Bot '{result.Name}' created but failed to connect to Telegram. Check token.";
            }
            
            return RedirectToAction(nameof(Details), new { id = result.BotId });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to create bot");
            ModelState.AddModelError("", $"Failed to create bot: {ex.Message}");
            return View("Wizard", dto);
        }
    }

    // POST: Admin/Bots/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(BotRegistrationDto dto)
    {
        _logger.LogInformation("Received bot registration: Name={Name}, Type={Type}, Version={Version}", 
            dto?.Name, dto?.Type, dto?.Version);

        if (!ModelState.IsValid)
        {
            _logger.LogWarning("Model validation failed for bot registration");
            foreach (var error in ModelState.Values.SelectMany(v => v.Errors))
            {
                _logger.LogWarning("Validation error: {Error}", error.ErrorMessage);
            }
            return View(dto);
        }

        try
        {
            var result = await _botService.RegisterBotAsync(dto);
            _logger.LogInformation("Bot registered successfully: {BotId}, Key: {KeyPrefix}...", 
                result.BotId, result.BotKey.Substring(0, 8));
            
            TempData["BotKey"] = result.BotKey;
            TempData["Success"] = $"Bot '{result.Name}' created successfully. Save the API key securely!";
            return RedirectToAction(nameof(Details), new { id = result.BotId });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to create bot");
            ModelState.AddModelError("", $"Failed to create bot: {ex.Message}");
            return View(dto);
        }
    }

    // GET: Admin/Bots/Edit/5
    public async Task<IActionResult> Edit(Guid id)
    {
        var bot = await _botService.GetBotByIdAsync(id);
        if (bot == null)
            return NotFound();

        ViewData["BotSettings"] = JsonSerializer.Serialize(bot.Settings, new JsonSerializerOptions { WriteIndented = true });
        return View(bot);
    }

    // POST: Admin/Bots/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(Guid id, string settingsJson, BotStatus status)
    {
        try
        {
            // Parse and update settings
            var settings = JsonSerializer.Deserialize<Dictionary<string, object>>(settingsJson) ?? new Dictionary<string, object>();
            var updateDto = new UpdateBotSettingsDto { Settings = settings };
            
            await _botService.UpdateBotSettingsAsync(id, updateDto);
            await _botService.UpdateBotStatusAsync(id, status);
            
            TempData["Success"] = "Bot updated successfully";
            return RedirectToAction(nameof(Details), new { id });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to update bot");
            TempData["Error"] = "Failed to update bot";
            return RedirectToAction(nameof(Edit), new { id });
        }
    }

    // GET: Admin/Bots/Metrics/5
    public async Task<IActionResult> Metrics(Guid id, DateTime? startDate, DateTime? endDate)
    {
        var bot = await _botService.GetBotByIdAsync(id);
        if (bot == null)
            return NotFound();

        var start = startDate ?? DateTime.UtcNow.AddDays(-7);
        var end = endDate ?? DateTime.UtcNow;

        var metricsSummary = await _metricsService.GetMetricsSummaryAsync(id, start, end);
        var sessionSummary = await _metricsService.GetSessionSummaryAsync(id, start, end);
        
        ViewData["Bot"] = bot;
        ViewData["SessionSummary"] = sessionSummary;
        ViewData["StartDate"] = start;
        ViewData["EndDate"] = end;
        
        return View(metricsSummary);
    }

    // POST: Admin/Bots/Delete/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Delete(Guid id)
    {
        var success = await _botService.DeleteBotAsync(id);
        if (!success)
        {
            TempData["Error"] = "Failed to delete bot";
            return RedirectToAction(nameof(Index));
        }

        TempData["Success"] = "Bot deleted successfully";
        return RedirectToAction(nameof(Index));
    }

    // POST: Admin/Bots/Suspend/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Suspend(Guid id)
    {
        await _botService.UpdateBotStatusAsync(id, BotStatus.Suspended);
        TempData["Success"] = "Bot suspended";
        return RedirectToAction(nameof(Details), new { id });
    }

    // POST: Admin/Bots/Activate/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Activate(Guid id)
    {
        await _botService.UpdateBotStatusAsync(id, BotStatus.Active);
        TempData["Success"] = "Bot activated";
        return RedirectToAction(nameof(Details), new { id });
    }

    // GET: Admin/Bots/RegenerateKey/5
    public IActionResult RegenerateKey(Guid id)
    {
        // This would require updating the bot model to support key regeneration
        TempData["Error"] = "Key regeneration not yet implemented";
        return RedirectToAction(nameof(Details), new { id });
    }

    private string GenerateBotFatherCommands(BotWizardDto dto)
    {
        var commands = new List<string>
        {
            "1. Open Telegram and find @BotFather",
            "2. Send: /newbot",
            $"3. Send bot name: {dto.BotName}",
            $"4. Send bot username: {dto.BotUsername}",
            "5. Copy the token from BotFather's response",
            "6. Paste the token in the field below"
        };

        if (!string.IsNullOrEmpty(dto.Description))
        {
            commands.Add($"7. Optional: Send /setdescription and then: {dto.Description}");
        }

        return string.Join("\n", commands);
    }

    private async Task<bool> ValidateTelegramToken(string token)
    {
        try
        {
            using var httpClient = new HttpClient();
            var response = await httpClient.GetAsync($"https://api.telegram.org/bot{token}/getMe");
            return response.IsSuccessStatusCode;
        }
        catch
        {
            return false;
        }
    }
}