using System.Collections.Generic;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Application.App.Stores.Queries;
using TakeoutSaaS.Domain.Stores.Enums;
using TakeoutSaaS.Module.Authorization.Attributes;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;

namespace TakeoutSaaS.AdminApi.Controllers;

/// <summary>
/// 门店管理。
/// </summary>
[ApiVersion("1.0")]
[Authorize]
[Route("api/admin/v{version:apiVersion}/stores")]
public sealed class StoresController(IMediator mediator) : BaseApiController
{
    /// <summary>
    /// 创建门店。
    /// </summary>
    /// <returns>创建的门店信息。</returns>
    [HttpPost]
    [PermissionAuthorize("store:create")]
    [ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<StoreDto>> Create([FromBody] CreateStoreCommand command, CancellationToken cancellationToken)
    {
        // 1. 创建门店
        var result = await mediator.Send(command, cancellationToken);

        // 2. 返回创建结果
        return ApiResponse<StoreDto>.Ok(result);
    }

    /// <summary>
    /// 查询门店列表。
    /// </summary>
    /// <returns>门店分页列表。</returns>
    [HttpGet]
    [PermissionAuthorize("store:read")]
    [ProducesResponseType(typeof(ApiResponse<PagedResult<StoreDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<PagedResult<StoreDto>>> List(
        [FromQuery] long? merchantId,
        [FromQuery] StoreStatus? status,
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] string? sortBy = null,
        [FromQuery] bool sortDesc = true,
        CancellationToken cancellationToken = default)
    {
        // 1. 组装查询参数并执行查询
        var result = await mediator.Send(new SearchStoresQuery
        {
            MerchantId = merchantId,
            Status = status,
            Page = page,
            PageSize = pageSize,
            SortBy = sortBy,
            SortDescending = sortDesc
        }, cancellationToken);

        // 2. 返回分页结果
        return ApiResponse<PagedResult<StoreDto>>.Ok(result);
    }

    /// <summary>
    /// 获取门店详情。
    /// </summary>
    /// <returns>门店详情。</returns>
    [HttpGet("{storeId:long}")]
    [PermissionAuthorize("store:read")]
    [ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<StoreDto>> Detail(long storeId, CancellationToken cancellationToken)
    {
        // 1. 查询门店详情
        var result = await mediator.Send(new GetStoreByIdQuery { StoreId = storeId }, cancellationToken);

        // 2. 返回详情或 404
        return result == null
            ? ApiResponse<StoreDto>.Error(ErrorCodes.NotFound, "门店不存在")
            : ApiResponse<StoreDto>.Ok(result);
    }

    /// <summary>
    /// 更新门店。
    /// </summary>
    /// <returns>更新后的门店信息。</returns>
    [HttpPut("{storeId:long}")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<StoreDto>> Update(long storeId, [FromBody] UpdateStoreCommand command, CancellationToken cancellationToken)
    {
        // 1. 确保命令包含门店标识
        if (command.StoreId == 0)
        {
            command = command with { StoreId = storeId };
        }

        // 2. 执行更新
        var result = await mediator.Send(command, cancellationToken);

        // 3. 返回更新结果或 404
        return result == null
            ? ApiResponse<StoreDto>.Error(ErrorCodes.NotFound, "门店不存在")
            : ApiResponse<StoreDto>.Ok(result);
    }

    /// <summary>
    /// 删除门店。
    /// </summary>
    /// <returns>删除结果。</returns>
    [HttpDelete("{storeId:long}")]
    [PermissionAuthorize("store:delete")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<object>> Delete(long storeId, CancellationToken cancellationToken)
    {
        // 1. 执行删除
        var success = await mediator.Send(new DeleteStoreCommand { StoreId = storeId }, cancellationToken);

        // 2. 返回结果或 404
        return success
            ? ApiResponse<object>.Ok(null)
            : ApiResponse<object>.Error(ErrorCodes.NotFound, "门店不存在");
    }

    /// <summary>
    /// 查询门店营业时段。
    /// </summary>
    [HttpGet("{storeId:long}/business-hours")]
    [PermissionAuthorize("store:read")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<StoreBusinessHourDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<StoreBusinessHourDto>>> ListBusinessHours(long storeId, CancellationToken cancellationToken)
    {
        var result = await mediator.Send(new ListStoreBusinessHoursQuery { StoreId = storeId }, cancellationToken);
        return ApiResponse<IReadOnlyList<StoreBusinessHourDto>>.Ok(result);
    }

    /// <summary>
    /// 新增营业时段。
    /// </summary>
    [HttpPost("{storeId:long}/business-hours")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<StoreBusinessHourDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<StoreBusinessHourDto>> CreateBusinessHour(long storeId, [FromBody] CreateStoreBusinessHourCommand command, CancellationToken cancellationToken)
    {
        if (command.StoreId == 0)
        {
            command = command with { StoreId = storeId };
        }

        var result = await mediator.Send(command, cancellationToken);
        return ApiResponse<StoreBusinessHourDto>.Ok(result);
    }

    /// <summary>
    /// 更新营业时段。
    /// </summary>
    [HttpPut("{storeId:long}/business-hours/{businessHourId:long}")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<StoreBusinessHourDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<StoreBusinessHourDto>> UpdateBusinessHour(long storeId, long businessHourId, [FromBody] UpdateStoreBusinessHourCommand command, CancellationToken cancellationToken)
    {
        if (command.StoreId == 0 || command.BusinessHourId == 0)
        {
            command = command with { StoreId = storeId, BusinessHourId = businessHourId };
        }

        var result = await mediator.Send(command, cancellationToken);
        return result == null
            ? ApiResponse<StoreBusinessHourDto>.Error(ErrorCodes.NotFound, "营业时段不存在")
            : ApiResponse<StoreBusinessHourDto>.Ok(result);
    }

    /// <summary>
    /// 删除营业时段。
    /// </summary>
    [HttpDelete("{storeId:long}/business-hours/{businessHourId:long}")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<object>> DeleteBusinessHour(long storeId, long businessHourId, CancellationToken cancellationToken)
    {
        var success = await mediator.Send(new DeleteStoreBusinessHourCommand { StoreId = storeId, BusinessHourId = businessHourId }, cancellationToken);
        return success
            ? ApiResponse<object>.Ok(null)
            : ApiResponse<object>.Error(ErrorCodes.NotFound, "营业时段不存在");
    }

    /// <summary>
    /// 查询配送区域。
    /// </summary>
    [HttpGet("{storeId:long}/delivery-zones")]
    [PermissionAuthorize("store:read")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<StoreDeliveryZoneDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<StoreDeliveryZoneDto>>> ListDeliveryZones(long storeId, CancellationToken cancellationToken)
    {
        var result = await mediator.Send(new ListStoreDeliveryZonesQuery { StoreId = storeId }, cancellationToken);
        return ApiResponse<IReadOnlyList<StoreDeliveryZoneDto>>.Ok(result);
    }

    /// <summary>
    /// 新增配送区域。
    /// </summary>
    [HttpPost("{storeId:long}/delivery-zones")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<StoreDeliveryZoneDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<StoreDeliveryZoneDto>> CreateDeliveryZone(long storeId, [FromBody] CreateStoreDeliveryZoneCommand command, CancellationToken cancellationToken)
    {
        if (command.StoreId == 0)
        {
            command = command with { StoreId = storeId };
        }

        var result = await mediator.Send(command, cancellationToken);
        return ApiResponse<StoreDeliveryZoneDto>.Ok(result);
    }

    /// <summary>
    /// 更新配送区域。
    /// </summary>
    [HttpPut("{storeId:long}/delivery-zones/{deliveryZoneId:long}")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<StoreDeliveryZoneDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<StoreDeliveryZoneDto>> UpdateDeliveryZone(long storeId, long deliveryZoneId, [FromBody] UpdateStoreDeliveryZoneCommand command, CancellationToken cancellationToken)
    {
        if (command.StoreId == 0 || command.DeliveryZoneId == 0)
        {
            command = command with { StoreId = storeId, DeliveryZoneId = deliveryZoneId };
        }

        var result = await mediator.Send(command, cancellationToken);
        return result == null
            ? ApiResponse<StoreDeliveryZoneDto>.Error(ErrorCodes.NotFound, "配送区域不存在")
            : ApiResponse<StoreDeliveryZoneDto>.Ok(result);
    }

    /// <summary>
    /// 删除配送区域。
    /// </summary>
    [HttpDelete("{storeId:long}/delivery-zones/{deliveryZoneId:long}")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<object>> DeleteDeliveryZone(long storeId, long deliveryZoneId, CancellationToken cancellationToken)
    {
        var success = await mediator.Send(new DeleteStoreDeliveryZoneCommand { StoreId = storeId, DeliveryZoneId = deliveryZoneId }, cancellationToken);
        return success
            ? ApiResponse<object>.Ok(null)
            : ApiResponse<object>.Error(ErrorCodes.NotFound, "配送区域不存在");
    }

    /// <summary>
    /// 查询门店节假日。
    /// </summary>
    [HttpGet("{storeId:long}/holidays")]
    [PermissionAuthorize("store:read")]
    [ProducesResponseType(typeof(ApiResponse<IReadOnlyList<StoreHolidayDto>>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<IReadOnlyList<StoreHolidayDto>>> ListHolidays(long storeId, CancellationToken cancellationToken)
    {
        var result = await mediator.Send(new ListStoreHolidaysQuery { StoreId = storeId }, cancellationToken);
        return ApiResponse<IReadOnlyList<StoreHolidayDto>>.Ok(result);
    }

    /// <summary>
    /// 新增节假日配置。
    /// </summary>
    [HttpPost("{storeId:long}/holidays")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<StoreHolidayDto>), StatusCodes.Status200OK)]
    public async Task<ApiResponse<StoreHolidayDto>> CreateHoliday(long storeId, [FromBody] CreateStoreHolidayCommand command, CancellationToken cancellationToken)
    {
        if (command.StoreId == 0)
        {
            command = command with { StoreId = storeId };
        }

        var result = await mediator.Send(command, cancellationToken);
        return ApiResponse<StoreHolidayDto>.Ok(result);
    }

    /// <summary>
    /// 更新节假日配置。
    /// </summary>
    [HttpPut("{storeId:long}/holidays/{holidayId:long}")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<StoreHolidayDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<StoreHolidayDto>> UpdateHoliday(long storeId, long holidayId, [FromBody] UpdateStoreHolidayCommand command, CancellationToken cancellationToken)
    {
        if (command.StoreId == 0 || command.HolidayId == 0)
        {
            command = command with { StoreId = storeId, HolidayId = holidayId };
        }

        var result = await mediator.Send(command, cancellationToken);
        return result == null
            ? ApiResponse<StoreHolidayDto>.Error(ErrorCodes.NotFound, "节假日配置不存在")
            : ApiResponse<StoreHolidayDto>.Ok(result);
    }

    /// <summary>
    /// 删除节假日配置。
    /// </summary>
    [HttpDelete("{storeId:long}/holidays/{holidayId:long}")]
    [PermissionAuthorize("store:update")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    public async Task<ApiResponse<object>> DeleteHoliday(long storeId, long holidayId, CancellationToken cancellationToken)
    {
        var success = await mediator.Send(new DeleteStoreHolidayCommand { StoreId = storeId, HolidayId = holidayId }, cancellationToken);
        return success
            ? ApiResponse<object>.Ok(null)
            : ApiResponse<object>.Error(ErrorCodes.NotFound, "节假日配置不存在");
    }
}
