using System.Text.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MilitaryTrainingManagement.Models.DTOs;
using MilitaryTrainingManagement.Models.Enums;
using MilitaryTrainingManagement.Services.Interfaces;

namespace MilitaryTrainingManagement.Controllers;

/// <summary>
/// 审批工作流控制器
/// </summary>
[Authorize]
public class ApprovalsController : BaseApiController
{
    private readonly IWorkflowService _workflowService;
    private readonly IAllocationService _allocationService;
    private readonly IAuditService _auditService;

    public ApprovalsController(
        IWorkflowService workflowService,
        IAllocationService allocationService,
        IAuditService auditService)
    {
        _workflowService = workflowService;
        _allocationService = allocationService;
        _auditService = auditService;
    }
    
    private string? GetClientIpAddress()
    {
        return HttpContext.Connection.RemoteIpAddress?.ToString();
    }

    /// <summary>
    /// 获取所有审批请求（分页）
    /// </summary>
    [HttpGet]
    public async Task<IActionResult> GetAll(
        [FromQuery] int pageNumber = 1,
        [FromQuery] int pageSize = 10,
        [FromQuery] string? status = null)
    {
        var unitId = GetCurrentUnitId();
        var unitLevel = GetCurrentUnitLevel();
        if (unitId == null || unitLevel == null)
            return Unauthorized(new { message = "无法获取用户组织信息" });

        ApprovalStatus? statusFilter = null;
        if (!string.IsNullOrEmpty(status) && Enum.TryParse<ApprovalStatus>(status, out var parsedStatus))
        {
            statusFilter = parsedStatus;
        }

        // 师团级别可以查看所有，其他级别只能查看自己提交的
        IEnumerable<Models.Entities.ApprovalRequest> requests;
        if (unitLevel == OrganizationalLevel.Division)
        {
            requests = await _workflowService.GetAllRequestsAsync(statusFilter);
        }
        else
        {
            requests = await _workflowService.GetRequestsByUnitAsync(unitId.Value, statusFilter);
        }

        var totalCount = requests.Count();
        var items = requests
            .Skip((pageNumber - 1) * pageSize)
            .Take(pageSize)
            .Select(MapToResponse)
            .ToList();

        return Ok(new
        {
            items,
            totalCount,
            pageNumber,
            pageSize,
            totalPages = (int)Math.Ceiling(totalCount / (double)pageSize)
        });
    }

    /// <summary>
    /// 获取待处理的审批请求（仅师团级别可见）
    /// 需求5.3：师团管理员审批修改请求
    /// </summary>
    [HttpGet("pending")]
    [Authorize(Policy = "DivisionLevel")]
    public async Task<IActionResult> GetPendingRequests()
    {
        var requests = await _workflowService.GetPendingRequestsAsync();
        var response = requests.Select(MapToResponse);
        return Ok(response);
    }

    /// <summary>
    /// 获取当前单位提交的审批请求
    /// </summary>
    [HttpGet("my")]
    public async Task<IActionResult> GetMyRequests([FromQuery] ApprovalStatus? status = null)
    {
        var unitId = GetCurrentUnitId();
        if (unitId == null)
            return Unauthorized(new { message = "无法获取用户组织信息" });

        var requests = await _workflowService.GetRequestsByUnitAsync(unitId.Value, status);
        var response = requests.Select(MapToResponse);
        return Ok(response);
    }


    /// <summary>
    /// 根据ID获取审批请求详情
    /// </summary>
    [HttpGet("{id}")]
    public async Task<IActionResult> GetById(int id)
    {
        var unitId = GetCurrentUnitId();
        var unitLevel = GetCurrentUnitLevel();
        if (unitId == null || unitLevel == null)
            return Unauthorized(new { message = "无法获取用户组织信息" });

        var request = await _workflowService.GetByIdAsync(id);
        if (request == null)
            return NotFound(new { message = "审批请求不存在" });

        // 检查访问权限：师团级别可以查看所有，其他级别只能查看自己提交的
        if (unitLevel != OrganizationalLevel.Division && request.RequestedByUnitId != unitId.Value)
            return Forbid();

        return Ok(MapToResponse(request));
    }

