using System.Linq;
using TakeoutSaaS.Application.App.Stores.Dto;

namespace TakeoutSaaS.Application.App.Stores.Validators;

/// <summary>
/// 营业时段校验助手。
/// </summary>
public static class BusinessHourValidators
{
    /// <summary>
    /// 校验营业时段是否存在重叠。
    /// </summary>
    /// <param name="items">营业时段列表。</param>
    /// <returns>错误信息，若为空表示通过。</returns>
    public static string? ValidateOverlap(IReadOnlyList<StoreBusinessHourInputDto> items)
    {
        if (items.Count == 0)
        {
            return null;
        }

        var segments = new List<(DayOfWeek Day, TimeSpan Start, TimeSpan End)>();
        foreach (var item in items)
        {
            if (item.StartTime == item.EndTime)
            {
                return "营业时段开始时间不能等于结束时间";
            }

            if (item.StartTime < item.EndTime)
            {
                segments.Add((item.DayOfWeek, item.StartTime, item.EndTime));
                continue;
            }

            var nextDay = NextDay(item.DayOfWeek);
            segments.Add((item.DayOfWeek, item.StartTime, TimeSpan.FromDays(1)));
            segments.Add((nextDay, TimeSpan.Zero, item.EndTime));
        }

        var grouped = segments.GroupBy(x => x.Day).ToList();
        foreach (var group in grouped)
        {
            var ordered = group.OrderBy(x => x.Start).ToList();
            for (var index = 0; index < ordered.Count - 1; index++)
            {
                var current = ordered[index];
                var next = ordered[index + 1];
                if (next.Start < current.End)
                {
                    return "营业时段存在重叠，请调整";
                }
            }
        }

        return null;
    }

    private static DayOfWeek NextDay(DayOfWeek day)
    {
        var next = (int)day + 1;
        return next > 6 ? DayOfWeek.Sunday : (DayOfWeek)next;
    }
}
