using Meezi.API.Models.Consumer;
using Meezi.API.Services.Printing;
using Meezi.Core.Enums;
using Meezi.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace Meezi.API.Services;

public interface IConsumerOrdersService
{
    Task<IReadOnlyList<ConsumerOrderHistoryDto>> GetMyOrdersAsync(
        string phone,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default);
}

public class ConsumerOrdersService : IConsumerOrdersService
{
    private readonly AppDbContext _db;

    public ConsumerOrdersService(AppDbContext db) => _db = db;

    public async Task<IReadOnlyList<ConsumerOrderHistoryDto>> GetMyOrdersAsync(
        string phone,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default)
    {
        page = Math.Max(1, page);
        pageSize = Math.Clamp(pageSize, 1, 50);

        var orders = await _db.Orders
            .AsNoTracking()
            .Include(o => o.Cafe)
            .Include(o => o.Table)
            .Include(o => o.Customer)
            .Include(o => o.Items)
            .Where(o =>
                o.DeletedAt == null
                && (o.GuestPhone == phone
                    || (o.Customer != null && o.Customer.Phone == phone)))
            .OrderByDescending(o => o.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync(cancellationToken);

        return orders.Select(o => new ConsumerOrderHistoryDto(
            o.Id,
            o.CafeId,
            o.Cafe.Name,
            o.Cafe.Slug,
            o.Status,
            o.Total,
            o.DisplayNumber > 0 ? o.DisplayNumber : ReceiptPrintFormatting.StableDisplayNumberFromId(o.Id),
            o.CreatedAt,
            o.Table?.Number,
            o.Items.Count(i => !i.IsVoided))).ToList();
    }
}