    /// <summary>
    /// 提交修改请求
    /// 需求5.1：用户可以请求修改已提交的报告
    /// 需求5.2：修改请求需要原因并路由到师团管理员
    /// </summary>
    [HttpPost]
    public async Task<IActionResult> CreateModificationRequest([FromBody] CreateModificationRequest request)
    {
        var userId = GetCurrentUserId();
        var unitId = GetCurrentUnitId();
        if (userId == null || unitId == null)
            return Unauthorized(new { message = "无法获取用户信息" });

        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        try
        {
            // 检查记录是否已被审批
            var isApproved = await _workflowService.IsRecordApprovedAsync(request.Type, request.TargetEntityId);
            if (isApproved)
            {
                // 已审批的记录需要通过工作流修改
                // 获取原始数据
                var originalData = await GetOriginalDataAsync(request.Type, request.TargetEntityId);
                
                var approvalRequest = await _workflowService.CreateModificationRequestAsync(
                    request.Type,
                    request.TargetEntityId,
                    userId.Value,
                    unitId.Value,
                    request.Reason,
                    originalData,
                    request.RequestedChanges);

                return CreatedAtAction(nameof(GetById), new { id = approvalRequest.Id }, MapToResponse(approvalRequest));
            }
            else
            {
                // 未审批的记录也可以提交修改请求（统一走审批流程）
                var originalData = await GetOriginalDataAsync(request.Type, request.TargetEntityId);
                
                var approvalRequest = await _workflowService.CreateModificationRequestAsync(
                    request.Type,
                    request.TargetEntityId,
                    userId.Value,
                    unitId.Value,
                    request.Reason,
                    originalData,
                    request.RequestedChanges);

                return CreatedAtAction(nameof(GetById), new { id = approvalRequest.Id }, MapToResponse(approvalRequest));
            }
        }
        catch (ArgumentException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (InvalidOperationException ex)
        {
            return Conflict(new { message = ex.Message });
        }
    }


    /// <summary>
    /// 审批通过请求
    /// 需求5.3：师团管理员可以查看并审批修改请求
    /// 需求5.4：审批通过后更新数据并维护审计跟踪
    /// </summary>
    [HttpPost("{id}/approve")]
    [Authorize(Policy = "DivisionLevel")]
    public async Task<IActionResult> Approve(int id, [FromBody] ProcessApprovalRequest request)
    {
        var userId = GetCurrentUserId();
        var unitId = GetCurrentUnitId();
        if (userId == null)
            return Unauthorized(new { message = "无法获取用户信息" });

        try
        {
            var approvalRequest = await _workflowService.ApproveAsync(id, userId.Value, request.Comments);
            
            // 记录审计日志
            await _auditService.LogApprovalAsync(
                "ApprovalRequest",
                id,
                "Approve",
                $"审批通过修改请求：{GetTypeName(approvalRequest.Type)}，处理意见：{request.Comments ?? "无"}",
                userId,
                unitId,
                GetClientIpAddress());
            
            return Ok(MapToResponse(approvalRequest));
        }
        catch (ArgumentException ex)
        {
            return NotFound(new { message = ex.Message });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (UnauthorizedAccessException ex)
        {
            return Forbid(ex.Message);
        }
    }

    /// <summary>
    /// 拒绝请求
    /// 需求5.3：师团管理员可以拒绝修改请求
    /// </summary>
    [HttpPost("{id}/reject")]
    [Authorize(Policy = "DivisionLevel")]
    public async Task<IActionResult> Reject(int id, [FromBody] ProcessApprovalRequest request)
    {
        var userId = GetCurrentUserId();
        var unitId = GetCurrentUnitId();
        if (userId == null)
            return Unauthorized(new { message = "无法获取用户信息" });

        try
        {
            var approvalRequest = await _workflowService.RejectAsync(id, userId.Value, request.Comments);
            
            // 记录审计日志
            await _auditService.LogApprovalAsync(
                "ApprovalRequest",
                id,
                "Reject",
                $"拒绝修改请求：{GetTypeName(approvalRequest.Type)}，处理意见：{request.Comments ?? "无"}",
                userId,
                unitId,
                GetClientIpAddress());
            
            return Ok(MapToResponse(approvalRequest));
        }
        catch (ArgumentException ex)
        {
            return NotFound(new { message = ex.Message });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (UnauthorizedAccessException ex)
        {
            return Forbid(ex.Message);
        }
    }

    /// <summary>
    /// 检查记录是否可以直接修改
    /// 需求5.5：已审批的记录不能直接修改
    /// </summary>
    [HttpGet("check/{type}/{entityId}")]
    public async Task<IActionResult> CheckModificationAllowed(ApprovalRequestType type, int entityId)
    {
        var isApproved = await _workflowService.IsRecordApprovedAsync(type, entityId);
        var hasPending = await _workflowService.HasPendingModificationRequestAsync(type, entityId);

        return Ok(new
        {
            isApproved,
            hasPendingRequest = hasPending,
            canDirectModify = !isApproved,
            requiresApproval = isApproved,
            message = isApproved ? "该记录已被审批，修改需要提交审批请求" :
                      hasPending ? "该记录已有待处理的修改请求" : "可以直接修改"
        });
    }


    /// <summary>
    /// 获取原始数据
    /// </summary>
    private async Task<string> GetOriginalDataAsync(ApprovalRequestType type, int entityId)
    {
        switch (type)
        {
            case ApprovalRequestType.ReportModification:
                var distribution = await _allocationService.GetDistributionByIdAsync(entityId);
                if (distribution == null)
                    throw new ArgumentException("目标上报记录不存在");
                return JsonSerializer.Serialize(new
                {
                    distribution.ActualCompletion,
                    distribution.UnitQuota,
                    distribution.ReportedAt
                });

            case ApprovalRequestType.AllocationModification:
                var allocation = await _allocationService.GetByIdAsync(entityId);
                if (allocation == null)
                    throw new ArgumentException("目标配额记录不存在");
                return JsonSerializer.Serialize(new
                {
                    allocation.Category,
                    allocation.MaterialName,
                    allocation.Unit,
                    allocation.TotalQuota
                });

            case ApprovalRequestType.PersonnelModification:
                // 人员修改的原始数据获取将在人员管理模块实现
                return "{}";

            default:
                return "{}";
        }
    }

    /// <summary>
    /// 映射实体到响应DTO
    /// </summary>
    private static ApprovalRequestResponse MapToResponse(Models.Entities.ApprovalRequest request)
    {
        return new ApprovalRequestResponse
        {
            Id = request.Id,
            Type = request.Type,
            TypeName = GetTypeName(request.Type),
            TargetEntityId = request.TargetEntityId,
            RequestedByUserId = request.RequestedByUserId,
            RequestedByUserName = request.RequestedByUser?.DisplayName ?? string.Empty,
            RequestedByUnitId = request.RequestedByUnitId,
            RequestedByUnitName = request.RequestedByUnit?.Name ?? string.Empty,
            Reason = request.Reason,
            OriginalData = request.OriginalData,
            RequestedChanges = request.RequestedChanges,
            Status = request.Status,
            StatusName = GetStatusName(request.Status),
            ReviewedByUserId = request.ReviewedByUserId,
            ReviewedByUserName = request.ReviewedByUser?.DisplayName,
            ReviewComments = request.ReviewComments,
            RequestedAt = request.RequestedAt,
            ReviewedAt = request.ReviewedAt
        };
    }

    private static string GetTypeName(ApprovalRequestType type)
    {
        return type switch
        {
            ApprovalRequestType.AllocationModification => "配额修改",
            ApprovalRequestType.ReportModification => "上报修改",
            ApprovalRequestType.PersonnelModification => "人员修改",
            _ => "未知类型"
        };
    }

    private static string GetStatusName(ApprovalStatus status)
    {
        return status switch
        {
            ApprovalStatus.Pending => "待审批",
            ApprovalStatus.Approved => "已批准",
            ApprovalStatus.Rejected => "已拒绝",
            _ => "未知状态"
        };
    }
}
