import { Injectable, NotFoundException, ConflictException, BadRequestException, Logger } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import {
  CreateOrganizationDto,
  UpdateOrganizationDto,
  OrganizationQueryDto,
  OrganizationRegionDto,
  OrganizationStatsDto,
  UserOrganizationDto,
  OrganizationStatus,
} from './dto';
import {
  IamOrganizationCodeExistsException,
  IamOrganizationNameExistsException,
} from '../exceptions';

@Injectable()
export class OrganizationsService {
  private readonly logger = new Logger(OrganizationsService.name);

  constructor(private prisma: PrismaService) {}

  /**
   * 创建组织
   * 
   * v2.1.16: 自动创建根部门（与组织同名）
   */
  async create(createDto: CreateOrganizationDto) {
    const { regionIds, ...organizationData } = createDto;

    // 检查 code, name, taxId 是否已存在（v2.1 增强）
    const whereConditions: Array<{ code?: string; name?: string; taxId?: string }> = [
      { code: createDto.code },
      { name: createDto.name },
    ];
    
    // 只有提供了 taxId 才检查（taxId 可选）
    if (createDto.taxId) {
      whereConditions.push({ taxId: createDto.taxId });
    }

    const existing = await this.prisma.organization.findFirst({
      where: {
        OR: whereConditions,
        deletedAt: null,
      },
    });

    if (existing) {
      // v2.1.1: 根据具体冲突字段返回对应的错误（使用自定义异常）
      if (existing.code === createDto.code) {
        throw new IamOrganizationCodeExistsException(createDto.code);
      } else if (existing.name === createDto.name) {
        throw new IamOrganizationNameExistsException(createDto.name);
      } else if (existing.taxId === createDto.taxId) {
        throw new ConflictException(`Tax ID '${createDto.taxId}' already exists`);
      }
    }

    // 如果指定了主要区域，验证其存在性
    if (createDto.primaryRegionId) {
      const region = await this.prisma.region.findUnique({
        where: { id: createDto.primaryRegionId },
      });
      if (!region) {
        throw new NotFoundException(`Primary region '${createDto.primaryRegionId}' not found`);
      }
    }

    // 使用事务创建组织和根部门
    const result = await this.prisma.$transaction(async (tx) => {
      // 1. 创建组织
      const organization = await tx.organization.create({
        data: {
          ...organizationData,
          establishedAt: organizationData.establishedAt ? new Date(organizationData.establishedAt) : null,
        },
      });

      // 2. 自动创建根部门（v2.1.16）
      // 根部门的 parentId = null，表示顶级部门
      const rootDepartment = await tx.department.create({
        data: {
          name: organization.name,
          code: organization.code,
          organizationId: organization.id,
          parentId: null,
          description: `${organization.name} 顶级部门（自动创建）`,
        },
      });

      this.logger.log(`Created root department for organization ${organization.id}: ${rootDepartment.id}`);

      return { organization, rootDepartment };
    });

    // 如果提供了区域ID列表，创建区域关联
    if (regionIds && regionIds.length > 0) {
      await this.addRegions(result.organization.id, { 
        regionIds,
        primaryRegionId: createDto.primaryRegionId,
      });
    }

    // 重新查询以包含完整信息
    const organizationWithDetails = await this.prisma.organization.findUnique({
      where: { id: result.organization.id },
      include: {
        primaryRegion: true,
        organizationRegions: {
          include: {
            region: true,
          },
        },
        departments: {
          where: { parentId: null }, // 只查询根部门
        },
      },
    });

    return organizationWithDetails;
  }

