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

namespace TrackQrApi.Features.Billing.Endpoints;

public class CreateCheckoutSessionValidator : Validator<CheckoutSessionRequest>
{
    public CreateCheckoutSessionValidator()
    {
        RuleFor(x => x.WorkspaceId).NotEmpty();
        RuleFor(x => x.Plan)
            .NotEmpty()
            .Must(p => p == "Pro" || p == "Business")
            .WithMessage("Plan must be 'Pro' or 'Business'");
        RuleFor(x => x.SuccessUrl).NotEmpty().Must(BeValidUrl);
        RuleFor(x => x.CancelUrl).NotEmpty().Must(BeValidUrl);
    }

    private static bool BeValidUrl(string url)
    {
        return Uri.TryCreate(url, UriKind.Absolute, out var uri)
               && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps);
    }
}

public class CreateCheckoutSessionEndpoint(AppDbContext db, IStripeService stripeService)
    : Endpoint<CheckoutSessionRequest, CheckoutSessionResponse>
{
    public override void Configure()
    {
        Post("/billing/checkout");
    }

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

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

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

        // Check if already subscribed
        if (!string.IsNullOrEmpty(workspace.StripeSubscriptionId))
        {
            await HttpContext.Response.SendAsync(
                new MessageResponse(
                    "Workspace already has an active subscription. Use the billing portal to manage it."),
                400,
                cancellation: ct);
            return;
        }

        var plan = Enum.Parse<WorkspacePlan>(req.Plan);

        try
        {
            var checkoutUrl = await stripeService.CreateCheckoutSessionAsync(
                userId,
                req.WorkspaceId,
                plan,
                req.SuccessUrl,
                req.CancelUrl,
                ct);

            await HttpContext.Response.SendAsync(new CheckoutSessionResponse(checkoutUrl), cancellation: ct);
        }
        catch (Exception ex)
        {
            await HttpContext.Response.SendAsync(
                new MessageResponse($"Failed to create checkout session: {ex.Message}"),
                500,
                cancellation: ct);
        }
    }
}