using MediatR;
using System.Text.Json;
using TakeoutSaaS.Application.App.Personal.Dto;
using TakeoutSaaS.Application.App.Personal.Queries;
using TakeoutSaaS.Application.App.Personal.Services;
using TakeoutSaaS.Application.App.Personal.Validators;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Results;

namespace TakeoutSaaS.Application.App.Personal.Handlers;

/// <summary>
/// 分页查询个人操作记录处理器。
/// </summary>
public sealed class SearchPersonalOperationsQueryHandler(
    PersonalContextService personalContextService,
    PersonalDateRangeValidator personalDateRangeValidator,
    IOperationLogRepository operationLogRepository)
    : IRequestHandler<SearchPersonalOperationsQuery, PagedResult<PersonalOperationLogDto>>
{
    /// <summary>
    /// 处理查询。
    /// </summary>
    /// <param name="request">查询请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>操作记录分页结果。</returns>
    public async Task<PagedResult<PersonalOperationLogDto>> Handle(SearchPersonalOperationsQuery request, CancellationToken cancellationToken)
    {
        // 1. 获取上下文并解析时间窗
        var context = personalContextService.GetRequiredContext();
        var dateRange = personalDateRangeValidator.Resolve(request.From, request.To);

        // 2. 解析分页参数（默认 50，上限 50）
        var page = request.Page <= 0 ? 1 : request.Page;
        var pageSize = request.PageSize <= 0 ? 50 : Math.Min(request.PageSize, 50);

        // 3. 查询并映射
        var paged = await operationLogRepository.SearchByOperatorPagedAsync(
            context.TenantId,
            context.UserId.ToString(),
            dateRange.From,
            dateRange.To,
            page,
            pageSize,
            cancellationToken);
        var items = paged.Items.Select(log => new PersonalOperationLogDto
        {
            OperationId = log.Id,
            OperatorUserId = ParseOperatorUserId(log.OperatorId, context.UserId),
            ActionType = log.OperationType,
            TargetType = log.TargetType,
            TargetId = ResolveTargetId(log.TargetIds),
            IsSuccess = log.Success,
            OccurredAt = log.CreatedAt
        }).ToList();

        // 4. 返回分页结果
        return new PagedResult<PersonalOperationLogDto>(items, page, pageSize, paged.Total);
    }

    private static long ParseOperatorUserId(string? operatorId, long fallbackUserId)
    {
        // 1. 尝试从字符串解析用户 ID
        if (long.TryParse(operatorId, out var parsed) && parsed > 0)
        {
            return parsed;
        }

        // 2. 解析失败时回退当前用户
        return fallbackUserId;
    }

    private static string? ResolveTargetId(string? targetIds)
    {
        // 1. 空值直接返回
        if (string.IsNullOrWhiteSpace(targetIds))
        {
            return null;
        }

        // 2. 尝试解析 JSON 数组并提取首个元素
        var normalized = targetIds.Trim();
        if (normalized.StartsWith("[", StringComparison.Ordinal))
        {
            try
            {
                using var doc = JsonDocument.Parse(normalized);
                if (doc.RootElement.ValueKind == JsonValueKind.Array && doc.RootElement.GetArrayLength() > 0)
                {
                    return doc.RootElement[0].ToString();
                }
            }
            catch (JsonException)
            {
                // 3. JSON 解析失败时按原始字符串返回
            }
        }

        // 4. 非数组场景直接返回原值
        return normalized;
    }
}