  /**
   * 查询组织列表（v2.1 - 支持组织级过滤）
   * @param query 查询参数
   * @param currentUserId 当前用户ID（用于组织级过滤）
   */
  async findAll(query: OrganizationQueryDto, currentUserId?: string) {
    const {
      search,
      primaryRegionId,
      status,
      isActive,
      page = 1,
      pageSize = 20,
      sortBy = 'createdAt',
      sortOrder = 'desc',
    } = query;

    const where: any = {
      deletedAt: null,
    };

    // v2.1: 如果提供了 currentUserId，只返回用户所属的组织
    if (currentUserId) {
      const userOrganizations = await this.prisma.userDepartment.findMany({
        where: {
          userId: currentUserId,
          leftAt: null,
        },
        select: {
          organizationId: true,
        },
        distinct: ['organizationId'],
      });

      const organizationIds = userOrganizations.map(uo => uo.organizationId);
      
      if (organizationIds.length > 0) {
        where.id = { in: organizationIds };
      } else {
        // 用户不属于任何组织，返回空列表
        return {
          items: [],
          total: 0,
          page,
          pageSize,
          totalPages: 0,
        };
      }
    }

    // 搜索条件
    if (search) {
      where.OR = [
        { name: { contains: search, mode: 'insensitive' } },
        { code: { contains: search, mode: 'insensitive' } },
        { displayName: { contains: search, mode: 'insensitive' } },
        { nameEn: { contains: search, mode: 'insensitive' } },
        { nameZh: { contains: search, mode: 'insensitive' } },
      ];
    }

    if (primaryRegionId) {
      where.primaryRegionId = primaryRegionId;
    }

    if (status) {
      where.status = status;
    }

    if (typeof isActive === 'boolean') {
      where.isActive = isActive;
    }

    // 查询总数
    const total = await this.prisma.organization.count({ where });

    // 查询列表
    const items = await this.prisma.organization.findMany({
      where,
      include: {
        primaryRegion: true,
        organizationRegions: {
          include: {
            region: true,
          },
        },
        _count: {
          select: {
            departments: true,
            userDepartments: true,
          },
        },
      },
      orderBy: {
        [sortBy]: sortOrder,
      },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });

    return {
      items,
      total,
      page,
      pageSize,
      totalPages: Math.ceil(total / pageSize),
    };
  }

  /**
   * 获取组织详情
   */
  async findOne(id: string) {
    const organization = await this.prisma.organization.findFirst({
      where: {
        id,
        deletedAt: null,
      },
      include: {
        primaryRegion: true,
        organizationRegions: {
          include: {
            region: true,
          },
          orderBy: {
            isDefault: 'desc',
          },
        },
        _count: {
          select: {
            departments: true,
            userDepartments: true,
          },
        },
      },
    });

    if (!organization) {
      throw new NotFoundException(`Organization '${id}' not found`);
    }

    return organization;
  }

  /**
   * 更新组织
   * 
   * v2.1.1: 禁止修改组织代码（业务规则）
   */
  async update(id: string, updateDto: UpdateOrganizationDto) {
    // 确认组织存在
    const existingOrg = await this.findOne(id);

    // v2.1.1: 禁止修改组织代码（文档 line 2970）
    if (updateDto.code && updateDto.code !== existingOrg.code) {
      throw new BadRequestException('Cannot modify organization code');
    }

    // 如果修改了主要区域，验证其存在性
    if (updateDto.primaryRegionId) {
      const region = await this.prisma.region.findUnique({
        where: { id: updateDto.primaryRegionId },
      });
      if (!region) {
        throw new NotFoundException(`Primary region '${updateDto.primaryRegionId}' not found`);
      }
    }

    const organization = await this.prisma.organization.update({
      where: { id },
      data: {
        ...updateDto,
        code: undefined, // 确保不会更新 code
        establishedAt: updateDto.establishedAt ? new Date(updateDto.establishedAt) : undefined,
      },
      include: {
        primaryRegion: true,
        organizationRegions: {
          include: {
            region: true,
          },
        },
      },
    });

    return organization;
  }

  /**
   * 删除组织（软删除）
   * 
   * v2.1.1: 业务规则检查（文档 line 2994-2996）
   */
  async remove(id: string) {
    // 确认组织存在
    await this.findOne(id);

    // v2.1.1: 检查是否有关联的用户（通过 department 关联）
    const userCount = await this.prisma.userDepartment.count({
      where: {
        department: {
          organizationId: id,
        },
        leftAt: null, // 只检查仍在职的用户
        user: {
          deletedAt: null,
        },
      },
    });

    if (userCount > 0) {
      throw new BadRequestException(
        `Cannot delete organization '${id}': ${userCount} active users exist. Please transfer users first.`
      );
    }

    // v2.1.16: 使用事务删除组织和所有部门（包括根部门）
    await this.prisma.$transaction(async (tx) => {
      // 1. 软删除所有部门（包括根部门）
      await tx.department.updateMany({
        where: {
          organizationId: id,
          deletedAt: null,
        },
        data: {
          deletedAt: new Date(),
        },
      });

      // 2. 软删除组织
      await tx.organization.update({
        where: { id },
        data: {
          deletedAt: new Date(),
          isActive: false,
        },
      });
    });

    this.logger.log(`Deleted organization ${id} and all its departments`);

    return { message: 'Organization deleted successfully' };
  }

