namespace WebApi.Controllers;

[ApiController]
[Route("api/[controller]/[action]")]
public class BudgetController(
    IBudgetService budgetService,
    IBudgetRepository budgetRepository,
    ILogger<BudgetController> logger) : ControllerBase
{
    /// <summary>
    /// 获取预算列表
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<List<BudgetResult>>> GetListAsync([FromQuery] DateTime referenceDate)
    {
        try
        {
            return (await budgetService.GetListAsync(referenceDate))
                .OrderByDescending(b => b.IsMandatoryExpense)
                .ThenBy(b => b.Category)
                .ThenBy(b => b.Type)
                .ThenByDescending(b => b.Limit > 0 ? b.Current / b.Limit : 0)
                .ThenBy(b => b.Name)
                .ToList()
                .Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取预算列表失败");
            return $"获取预算列表失败: {ex.Message}".Fail<List<BudgetResult>>();
        }
    }

    /// <summary>
    /// 获取分类统计信息（月度和年度）
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<BudgetCategoryStats>> GetCategoryStatsAsync([FromQuery] BudgetCategory category, [FromQuery] DateTime referenceDate)
    {
        try
        {
            var result = await budgetService.GetCategoryStatsAsync(category, referenceDate);
            return result.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取分类统计失败, Category: {Category}", category);
            return $"获取分类统计失败: {ex.Message}".Fail<BudgetCategoryStats>();
        }
    }

    /// <summary>
    /// 获取未被预算覆盖的分类统计信息
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<List<UncoveredCategoryDetail>>> GetUncoveredCategoriesAsync([FromQuery] BudgetCategory category, [FromQuery] DateTime? referenceDate = null)
    {
        try
        {
            var result = await budgetService.GetUncoveredCategoriesAsync(category, referenceDate);
            return result.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取未覆盖分类统计失败, Category: {Category}", category);
            return $"获取未覆盖分类统计失败: {ex.Message}".Fail<List<UncoveredCategoryDetail>>();
        }
    }

    /// <summary>
    /// 获取归档总结
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<string?>> GetArchiveSummaryAsync([FromQuery] DateTime referenceDate)
    {
        try
        {
            var result = await budgetService.GetArchiveSummaryAsync(referenceDate.Year, referenceDate.Month);
            return result.Ok<string?>();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取归档总结失败");
            return $"获取归档总结失败: {ex.Message}".Fail<string?>();
        }
    }

    /// <summary>
    /// 获取指定周期的存款预算信息
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<BudgetResult?>> GetSavingsBudgetAsync(int year, int month, BudgetPeriodType type)
    {
        try
        {
            var result = await budgetService.GetSavingsBudgetAsync(year, month, type);
            return result.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取存款预算信息失败");
            return $"获取存款预算信息失败: {ex.Message}".Fail<BudgetResult?>();
        }
    }

    /// <summary>
    /// 删除预算
    /// </summary>
    [HttpDelete("{id}")]
    public async Task<BaseResponse> DeleteByIdAsync(long id)
    {
        try
        {
            var success = await budgetRepository.DeleteAsync(id);
            return success ? BaseResponse.Done() : "删除预算失败".Fail();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "删除预算失败, Id: {Id}", id);
            return $"删除预算失败: {ex.Message}".Fail();
        }
    }

    /// <summary>
    /// 创建预算
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse<long>> CreateAsync([FromBody] CreateBudgetDto dto)
    {
        try
        {
            // 不记额预算的金额强制设为0
            var limit = dto.NoLimit ? 0 : dto.Limit;

            var budget = new BudgetRecord
            {
                Name = dto.Name,
                Type = dto.Type,
                Limit = limit,
                Category = dto.Category,
                SelectedCategories = string.Join(",", dto.SelectedCategories),
                StartDate = dto.StartDate ?? DateTime.Now,
                NoLimit = dto.NoLimit,
                IsMandatoryExpense = dto.IsMandatoryExpense
            };

            var varidationError = await ValidateBudgetSelectedCategoriesAsync(budget);
            if (!string.IsNullOrEmpty(varidationError))
            {
                return varidationError.Fail<long>();
            }

            var success = await budgetRepository.AddAsync(budget);
            if (success)
            {
                return budget.Id.Ok();
            }
            return "创建预算失败".Fail<long>();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "创建预算失败");
            return $"创建预算失败: {ex.Message}".Fail<long>();
        }
    }

    /// <summary>
    /// 更新预算
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse> UpdateAsync([FromBody] UpdateBudgetDto dto)
    {
        try
        {
            var budget = await budgetRepository.GetByIdAsync(dto.Id);
            if (budget == null) return "预算不存在".Fail();

            // 不记额预算的金额强制设为0
            var limit = dto.NoLimit ? 0 : dto.Limit;

            budget.Name = dto.Name;
            budget.Type = dto.Type;
            budget.Limit = limit;
            budget.Category = dto.Category;
            budget.SelectedCategories = string.Join(",", dto.SelectedCategories);
            budget.NoLimit = dto.NoLimit;
            budget.IsMandatoryExpense = dto.IsMandatoryExpense;
            if (dto.StartDate.HasValue)
            {
                budget.StartDate = dto.StartDate.Value;
            }

            var varidationError = await ValidateBudgetSelectedCategoriesAsync(budget);
            if (!string.IsNullOrEmpty(varidationError))
            {
                return varidationError.Fail();
            }

            var success = await budgetRepository.UpdateAsync(budget);
            return success ? BaseResponse.Done() : "更新预算失败".Fail();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "更新预算失败, Id: {Id}", dto.Id);
            return $"更新预算失败: {ex.Message}".Fail();
        }
    }

    private async Task<string> ValidateBudgetSelectedCategoriesAsync(BudgetRecord record)
    {
        // 验证不记额预算必须是年度预算
        if (record.NoLimit && record.Type != BudgetPeriodType.Year)
        {
            return "不记额预算只能设置为年度预算。";
        }

        var allBudgets = await budgetRepository.GetAllAsync();

        var recordSelectedCategories = record.SelectedCategories.Split(',', StringSplitOptions.RemoveEmptyEntries);
        foreach (var budget in allBudgets)
        {
            var selectedCategories = budget.SelectedCategories.Split(',', StringSplitOptions.RemoveEmptyEntries);
            if (budget.Id != record.Id)
            {
                if (budget.Category == record.Category &&
                    recordSelectedCategories.Intersect(selectedCategories).Any())
                {
                    return $"和 {budget.Name} 存在分类冲突，请调整相关分类。";
                }
            }
        }

        return string.Empty;
    }
}
