using System.Security.Claims;
using FastEndpoints;
using Microsoft.EntityFrameworkCore;
using TrackQrApi.Data;
using TrackQrApi.Features.Assets.Common;
using TrackQrApi.Features.Assets.Services;
using TrackQrApi.Features.Auth.Common;
using TrackQrApi.Models;

namespace TrackQrApi.Features.Assets.Endpoints;

public class UploadAssetRequest
{
    public Guid WorkspaceId { get; set; }
    public IFormFile? File { get; set; }
}

public class UploadAssetEndpoint(AppDbContext db, IAssetStorageService storage)
    : Endpoint<UploadAssetRequest, AssetResponse>
{
    public override void Configure()
    {
        Post("/workspaces/{WorkspaceId}/assets");
        AllowFileUploads();
    }

    public override async Task HandleAsync(UploadAssetRequest req, CancellationToken ct)
    {
        var userId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);

        // Verify workspace ownership
        var workspaceExists = await db.Workspaces
            .AnyAsync(w => w.Id == req.WorkspaceId && w.OwnerUserId == userId, ct);

        if (!workspaceExists)
        {
            await HttpContext.Response.SendAsync(new MessageResponse("Workspace not found"), 404, cancellation: ct);
            return;
        }

        // Get file from form
        var file = req.File;
        if (file is null)
            try
            {
                file = HttpContext.Request.Form.Files.FirstOrDefault();
            }
            catch
            {
                // Form access failed - no file uploaded
            }

        if (file is null || file.Length == 0)
        {
            await HttpContext.Response.SendAsync(new MessageResponse("No file uploaded"), 400, cancellation: ct);
            return;
        }

        // Validate file type
        var allowedTypes = new[] { "image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml" };
        if (!allowedTypes.Contains(file.ContentType.ToLowerInvariant()))
        {
            await HttpContext.Response.SendAsync(
                new MessageResponse("Invalid file type. Allowed: PNG, JPEG, GIF, WebP, SVG"),
                400,
                cancellation: ct);
            return;
        }

        // Validate file size (max 5MB)
        const long maxSize = 5 * 1024 * 1024;
        if (file.Length > maxSize)
        {
            await HttpContext.Response.SendAsync(
                new MessageResponse("File too large. Maximum size is 5MB"),
                400,
                cancellation: ct);
            return;
        }

        // Store file
        await using var stream = file.OpenReadStream();
        var storageKey = await storage.StoreAsync(stream, file.FileName, file.ContentType);

        // Save to database
        var asset = new Asset
        {
            Id = Guid.NewGuid(),
            WorkspaceId = req.WorkspaceId,
            Type = AssetType.Logo,
            StorageKey = storageKey,
            Mime = file.ContentType,
            Size = file.Length,
            CreatedAt = DateTime.UtcNow
        };

        db.Assets.Add(asset);
        await db.SaveChangesAsync(ct);

        var response = new AssetResponse(
            asset.Id,
            asset.WorkspaceId,
            asset.Type.ToString(),
            asset.Mime,
            asset.Size,
            storage.GetPublicUrl(asset.StorageKey, HttpContext),
            asset.CreatedAt
        );

        await HttpContext.Response.SendAsync(response, 201, cancellation: ct);
    }
}