using FastEndpoints;
using TaxBaik.Application.Services;
using TaxBaik.Domain.Entities;
using FaqEntity = TaxBaik.Domain.Entities.Faq;

namespace TaxBaik.Web.Endpoints.Faq;

// DTOs
public class CreateFaqRequest
{
    public string Question { get; set; } = string.Empty;
    public string Answer { get; set; } = string.Empty;
    public string? Category { get; set; }
    public int SortOrder { get; set; }
}

public class UpdateFaqRequest
{
    public string Question { get; set; } = string.Empty;
    public string Answer { get; set; } = string.Empty;
    public string? Category { get; set; }
    public int SortOrder { get; set; }
    public bool IsActive { get; set; } = true;
}

public class FaqListResponse
{
    public List<FaqEntity> Data { get; set; } = [];
}

public class FaqCreateResponse
{
    public int Id { get; set; }
}

public class FaqUpdateResponse
{
    public string Message { get; set; } = string.Empty;
}

// Endpoints
public class GetActiveEndpoint : Endpoint<EmptyRequest, FaqListResponse>
{
    private readonly FaqService _service;
    public GetActiveEndpoint(FaqService service) => _service = service;

    public override void Configure()
    {
        Get("/api/faq/active");
        AllowAnonymous();
    }

    public override async Task HandleAsync(EmptyRequest _, CancellationToken ct)
    {
        try
        {
            var faqs = await _service.GetActiveAsync(ct);
            await SendAsync(new FaqListResponse { Data = faqs.ToList() }, 200, cancellation: ct);
        }
        catch (Exception ex)
        {
            ThrowError(ex.Message, statusCode: 500);
        }
    }
}

public class GetAllEndpoint : Endpoint<EmptyRequest, FaqListResponse>
{
    private readonly FaqService _service;
    public GetAllEndpoint(FaqService service) => _service = service;

    public override void Configure()
    {
        Get("/api/faq");
        Policies("Bearer");
    }

    public override async Task HandleAsync(EmptyRequest _, CancellationToken ct)
    {
        try
        {
            var faqs = await _service.GetAllAsync(ct);
            await SendAsync(new FaqListResponse { Data = faqs.ToList() }, 200, cancellation: ct);
        }
        catch (Exception ex)
        {
            ThrowError(ex.Message, statusCode: 500);
        }
    }
}

public class GetByIdEndpoint : Endpoint<EmptyRequest, FaqEntity>
{
    private readonly FaqService _service;
    public GetByIdEndpoint(FaqService service) => _service = service;

    public override void Configure()
    {
        Get("/api/faq/{id}");
        Policies("Bearer");
    }

    public override async Task HandleAsync(EmptyRequest _, CancellationToken ct)
    {
        var id = Route<int>("id");
        try
        {
            var faq = await _service.GetByIdAsync(id, ct);
            if (faq == null)
                ThrowError("FAQ를 찾을 수 없습니다.", statusCode: 404);
            await SendAsync(faq, 200, cancellation: ct);
        }
        catch (Exception ex)
        {
            ThrowError(ex.Message, statusCode: 500);
        }
    }
}

public class CreateEndpoint : Endpoint<CreateFaqRequest, FaqCreateResponse>
{
    private readonly FaqService _service;
    public CreateEndpoint(FaqService service) => _service = service;

    public override void Configure()
    {
        Post("/api/faq");
        Policies("Bearer");
    }

    public override async Task HandleAsync(CreateFaqRequest request, CancellationToken ct)
    {
        try
        {
            var faq = new FaqEntity
            {
                Question = request.Question,
                Answer = request.Answer,
                Category = request.Category,
                SortOrder = request.SortOrder,
                IsActive = true,
                CreatedAt = DateTime.UtcNow,
                UpdatedAt = DateTime.UtcNow
            };
            var id = await _service.CreateAsync(faq, ct);
            await SendAsync(new FaqCreateResponse { Id = id }, 201, cancellation: ct);
        }
        catch (ValidationException ex)
        {
            ThrowError(ex.Message);
        }
        catch (Exception ex)
        {
            ThrowError(ex.Message, statusCode: 500);
        }
    }
}

public class UpdateEndpoint : Endpoint<UpdateFaqRequest, FaqUpdateResponse>
{
    private readonly FaqService _service;
    public UpdateEndpoint(FaqService service) => _service = service;

    public override void Configure()
    {
        Put("/api/faq/{id}");
        Policies("Bearer");
    }

    public override async Task HandleAsync(UpdateFaqRequest request, CancellationToken ct)
    {
        var id = Route<int>("id");
        try
        {
            var faq = new FaqEntity
            {
                Id = id,
                Question = request.Question,
                Answer = request.Answer,
                Category = request.Category,
                SortOrder = request.SortOrder,
                IsActive = request.IsActive,
                UpdatedAt = DateTime.UtcNow
            };
            await _service.UpdateAsync(faq, ct);
            await SendAsync(new FaqUpdateResponse { Message = "FAQ가 수정되었습니다." }, 200, cancellation: ct);
        }
        catch (ValidationException ex)
        {
            ThrowError(ex.Message);
        }
        catch (Exception ex)
        {
            ThrowError(ex.Message, statusCode: 500);
        }
    }
}

public class DeleteEndpoint : Endpoint<EmptyRequest, EmptyResponse>
{
    private readonly FaqService _service;
    public DeleteEndpoint(FaqService service) => _service = service;

    public override void Configure()
    {
        Delete("/api/faq/{id}");
        Policies("Bearer");
    }

    public override async Task HandleAsync(EmptyRequest _, CancellationToken ct)
    {
        var id = Route<int>("id");
        try
        {
            await _service.DeleteAsync(id, ct);
            await SendAsync(new EmptyResponse(), 204, cancellation: ct);
        }
        catch (Exception ex)
        {
            ThrowError(ex.Message, statusCode: 500);
        }
    }
}
