import { PrismaClient, Organization } from '@prisma/client';

import { getPrismaClient } from '../config/database.config';
import { BaseRepository } from '../modules/common/repository';

/**
 * EN: Organization repository for database operations
 * VI: Repository tổ chức cho các thao tác database
 */
export class OrganizationRepository extends BaseRepository<Organization, any, any> {
  constructor(prisma?: PrismaClient) {
    super(prisma || getPrismaClient(), 'organization');
  }

  /**
   * EN: Find organization by domain
   * VI: Tìm tổ chức theo domain
   */
  async findByDomain(domain: string): Promise<Organization | null> {
    return this.prisma.organization.findUnique({
      where: { domain },
      include: {
        parent: true,
        children: true,
        users: true,
        groups: true,
      },
    });
  }

  /**
   * EN: Find child organizations
   * VI: Tìm các tổ chức con
   */
  async findChildren(parentId: string): Promise<Organization[]> {
    return this.prisma.organization.findMany({
      where: { parentId },
      include: {
        parent: true,
        children: true,
      },
    });
  }

  /**
   * EN: Find organizations with hierarchy
   * VI: Tìm tổ chức với hierarchy
   */
  async findWithHierarchy(id: string): Promise<Organization | null> {
    return this.prisma.organization.findUnique({
      where: { id },
      include: {
        parent: {
          include: {
            parent: true, // Include grandparent
          },
        },
        children: {
          include: {
            children: true, // Include grandchildren
          },
        },
        users: {
          take: 10, // Limit users for performance
        },
        groups: {
          take: 10, // Limit groups for performance
        },
      },
    });
  }

  /**
   * EN: Get organization users count
   * VI: Lấy số lượng users của tổ chức
   */
  async getUserCount(organizationId: string): Promise<number> {
    return this.prisma.user.count({
      where: { organizationId },
    });
  }

  /**
   * EN: Get organization groups count
   * VI: Lấy số lượng groups của tổ chức
   */
  async getGroupCount(organizationId: string): Promise<number> {
    return this.prisma.group.count({
      where: { organizationId },
    });
  }
}
