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.Application.App.Stores.Services;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Web.Api;
using TakeoutSaaS.TenantApi.Services;

namespace TakeoutSaaS.TenantApi.Controllers;

/// <summary>
/// 租户端门店管理。
/// </summary>
[ApiVersion("1.0")]
[Authorize]
[Route("api/tenant/v{version:apiVersion}/store")]
public sealed class StoreController(
    IMediator mediator,
    StoreContextService storeContextService,
    GeoLocationOrchestrator geoLocationOrchestrator) : BaseApiController
{
    /// <summary>
    /// 查询门店列表。
    /// </summary>
    /// <param name="query">查询参数。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>分页列表。</returns>
    [HttpGet("list")]
    [ProducesResponseType(typeof(ApiResponse<StoreListResultDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<StoreListResultDto>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<StoreListResultDto>> List([FromQuery] SearchStoresQuery query, CancellationToken cancellationToken)
    {
        // 1. 查询门店分页
        var result = await mediator.Send(query, cancellationToken);

        // 2. 返回分页数据
        return ApiResponse<StoreListResultDto>.Ok(result);
    }

    /// <summary>
    /// 查询门店统计。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>统计结果。</returns>
    [HttpGet("stats")]
    [ProducesResponseType(typeof(ApiResponse<StoreStatsDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<StoreStatsDto>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<StoreStatsDto>> Stats(CancellationToken cancellationToken)
    {
        // 1. 查询门店统计
        var result = await mediator.Send(new GetStoreStatsQuery(), cancellationToken);

        // 2. 返回统计结果
        return ApiResponse<StoreStatsDto>.Ok(result);
    }

    /// <summary>
    /// 创建门店。
    /// </summary>
    /// <param name="command">创建命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>创建结果。</returns>
    [HttpPost("create")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<object>> Create([FromBody] CreateStoreCommand command, CancellationToken cancellationToken)
    {
        // 1. 执行创建
        await mediator.Send(command, cancellationToken);

        // 2. 返回成功响应
        return ApiResponse<object>.Ok(null);
    }

    /// <summary>
    /// 更新门店。
    /// </summary>
    /// <param name="command">更新命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>更新结果。</returns>
    [HttpPost("update")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<object>> Update([FromBody] UpdateStoreCommand command, CancellationToken cancellationToken)
    {
        // 1. 执行更新
        await mediator.Send(command, cancellationToken);

        // 2. 返回成功响应
        return ApiResponse<object>.Ok(null);
    }

    /// <summary>
    /// 删除门店。
    /// </summary>
    /// <param name="command">删除命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>删除结果。</returns>
    [HttpPost("delete")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<object>> Delete([FromBody] DeleteStoreCommand command, CancellationToken cancellationToken)
    {
        // 1. 执行删除
        await mediator.Send(command, cancellationToken);

        // 2. 返回成功响应
        return ApiResponse<object>.Ok(null);
    }

    /// <summary>
    /// 快速切换门店经营状态。
    /// </summary>
    /// <param name="command">切换命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>切换后的门店信息。</returns>
    [HttpPost("toggle-business-status")]
    [ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<StoreDto>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<StoreDto>> ToggleBusinessStatus(
        [FromBody] ToggleBusinessStatusCommand command,
        CancellationToken cancellationToken)
    {
        // 1. 执行状态切换
        var result = await mediator.Send(command, cancellationToken);

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

    /// <summary>
    /// 手动重试门店地理定位。
    /// </summary>
    /// <param name="storeId">门店 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>重试结果。</returns>
    [HttpPost("{storeId}/geocode/retry")]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<ApiResponse<object>> RetryGeocode(string storeId, CancellationToken cancellationToken)
    {
        var parsedStoreId = StoreApiHelpers.ParseRequiredSnowflake(storeId, nameof(storeId));
        var (tenantId, merchantId) = StoreApiHelpers.GetTenantMerchantContext(storeContextService);
        var success = await geoLocationOrchestrator.RetryStoreAsync(
            tenantId,
            merchantId,
            parsedStoreId,
            cancellationToken);
        if (!success)
        {
            return ApiResponse<object>.Error(ErrorCodes.NotFound, "门店不存在或无权限访问");
        }

        return ApiResponse<object>.Ok(null);
    }
}