  /**
   * 添加运营区域
   */
  async addRegions(organizationId: string, dto: OrganizationRegionDto) {
    // 确认组织存在
    await this.findOne(organizationId);

    const { regionIds, primaryRegionId } = dto;

    // 验证所有区域存在
    const regions = await this.prisma.region.findMany({
      where: {
        id: { in: regionIds },
        deletedAt: null,
      },
    });

    if (regions.length !== regionIds.length) {
      const foundIds = regions.map(r => r.id);
      const missingIds = regionIds.filter(id => !foundIds.includes(id));
      throw new NotFoundException(`Regions not found: ${missingIds.join(', ')}`);
    }

    // 删除现有关联
    await this.prisma.organizationRegion.deleteMany({
      where: { organizationId },
    });

    // 创建新关联
    await this.prisma.organizationRegion.createMany({
      data: regionIds.map(regionId => ({
        organizationId,
        regionId,
        isDefault: regionId === primaryRegionId,
      })),
    });

    // 如果指定了主要区域，更新组织的 primaryRegionId
    if (primaryRegionId && regionIds.includes(primaryRegionId)) {
      await this.prisma.organization.update({
        where: { id: organizationId },
        data: { primaryRegionId },
      });
    }

    return this.findOne(organizationId);
  }

  /**
   * 从组织移除区域 (v2.1 新增)
   */
  async removeRegion(organizationId: string, regionId: string) {
    // 确认组织存在
    const organization = await this.findOne(organizationId);

    // 检查区域关联是否存在
    const orgRegion = await this.prisma.organizationRegion.findUnique({
      where: {
        organizationId_regionId: {
          organizationId,
          regionId,
        },
      },
    });

    if (!orgRegion) {
      throw new NotFoundException(
        `Region '${regionId}' is not associated with organization '${organizationId}'`
      );
    }

    // 不能移除主要区域
    if (organization.primaryRegionId === regionId) {
      throw new BadRequestException(
        'Cannot remove primary region. Please set another region as primary first.'
      );
    }

    // 删除关联
    await this.prisma.organizationRegion.delete({
      where: {
        organizationId_regionId: {
          organizationId,
          regionId,
        },
      },
    });

    return { message: 'Region removed successfully' };
  }

  /**
   * 获取组织统计
   */
  async getStats(id: string): Promise<OrganizationStatsDto> {
    // 确认组织存在
    await this.findOne(id);

    // 统计部门数
    const totalDepartments = await this.prisma.department.count({
      where: {
        organizationId: id,
        deletedAt: null,
      },
    });

    // 统计用户数（通过 user_departments 表）
    const userDepartments = await this.prisma.userDepartment.findMany({
      where: {
        organizationId: id,
        leftAt: null,
      },
      select: {
        userId: true,
        user: {
          select: {
            status: true,
          },
        },
      },
      distinct: ['userId'],
    });

    const totalUsers = userDepartments.length;
    const activeUsers = userDepartments.filter(ud => ud.user.status === 'ACTIVE').length;

    // 统计区域数
    const totalRegions = await this.prisma.organizationRegion.count({
      where: { organizationId: id },
    });

    return {
      totalDepartments,
      totalUsers,
      activeUsers,
      totalRegions,
    };
  }

  /**
   * 获取用户的组织列表
   */
  async getUserOrganizations(userId: string): Promise<UserOrganizationDto[]> {
    // 查询用户的所有部门归属
    const userDepartments = await this.prisma.userDepartment.findMany({
      where: {
        userId,
        leftAt: null,
      },
      include: {
        organization: true,
        department: true,
      },
    });

    // 按组织分组
    const orgMap = new Map<string, UserOrganizationDto>();

    for (const ud of userDepartments) {
      const orgId = ud.organizationId;
      
      if (!orgMap.has(orgId)) {
        orgMap.set(orgId, {
          organizationId: orgId,
          organizationCode: ud.organization.code,
          organizationName: ud.organization.name,
          departmentIds: [],
          isPrimary: ud.isPrimary,
        });
      }

      const orgData = orgMap.get(orgId)!;
      orgData.departmentIds.push(ud.departmentId);
      
      // 如果当前归属是主归属，更新标记
      if (ud.isPrimary) {
        orgData.isPrimary = true;
      }
    }

    return Array.from(orgMap.values());
  }
}

