using Aberwyn.Data;
using BencodeNET.Torrents;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

public class RssController : Controller
{
    private readonly ITorrentService _torrentService;
    private readonly ILogger<RssController> _logger;
    private readonly DelugeClient _deluge;
    private readonly MovieMetadataService _movieMetadataService;
    private readonly ApplicationDbContext _context;

    public RssController(
        ITorrentService torrentService,
        ILogger<RssController> logger,
        DelugeClient delugeClient,
        MovieMetadataService movieMetadataService,
        ApplicationDbContext context)
    {
        _torrentService = torrentService;
        _logger = logger;
        _deluge = delugeClient;
        _movieMetadataService = movieMetadataService;
        _context = context;
    }

    [HttpGet]
    public async Task<IActionResult> Index(int page = 1, string sort = "date", string range = "all")
    {
        var pageSize = 20;
        var userId = User.Identity?.Name ?? "guest";

        var torrents = await _torrentService.GetRecentTorrentsAsync(500);

        // Filtrera på tidsintervall
        torrents = range switch
        {
            "day" => torrents.Where(t => t.PublishDate > DateTime.UtcNow.AddDays(-1)).ToList(),
            "week" => torrents.Where(t => t.PublishDate > DateTime.UtcNow.AddDays(-7)).ToList(),
            "month" => torrents.Where(t => t.PublishDate > DateTime.UtcNow.AddMonths(-1)).ToList(),
            _ => torrents
        };

        // Sortera
        torrents = sort switch
        {
            "seeders" => torrents.OrderByDescending(t => t.Seeders).ToList(),
            "leechers" => torrents.OrderByDescending(t => t.Leechers).ToList(),
            "title" => torrents.OrderBy(t => t.MovieName).ToList(),
            _ => torrents.OrderByDescending(t => t.PublishDate).ToList(),
        };

        // Hämta sedda torrents för användaren
        var seenHashes = await _context.UserTorrentSeen
            .Where(x => x.UserId == userId)
            .Select(x => x.InfoHash)
            .ToListAsync();

        // Bygg viewmodels med IsNew
        var pagedItems = torrents
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .Select(t => new TorrentListItemViewModel
            {
                InfoHash = t.InfoHash ?? "",
                Title = t.Title,
                MovieName = t.MovieName ?? "",
                PublishDate = t.PublishDate,
                Seeders = t.Seeders,
                Leechers = t.Leechers,
                TorrentUrl = t.TorrentUrl,
                Metadata = t.Metadata,
                IsDownloaded = t.IsDownloaded,
                IsNew = t.InfoHash != null && !seenHashes.Contains(t.InfoHash),
                AvailableOn = !string.IsNullOrEmpty(t.Metadata?.Providers)
                ? t.Metadata.Providers.Split(',').ToList()
                : new List<string>()
            })
            .ToList();

        // Markera som sedda
        var newSeen = pagedItems
            .Where(i => i.IsNew && !string.IsNullOrEmpty(i.InfoHash))
            .Select(i => new UserTorrentSeen
            {
                UserId = userId,
                InfoHash = i.InfoHash,
                SeenDate = DateTime.UtcNow
            });

        _context.UserTorrentSeen.AddRange(newSeen);
        await _context.SaveChangesAsync();

        var vm = new TorrentListViewModel
        {
            Items = pagedItems,
            CurrentPage = page,
            TotalPages = (int)Math.Ceiling(torrents.Count / (double)pageSize),
            CurrentSort = sort,
            CurrentRange = range
        };

        return View(vm);
    }



    [HttpPost]
    public async Task<IActionResult> Add(string torrentUrl)
    {
        try
        {
            if (await _deluge.LoginAsync("deluge1"))
            {
                var success = await _deluge.AddTorrentUrlAsync(torrentUrl);

                if (success)
                {
                    // Hämta torrenten baserat på TorrentUrl
                    var torrent = await _context.Set<TorrentItem>()
                        .FirstOrDefaultAsync(t => t.TorrentUrl == torrentUrl);

                    if (torrent != null)
                    {
                        // Markera som nerladdad
                        torrent.IsDownloaded = true;
                        torrent.Status = TorrentStatus.Downloaded;
                        _context.Update(torrent);
                    }
                    else
                    {
                        // Skapa ny post om den inte finns
                        var newTorrent = new TorrentItem
                        {
                            Title = torrentUrl, // byt till korrekt namnkälla om du har
                            TorrentUrl = torrentUrl,
                            PublishDate = DateTime.UtcNow,
                            Status = TorrentStatus.Downloaded,
                            IsDownloaded = true,
                            RssSource = "Manuell", // eller sätt rätt källa
                        };

                        _context.Add(newTorrent);
                    }

                    await _context.SaveChangesAsync();
                    _logger.LogInformation("SavedChanges to torrents");
                    return Json(new
                    {
                        success = true,
                        message = "Torrent tillagd i Deluge och markerad som nerladdad."
                    });
                }
            }

            return Json(new { success = false, message = "Misslyckades att lägga till torrent i Deluge." });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Fel vid tillägg av torrent");
            return Json(new { success = false, message = "Ett fel uppstod vid tillägg av torrent." });
        }
    }



    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Upload(TorrentUploadViewModel model)
    {
        if (model.TorrentFile == null || model.TorrentFile.Length == 0)
        {
            ModelState.AddModelError("TorrentFile", "Vänligen välj en torrent-fil");
            return View("Index", model);
        }

        if (!model.TorrentFile.FileName.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase))
        {
            ModelState.AddModelError("TorrentFile", "Endast .torrent filer är tillåtna");
            return View("Index", model);
        }

        if (model.TorrentFile.Length > 10 * 1024 * 1024) // 10MB limit
        {
            ModelState.AddModelError("TorrentFile", "Filen är för stor (max 10MB)");
            return View("Index", model);
        }

        try
        {
            var torrentInfo = await _torrentService.ParseTorrentAsync(model.TorrentFile);

            if (!string.IsNullOrEmpty(torrentInfo.ErrorMessage))
            {
                ModelState.AddModelError("", torrentInfo.ErrorMessage);
                return View("Index", model);
            }

            torrentInfo = await _torrentService.FetchTrackerStatsAsync(torrentInfo);

            model.TorrentInfo = torrentInfo;
            model.ShowResults = true;

            return View("Index", model);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Fel vid uppladdning av torrent");
            ModelState.AddModelError("", "Ett oväntat fel inträffade");
            return View("Index", model);
        }
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> RefreshStats(string infoHash, string scrapeUrl)
    {
        try
        {
            var torrentInfo = new TorrentInfo
            {
                InfoHash = infoHash,
                ScrapeUrl = scrapeUrl,
                InfoHashBytes = Convert.FromHexString(infoHash.Replace("%", ""))
            };

            var updatedInfo = await _torrentService.FetchTrackerStatsAsync(torrentInfo);

            return Json(new
            {
                success = updatedInfo.HasTrackerData,
                seeders = updatedInfo.Seeders,
                leechers = updatedInfo.Leechers,
                completed = updatedInfo.Completed,
                error = updatedInfo.ErrorMessage
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Fel vid uppdatering av tracker-stats");
            return Json(new { success = false, error = "Fel vid uppdatering" });
        }
    }
}
