namespace WebApi.Controllers;

using Repository;

[ApiController]
[Route("api/[controller]/[action]")]
public class TransactionRecordController(
    ITransactionRecordRepository transactionRepository,
    ISmartHandleService smartHandleService,
    ILogger<TransactionRecordController> logger
) : ControllerBase
{
    /// <summary>
    /// 获取交易记录列表（分页）
    /// </summary>
    [HttpGet]
    public async Task<PagedResponse<TransactionRecord>> GetListAsync(
        [FromQuery] int pageIndex = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] string? searchKeyword = null,
        [FromQuery] string? classify = null,
        [FromQuery] int? type = null,
        [FromQuery] int? year = null,
        [FromQuery] int? month = null,
        [FromQuery] string? reason = null,
        [FromQuery] bool sortByAmount = false
    )
    {
        try
        {
            TransactionType? transactionType = type.HasValue ? (TransactionType)type.Value : null;
            var list = await transactionRepository.GetPagedListAsync(
                pageIndex,
                pageSize,
                searchKeyword,
                classify,
                transactionType,
                year,
                month,
                reason,
                sortByAmount);
            var total = await transactionRepository.GetTotalCountAsync(
                searchKeyword,
                classify,
                transactionType,
                year,
                month,
                reason);

            return new PagedResponse<TransactionRecord>
            {
                Success = true,
                Data = list.ToArray(),
                Total = (int)total
            };
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取交易记录列表失败，页码: {PageIndex}, 页大小: {PageSize}", pageIndex, pageSize);
            return PagedResponse<TransactionRecord>.Fail($"获取交易记录列表失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 根据ID获取交易记录详情
    /// </summary>
    [HttpGet("{id}")]
    public async Task<BaseResponse<TransactionRecord>> GetByIdAsync(long id)
    {
        try
        {
            var transaction = await transactionRepository.GetByIdAsync(id);
            if (transaction == null)
            {
                return "交易记录不存在".Fail<TransactionRecord>();
            }

            return transaction.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取交易记录详情失败，交易ID: {TransactionId}", id);
            return $"获取交易记录详情失败: {ex.Message}".Fail<TransactionRecord>();
        }
    }

    /// <summary>
    /// 根据邮件ID获取交易记录列表
    /// </summary>
    [HttpGet("{emailId}")]
    public async Task<BaseResponse<List<TransactionRecord>>> GetByEmailIdAsync(long emailId)
    {
        try
        {
            var transactions = await transactionRepository.GetByEmailIdAsync(emailId);
            return transactions.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取邮件交易记录失败，邮件ID: {EmailId}", emailId);
            return $"获取邮件交易记录失败: {ex.Message}".Fail<List<TransactionRecord>>();
        }
    }

    /// <summary>
    /// 创建交易记录
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse> CreateAsync([FromBody] CreateTransactionDto dto)
    {
        try
        {
            // 解析日期字符串
            if (!DateTime.TryParse(dto.OccurredAt, out var occurredAt))
            {
                return "交易时间格式不正确".Fail();
            }

            var transaction = new TransactionRecord
            {
                OccurredAt = occurredAt,
                Reason = dto.Reason ?? string.Empty,
                Amount = dto.Amount,
                Type = dto.Type,
                Classify = dto.Classify ?? string.Empty,
                ImportFrom = "手动录入",
                ImportNo = Guid.NewGuid().ToString("N"),
                Card = "手动",
                EmailMessageId = 0 // 手动录入的记录，EmailMessageId 设为 0
            };

            var result = await transactionRepository.AddAsync(transaction);
            if (result)
            {
                return BaseResponse.Done();
            }
            else
            {
                return "创建交易记录失败".Fail();
            }
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "创建交易记录失败，交易信息: {@TransactionDto}", dto);
            return $"创建交易记录失败: {ex.Message}".Fail();
        }
    }

    /// <summary>
    /// 更新交易记录
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse> UpdateAsync([FromBody] UpdateTransactionDto dto)
    {
        try
        {
            var transaction = await transactionRepository.GetByIdAsync(dto.Id);
            if (transaction == null)
            {
                return "交易记录不存在".Fail();
            }

            // 更新可编辑字段
            transaction.Reason = dto.Reason ?? string.Empty;
            transaction.Amount = dto.Amount;
            transaction.Balance = dto.Balance;
            transaction.Type = dto.Type;
            transaction.Classify = dto.Classify ?? string.Empty;

            var success = await transactionRepository.UpdateAsync(transaction);
            if (success)
            {
                return BaseResponse.Done();
            }
            else
            {
                return "更新交易记录失败".Fail();
            }
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "更新交易记录失败，交易ID: {TransactionId}, 交易信息: {@TransactionDto}", dto.Id, dto);
            return $"更新交易记录失败: {ex.Message}".Fail();
        }
    }

    /// <summary>
    /// 删除交易记录
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse> DeleteByIdAsync([FromQuery] long id)
    {
        try
        {
            var success = await transactionRepository.DeleteAsync(id);
            if (success)
            {
                return BaseResponse.Done();
            }
            else
            {
                return "删除交易记录失败，记录不存在".Fail();
            }
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "删除交易记录失败，交易ID: {TransactionId}", id);
            return $"删除交易记录失败: {ex.Message}".Fail();
        }
    }

    /// <summary>
    /// 获取指定月份每天的消费统计
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<List<DailyStatisticsDto>>> GetDailyStatisticsAsync(
        [FromQuery] int year,
        [FromQuery] int month
    )
    {
        try
        {
            var statistics = await transactionRepository.GetDailyStatisticsAsync(year, month);
            var result = statistics.Select(s => new DailyStatisticsDto(s.Key, s.Value.count, s.Value.amount)).ToList();

            return result.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取日历统计数据失败，年份: {Year}, 月份: {Month}", year, month);
            return $"获取日历统计数据失败: {ex.Message}".Fail<List<DailyStatisticsDto>>();
        }
    }

    /// <summary>
    /// 获取月度统计数据
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<MonthlyStatistics>> GetMonthlyStatisticsAsync(
        [FromQuery] int year,
        [FromQuery] int month
    )
    {
        try
        {
            var statistics = await transactionRepository.GetMonthlyStatisticsAsync(year, month);
            return statistics.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取月度统计数据失败，年份: {Year}, 月份: {Month}", year, month);
            return $"获取月度统计数据失败: {ex.Message}".Fail<MonthlyStatistics>();
        }
    }

    /// <summary>
    /// 获取分类统计数据
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<List<CategoryStatistics>>> GetCategoryStatisticsAsync(
        [FromQuery] int year,
        [FromQuery] int month,
        [FromQuery] TransactionType type
    )
    {
        try
        {
            var statistics = await transactionRepository.GetCategoryStatisticsAsync(year, month, type);
            return statistics.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取分类统计数据失败，年份: {Year}, 月份: {Month}, 类型: {Type}", year, month, type);
            return $"获取分类统计数据失败: {ex.Message}".Fail<List<CategoryStatistics>>();
        }
    }

    /// <summary>
    /// 获取趋势统计数据
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<List<TrendStatistics>>> GetTrendStatisticsAsync(
        [FromQuery] int startYear,
        [FromQuery] int startMonth,
        [FromQuery] int monthCount = 6
    )
    {
        try
        {
            var statistics = await transactionRepository.GetTrendStatisticsAsync(startYear, startMonth, monthCount);
            return statistics.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取趋势统计数据失败，开始年份: {Year}, 开始月份: {Month}, 月份数: {Count}", startYear, startMonth, monthCount);
            return $"获取趋势统计数据失败: {ex.Message}".Fail<List<TrendStatistics>>();
        }
    }

    /// <summary>
    /// 智能分析账单（流式输出）
    /// </summary>
    public async Task AnalyzeBillAsync([FromBody] BillAnalysisRequest request)
    {
        Response.ContentType = "text/event-stream";
        Response.Headers.Append("Cache-Control", "no-cache");
        Response.Headers.Append("Connection", "keep-alive");

        if (string.IsNullOrWhiteSpace(request.UserInput))
        {
            await WriteEventAsync("<div class='error-message'>请输入分析内容</div>");
            return;
        }

        await smartHandleService.AnalyzeBillAsync(request.UserInput, async (chunk) =>
        {
            await WriteEventAsync(chunk);
        });
    }

    /// <summary>
    /// 获取指定日期的交易记录
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<List<TransactionRecord>>> GetByDateAsync([FromQuery] string date)
    {
        try
        {
            if (!DateTime.TryParse(date, out var targetDate))
            {
                return "日期格式不正确".Fail<List<TransactionRecord>>();
            }

            // 获取当天的开始和结束时间
            var startDate = targetDate.Date;
            var endDate = startDate.AddDays(1);

            var records = await transactionRepository.GetByDateRangeAsync(startDate, endDate);

            return records.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取指定日期的交易记录失败，日期: {Date}", date);
            return $"获取指定日期的交易记录失败: {ex.Message}".Fail<List<TransactionRecord>>();
        }
    }

    /// <summary>
    /// 获取未分类的账单数量
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<int>> GetUnclassifiedCountAsync()
    {
        try
        {
            var count = await transactionRepository.GetUnclassifiedCountAsync();
            return count.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取未分类账单数量失败");
            return $"获取未分类账单数量失败: {ex.Message}".Fail<int>();
        }
    }

    /// <summary>
    /// 获取未分类的账单列表
    /// </summary>
    [HttpGet]
    public async Task<BaseResponse<List<TransactionRecord>>> GetUnclassifiedAsync([FromQuery] int pageSize = 10)
    {
        try
        {
            var records = await transactionRepository.GetUnclassifiedAsync(pageSize);
            return records.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取未分类账单列表失败");
            return $"获取未分类账单列表失败: {ex.Message}".Fail<List<TransactionRecord>>();
        }
    }

    /// <summary>
    /// 智能分类 - 使用AI对账单进行分类（流式响应）
    /// </summary>
    [HttpPost]
    public async Task SmartClassifyAsync([FromBody] SmartClassifyRequest request)
    {
        Response.ContentType = "text/event-stream";
        Response.Headers.Append("Cache-Control", "no-cache");
        Response.Headers.Append("Connection", "keep-alive");

        // 验证账单ID列表
        if (request.TransactionIds == null || request.TransactionIds.Count == 0)
        {
            await WriteEventAsync("error", "请提供要分类的账单ID");
            return;
        }

        await smartHandleService.SmartClassifyAsync(request.TransactionIds.ToArray(), async (chunk) =>
        {
            var (eventType, content) = chunk;
            await WriteEventAsync(eventType, content);
        });

        await Response.Body.FlushAsync();
    }

    /// <summary>
    /// 批量更新账单分类
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse> BatchUpdateClassifyAsync([FromBody] List<BatchUpdateClassifyItem> items)
    {
        try
        {
            var successCount = 0;
            var failCount = 0;

            foreach (var item in items)
            {
                var record = await transactionRepository.GetByIdAsync(item.Id);
                if (record != null)
                {
                    record.Classify = item.Classify ?? string.Empty;
                    // 如果提供了Type，也更新Type
                    if (item.Type.HasValue)
                    {
                        record.Type = item.Type.Value;
                    }
                    var success = await transactionRepository.UpdateAsync(record);
                    if (success)
                        successCount++;
                    else
                        failCount++;
                }
                else
                {
                    failCount++;
                }
            }

            return $"批量更新完成，成功 {successCount} 条，失败 {failCount} 条".Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "批量更新分类失败");
            return $"批量更新分类失败: {ex.Message}".Fail();
        }
    }

    /// <summary>
    /// 获取按交易摘要分组的统计信息（支持分页）
    /// </summary>
    [HttpGet]
    public async Task<PagedResponse<ReasonGroupDto>> GetReasonGroupsAsync(
        [FromQuery] int pageIndex = 1,
        [FromQuery] int pageSize = 20)
    {
        try
        {
            var (list, total) = await transactionRepository.GetReasonGroupsAsync(pageIndex, pageSize);
            return new PagedResponse<ReasonGroupDto>
            {
                Success = true,
                Data = list.ToArray(),
                Total = total
            };
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取交易摘要分组失败");
            return PagedResponse<ReasonGroupDto>.Fail($"获取交易摘要分组失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 按摘要批量更新分类
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse<int>> BatchUpdateByReasonAsync([FromBody] BatchUpdateByReasonDto dto)
    {
        try
        {
            var count = await transactionRepository.BatchUpdateByReasonAsync(dto.Reason, dto.Type, dto.Classify);
            return count.Ok($"成功更新 {count} 条记录");
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "按摘要批量更新分类失败，摘要: {Reason}", dto.Reason);
            return $"按摘要批量更新分类失败: {ex.Message}".Fail<int>();
        }
    }

    /// <summary>
    /// 一句话录账解析
    /// </summary>
    [HttpPost]
    public async Task<BaseResponse<TransactionParseResult>> ParseOneLine([FromBody] ParseOneLineRequestDto request)
    {
        if (string.IsNullOrEmpty(request.Text))
        {
            return "请求参数缺失：text".Fail<TransactionParseResult>();
        }

        try
        {
            var result = await smartHandleService.ParseOneLineBillAsync(request.Text);

            if (result == null)
            {
                return "AI解析失败".Fail<TransactionParseResult>();
            }

            return result.Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "一句话录账解析失败，文本: {Text}", request.Text);
            return ("AI解析失败: " + ex.Message).Fail<TransactionParseResult>();
        }
    }

    /// <summary>
    /// 获取抵账候选列表
    /// </summary>
    [HttpGet("{id}")]
    public async Task<BaseResponse<TransactionRecord[]>> GetCandidatesForOffset(long id)
    {
        try
        {
            var current = await transactionRepository.GetByIdAsync(id);
            if (current == null)
            {
                return ((TransactionRecord[])[]).Ok();
            }

            var list = await transactionRepository.GetCandidatesForOffsetAsync(id, current.Amount, current.Type);

            return list.ToArray().Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取抵账候选列表失败，交易ID: {TransactionId}", id);
            return $"获取抵账候选列表失败: {ex.Message}".Fail<TransactionRecord[]>();
        }
    }

    /// <summary>
    /// 抵账（删除两笔交易）
    /// </summary>
    [HttpPost]
    public async Task<IActionResult> OffsetTransactions([FromBody] OffsetTransactionDto dto)
    {
        var t1 = await transactionRepository.GetByIdAsync(dto.Id1);
        var t2 = await transactionRepository.GetByIdAsync(dto.Id2);

        if (t1 == null || t2 == null)
        {
            return NotFound("交易记录不存在");
        }

        await transactionRepository.DeleteAsync(dto.Id1);
        await transactionRepository.DeleteAsync(dto.Id2);

        return Ok(new { success = true, message = "抵账成功" });
    }

    private async Task WriteEventAsync(string eventType, string data)
    {
        var message = $"event: {eventType}\ndata: {data}\n\n";
        await Response.WriteAsync(message);
        await Response.Body.FlushAsync();
    }

    private async Task WriteEventAsync(string data)
    {
        var message = $"data: {data}\n\n";
        await Response.WriteAsync(message);
        await Response.Body.FlushAsync();
    }

    private static string GetTypeName(TransactionType type)
    {
        return type switch
        {
            TransactionType.Expense => "支出",
            TransactionType.Income => "收入",
            TransactionType.None => "不计入收支",
            _ => "未知"
        };
    }
}

