using Microsoft.AspNetCore.Mvc;
using Ikar.Server.Infrastructure.Updates;
using Ikar.Shared;

namespace Ikar.Server.Controllers;

[ApiController]
[Route("api/app-updates")]
public sealed class AppUpdatesController(
    AndroidAppUpdateService androidAppUpdateService,
    AndroidUpdateCompatibilityTrackingService trackingService) : ControllerBase
{
    [HttpGet("android/latest")]
    [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
    [ProducesResponseType(typeof(AndroidAppReleaseDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<AndroidAppReleaseDto>> GetLatestAndroidRelease(CancellationToken cancellationToken)
    {
        ApplyNoCacheHeaders();
        await trackingService.TrackHitAsync(Request, "android/latest", null, cancellationToken);
        var release = await androidAppUpdateService.GetLatestReleaseAsync(cancellationToken);
        return release is null ? NotFound() : Ok(release);
    }

    [HttpGet("android/download/{fileName}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DownloadAndroidRelease(string fileName, CancellationToken cancellationToken)
    {
        await trackingService.TrackHitAsync(Request, "android/download/file", fileName, cancellationToken);
        var package = await androidAppUpdateService.ResolvePackageAsync(fileName, cancellationToken);
        if (package is null)
        {
            return NotFound();
        }

        if (!string.IsNullOrWhiteSpace(package.RedirectUrl))
        {
            return Redirect(package.RedirectUrl);
        }

        var physicalPath = package.PhysicalPath!;
        return PhysicalFile(
            physicalPath,
            "application/vnd.android.package-archive",
            package.FileName,
            enableRangeProcessing: true);
    }

    [HttpGet("android/download/latest")]
    [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DownloadLatestAndroidRelease(CancellationToken cancellationToken)
    {
        ApplyNoCacheHeaders();
        await trackingService.TrackHitAsync(Request, "android/download/latest", null, cancellationToken);
        var package = await androidAppUpdateService.ResolveLatestPackageAsync(cancellationToken);
        if (package is null)
        {
            return NotFound();
        }

        if (!string.IsNullOrWhiteSpace(package.RedirectUrl))
        {
            return Redirect(package.RedirectUrl);
        }

        var physicalPath = package.PhysicalPath!;
        return PhysicalFile(
            physicalPath,
            "application/vnd.android.package-archive",
            package.FileName,
            enableRangeProcessing: true);
    }

    private void ApplyNoCacheHeaders()
    {
        Response.Headers.CacheControl = "no-store, no-cache, must-revalidate, max-age=0";
        Response.Headers.Pragma = "no-cache";
        Response.Headers.Expires = "0";
    }
}
