using TakeoutSaaS.Domain.Stores.Entities;
using TakeoutSaaS.Domain.Stores.Enums;

namespace TakeoutSaaS.Domain.Stores.Repositories;

/// <summary>
/// 门店聚合仓储契约。
/// </summary>
public interface IStoreRepository
{
    /// <summary>
    /// 依据标识获取门店。
    /// </summary>
    /// <param name="storeId">门店 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<Store?> FindByIdAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 获取指定商户的门店列表。
    /// </summary>
    Task<IReadOnlyList<Store>> GetByMerchantIdAsync(long merchantId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 按租户筛选门店列表。
    /// </summary>
    Task<IReadOnlyList<Store>> SearchAsync(
        long? tenantId,
        long? merchantId,
        StoreStatus? status,
        StoreAuditStatus? auditStatus,
        StoreBusinessStatus? businessStatus,
        StoreOwnershipType? ownershipType,
        string? keyword,
        bool includeDeleted = false,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 判断指定坐标是否存在 100 米内门店。
    /// </summary>
    Task<bool> ExistsStoreWithinDistanceAsync(
        long merchantId,
        long tenantId,
        double longitude,
        double latitude,
        double distanceMeters,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取指定商户集合的门店数量。
    /// </summary>
    Task<Dictionary<long, int>> GetStoreCountsAsync(long? tenantId, IReadOnlyCollection<long> merchantIds, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店营业时段。
    /// </summary>
    /// <param name="storeId">门店 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<IReadOnlyList<StoreBusinessHour>> GetBusinessHoursAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 获取门店费用配置。
    /// </summary>
    /// <param name="storeId">门店 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<StoreFee?> GetStoreFeeAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 新增门店费用配置。
    /// </summary>
    Task AddStoreFeeAsync(StoreFee storeFee, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新门店费用配置。
    /// </summary>
    Task UpdateStoreFeeAsync(StoreFee storeFee, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店资质列表。
    /// </summary>
    /// <param name="storeId">门店 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<IReadOnlyList<StoreQualification>> GetQualificationsAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 依据标识获取门店资质。
    /// </summary>
    Task<StoreQualification?> FindQualificationByIdAsync(long qualificationId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增门店资质。
    /// </summary>
    Task AddQualificationAsync(StoreQualification qualification, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新门店资质。
    /// </summary>
    Task UpdateQualificationAsync(StoreQualification qualification, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除门店资质。
    /// </summary>
    Task DeleteQualificationAsync(long qualificationId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增门店审核记录。
    /// </summary>
    Task AddAuditRecordAsync(StoreAuditRecord record, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店审核记录。
    /// </summary>
    Task<IReadOnlyList<StoreAuditRecord>> GetAuditRecordsAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 依据标识获取营业时段。
    /// </summary>
    Task<StoreBusinessHour?> FindBusinessHourByIdAsync(long businessHourId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店配送区域配置。
    /// </summary>
    /// <param name="storeId">门店 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<IReadOnlyList<StoreDeliveryZone>> GetDeliveryZonesAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 依据标识获取配送区域。
    /// </summary>
    /// <param name="deliveryZoneId">配送区域 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<StoreDeliveryZone?> FindDeliveryZoneByIdAsync(long deliveryZoneId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 获取门店节假日配置。
    /// </summary>
    /// <param name="storeId">门店 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<IReadOnlyList<StoreHoliday>> GetHolidaysAsync(long storeId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 依据标识获取节假日配置。
    /// </summary>
    /// <param name="holidayId">节假日配置 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <param name="includeDeleted">是否包含已删除数据。</param>
    Task<StoreHoliday?> FindHolidayByIdAsync(long holidayId, long? tenantId, CancellationToken cancellationToken = default, bool includeDeleted = false);

    /// <summary>
    /// 获取门店桌台区域。
    /// </summary>
    Task<IReadOnlyList<StoreTableArea>> GetTableAreasAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 依据标识获取桌台区域。
    /// </summary>
    Task<StoreTableArea?> FindTableAreaByIdAsync(long areaId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店桌台列表。
    /// </summary>
    Task<IReadOnlyList<StoreTable>> GetTablesAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 依据标识获取桌台。
    /// </summary>
    Task<StoreTable?> FindTableByIdAsync(long tableId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 依据桌码获取桌台。
    /// </summary>
    Task<StoreTable?> FindTableByCodeAsync(string tableCode, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店自提配置。
    /// </summary>
    Task<StorePickupSetting?> GetPickupSettingAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增自提配置。
    /// </summary>
    Task AddPickupSettingAsync(StorePickupSetting setting, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新自提配置。
    /// </summary>
    Task UpdatePickupSettingAsync(StorePickupSetting setting, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店自提档期。
    /// </summary>
    Task<IReadOnlyList<StorePickupSlot>> GetPickupSlotsAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 依据标识获取档期。
    /// </summary>
    Task<StorePickupSlot?> FindPickupSlotByIdAsync(long slotId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增加档期。
    /// </summary>
    Task AddPickupSlotsAsync(IEnumerable<StorePickupSlot> slots, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新档期。
    /// </summary>
    Task UpdatePickupSlotAsync(StorePickupSlot slot, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取门店员工排班（可选时间范围）。
    /// </summary>
    Task<IReadOnlyList<StoreEmployeeShift>> GetShiftsAsync(long storeId, long tenantId, DateTime? from = null, DateTime? to = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 依据标识获取排班。
    /// </summary>
    Task<StoreEmployeeShift?> FindShiftByIdAsync(long shiftId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增门店。
    /// </summary>
    Task AddStoreAsync(Store store, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增营业时段。
    /// </summary>
    Task AddBusinessHoursAsync(IEnumerable<StoreBusinessHour> hours, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新营业时段。
    /// </summary>
    Task UpdateBusinessHourAsync(StoreBusinessHour hour, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增配送区域。
    /// </summary>
    Task AddDeliveryZonesAsync(IEnumerable<StoreDeliveryZone> zones, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新配送区域。
    /// </summary>
    Task UpdateDeliveryZoneAsync(StoreDeliveryZone zone, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增节假日配置。
    /// </summary>
    Task AddHolidaysAsync(IEnumerable<StoreHoliday> holidays, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新节假日配置。
    /// </summary>
    Task UpdateHolidayAsync(StoreHoliday holiday, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增桌台区域。
    /// </summary>
    Task AddTableAreasAsync(IEnumerable<StoreTableArea> areas, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新桌台区域。
    /// </summary>
    Task UpdateTableAreaAsync(StoreTableArea area, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增桌台。
    /// </summary>
    Task AddTablesAsync(IEnumerable<StoreTable> tables, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新桌台。
    /// </summary>
    Task UpdateTableAsync(StoreTable table, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增排班。
    /// </summary>
    Task AddShiftsAsync(IEnumerable<StoreEmployeeShift> shifts, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新排班。
    /// </summary>
    Task UpdateShiftAsync(StoreEmployeeShift shift, CancellationToken cancellationToken = default);

    /// <summary>
    /// 持久化变更。
    /// </summary>
    Task SaveChangesAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除营业时段。
    /// </summary>
    Task DeleteBusinessHourAsync(long businessHourId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除配送区域。
    /// </summary>
    /// <param name="deliveryZoneId">配送区域 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    Task DeleteDeliveryZoneAsync(long deliveryZoneId, long? tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除节假日。
    /// </summary>
    /// <param name="holidayId">节假日配置 ID。</param>
    /// <param name="tenantId">租户 ID（为空则不做租户过滤）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    Task DeleteHolidayAsync(long holidayId, long? tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除桌台区域。
    /// </summary>
    Task DeleteTableAreaAsync(long areaId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除桌台。
    /// </summary>
    Task DeleteTableAsync(long tableId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除自提档期。
    /// </summary>
    Task DeletePickupSlotAsync(long slotId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除排班。
    /// </summary>
    Task DeleteShiftAsync(long shiftId, long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新门店。
    /// </summary>
    Task UpdateStoreAsync(Store store, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除门店。
    /// </summary>
    Task DeleteStoreAsync(long storeId, long tenantId, CancellationToken cancellationToken = default);
}
