using Microsoft.EntityFrameworkCore;
using MilitaryTrainingManagement.Data;
using MilitaryTrainingManagement.Models.Entities;
using MilitaryTrainingManagement.Models.Enums;
using MilitaryTrainingManagement.Services.Interfaces;

namespace MilitaryTrainingManagement.Services.Implementations;

/// <summary>
/// 组织管理服务实现
/// </summary>
public class OrganizationService : IOrganizationService
{
    private readonly ApplicationDbContext _context;

    public OrganizationService(ApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<OrganizationalUnit?> GetByIdAsync(int id)
    {
        return await _context.OrganizationalUnits
            .Include(u => u.Parent)
            .Include(u => u.Children)
            .FirstOrDefaultAsync(u => u.Id == id);
    }

    public async Task<IEnumerable<OrganizationalUnit>> GetAllAsync()
    {
        var allUnits = await _context.OrganizationalUnits
            .OrderBy(u => u.Level)
            .ThenBy(u => u.CreatedAt)  // 按创建时间排序，新的在后面
            .ToListAsync();

        // 构建树形结构，只返回顶级节点（师团级）
        var rootUnits = allUnits.Where(u => u.ParentId == null).OrderBy(u => u.CreatedAt).ToList();
        
        // 递归构建子节点
        foreach (var root in rootUnits)
        {
            BuildChildrenTree(root, allUnits);
        }

        return rootUnits;
    }

    private void BuildChildrenTree(OrganizationalUnit parent, List<OrganizationalUnit> allUnits)
    {
        var children = allUnits.Where(u => u.ParentId == parent.Id).OrderBy(u => u.CreatedAt).ToList();
        parent.Children = children;
        
        foreach (var child in children)
        {
            child.Parent = parent;
            BuildChildrenTree(child, allUnits);
        }
    }

    public async Task<IEnumerable<OrganizationalUnit>> GetSubordinatesAsync(int unitId)
    {
        var unit = await _context.OrganizationalUnits.FindAsync(unitId);
        if (unit == null)
            return Enumerable.Empty<OrganizationalUnit>();

        return await GetAllSubordinatesRecursiveAsync(unitId);
    }

    private async Task<List<OrganizationalUnit>> GetAllSubordinatesRecursiveAsync(int unitId)
    {
        var result = new List<OrganizationalUnit>();
        var directChildren = await _context.OrganizationalUnits
            .Where(u => u.ParentId == unitId)
            .ToListAsync();

        foreach (var child in directChildren)
        {
            result.Add(child);
            var grandChildren = await GetAllSubordinatesRecursiveAsync(child.Id);
            result.AddRange(grandChildren);
        }

        return result;
    }

    public async Task<OrganizationalUnit> CreateAsync(string name, OrganizationalLevel level, int? parentId)
    {
        if (parentId.HasValue)
        {
            var parent = await _context.OrganizationalUnits.FindAsync(parentId.Value);
            if (parent == null)
                throw new ArgumentException("父级组织单位不存在");

            if ((int)level <= (int)parent.Level)
                throw new ArgumentException("子级组织层级必须低于父级");
        }
        else if (level != OrganizationalLevel.Division)
        {
            throw new ArgumentException("非师团级组织必须有父级单位");
        }

        var unit = new OrganizationalUnit
        {
            Name = name,
            Level = level,
            ParentId = parentId,
            CreatedAt = DateTime.UtcNow
        };

        _context.OrganizationalUnits.Add(unit);
        await _context.SaveChangesAsync();
        return unit;
    }

    public async Task<OrganizationalUnit> UpdateAsync(int id, string name)
    {
        var unit = await _context.OrganizationalUnits.FindAsync(id);
        if (unit == null)
            throw new ArgumentException("组织单位不存在");

        unit.Name = name;
        await _context.SaveChangesAsync();
        return unit;
    }

    public async Task DeleteAsync(int id)
    {
        var unit = await _context.OrganizationalUnits
            .Include(u => u.Children)
            .FirstOrDefaultAsync(u => u.Id == id);

        if (unit == null)
            throw new ArgumentException("组织单位不存在");

        if (unit.Children.Any())
            throw new InvalidOperationException("无法删除有下级单位的组织");

        // 检查是否有关联的用户账户
        var hasUsers = await _context.UserAccounts
            .AnyAsync(u => u.OrganizationalUnitId == id);
        if (hasUsers)
            throw new InvalidOperationException("无法删除有关联用户的组织");

        _context.OrganizationalUnits.Remove(unit);
        await _context.SaveChangesAsync();
    }

    public async Task<bool> IsSubordinateOfAsync(int unitId, int potentialParentId)
    {
        var unit = await _context.OrganizationalUnits.FindAsync(unitId);
        if (unit == null)
            return false;

        var currentParentId = unit.ParentId;
        while (currentParentId.HasValue)
        {
            if (currentParentId.Value == potentialParentId)
                return true;

            var parent = await _context.OrganizationalUnits.FindAsync(currentParentId.Value);
            currentParentId = parent?.ParentId;
        }

        return false;
    }

    public async Task<IEnumerable<int>> GetAllSubordinateIdsAsync(int unitId)
    {
        var subordinates = await GetAllSubordinatesRecursiveAsync(unitId);
        return subordinates.Select(u => u.Id);
    }

    public async Task<bool> IsUnitOrSubordinateAsync(int userUnitId, int targetUnitId)
    {
        // 如果是同一个单位，直接返回true
        if (userUnitId == targetUnitId)
            return true;

        // 检查目标单位是否是用户单位的下级
        return await IsSubordinateOfAsync(targetUnitId, userUnitId);
    }

    public async Task<bool> IsParentUnitAsync(int parentUnitId, int childUnitId)
    {
        var childUnit = await _context.OrganizationalUnits.FindAsync(childUnitId);
        if (childUnit == null)
            return false;

        // 检查直接父级关系
        if (childUnit.ParentId == parentUnitId)
            return true;

        // 检查是否是上级单位（递归向上查找）
        return await IsSubordinateOfAsync(childUnitId, parentUnitId);
    }

    public async Task<IEnumerable<int>> GetAllAncestorIdsAsync(int unitId)
    {
        var result = new List<int>();
        var currentUnit = await _context.OrganizationalUnits.FindAsync(unitId);
        
        while (currentUnit?.ParentId != null)
        {
            result.Add(currentUnit.ParentId.Value);
            currentUnit = await _context.OrganizationalUnits.FindAsync(currentUnit.ParentId.Value);
        }
        
        return result;
    }

    /// <summary>
    /// 获取用户可见的单位ID列表
    /// 营部及以下级别：本单位 + 直接下级
    /// 师团级别：本单位 + 所有下级
    /// </summary>
    public async Task<IEnumerable<int>> GetVisibleUnitIdsAsync(int unitId, OrganizationalLevel userLevel)
    {
        var result = new List<int> { unitId };
        
        // 检查单位是否存在
        var unit = await _context.OrganizationalUnits.FindAsync(unitId);
        if (unit == null)
        {
            return Enumerable.Empty<int>();
        }

        // 营部及以下级别（Battalion = 3, Company = 4）：只返回本单位 + 直接下级
        if (userLevel == OrganizationalLevel.Battalion || userLevel == OrganizationalLevel.Company)
        {
            var directChildren = await _context.OrganizationalUnits
                .Where(u => u.ParentId == unitId)
                .Select(u => u.Id)
                .ToListAsync();
            
            result.AddRange(directChildren);
        }
        // 师团级别（Division = 1, Regiment = 2）：返回本单位 + 所有下级
        else
        {
            var allSubordinates = await GetAllSubordinateIdsAsync(unitId);
            result.AddRange(allSubordinates);
        }

        return result;
    }
}