/// <summary>
/// 创建交易记录DTO
/// </summary>
public record CreateTransactionDto(
    string OccurredAt,
    string? Reason,
    decimal Amount,
    TransactionType Type,
    string? Classify
);

/// <summary>
/// 更新交易记录DTO
/// </summary>
public record UpdateTransactionDto(
    long Id,
    string? Reason,
    decimal Amount,
    decimal Balance,
    TransactionType Type,
    string? Classify
);

/// <summary>
/// 日历统计响应DTO
/// </summary>
public record DailyStatisticsDto(
    string Date,
    int Count,
    decimal Amount
);

/// <summary>
/// 智能分类请求DTO
/// </summary>
public record SmartClassifyRequest(
    List<long>? TransactionIds = null
);

/// <summary>
/// 批量更新分类项DTO
/// </summary>
public record BatchUpdateClassifyItem(
    long Id,
    string? Classify,
    TransactionType? Type = null
);

/// <summary>
/// 按摘要批量更新DTO
/// </summary>
public record BatchUpdateByReasonDto(
    string Reason,
    TransactionType Type,
    string Classify
);

/// <summary>
/// 账单分析请求DTO
/// </summary>
public record BillAnalysisRequest(
    string UserInput
);

/// <summary>
/// 抵账请求DTO
/// </summary>
public record OffsetTransactionDto(
    long Id1,
    long Id2
);


public record ParseOneLineRequestDto(
    string Text
);