import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';

export interface PermissionGroup {
  resource: string;
  resourceName: string;
  module?: string;
  permissions: any[];
}

@Injectable()
export class PermissionsService {
  constructor(private prisma: PrismaService) {}

  /**
   * Get all permissions
   */
  async findAll(module?: string) {
    const where = module ? { module } : {};

    return this.prisma.permission.findMany({
      where,
      orderBy: [{ resource: 'asc' }, { action: 'asc' }],
    });
  }

  /**
   * Get grouped permissions
   */
  async findGrouped(): Promise<PermissionGroup[]> {
    const permissions = await this.prisma.permission.findMany({
      orderBy: [{ resource: 'asc' }, { action: 'asc' }],
    });

    // Group by resource
    const grouped = permissions.reduce((acc, permission) => {
      const existing = acc.find((g) => g.resource === permission.resource);
      if (existing) {
        existing.permissions.push(permission);
      } else {
        acc.push({
          resource: permission.resource,
          resourceName: this.getResourceDisplayName(permission.resource),
          module: permission.module || undefined,
          permissions: [permission],
        });
      }
      return acc;
    }, [] as PermissionGroup[]);

    return grouped;
  }

  /**
   * Search permissions
   */
  async search(query: string) {
    return this.prisma.permission.findMany({
      where: {
        OR: [
          { resource: { contains: query, mode: 'insensitive' } },
          { action: { contains: query, mode: 'insensitive' } },
          { description: { contains: query, mode: 'insensitive' } },
          { module: { contains: query, mode: 'insensitive' } },
        ],
      },
      orderBy: [{ resource: 'asc' }, { action: 'asc' }],
    });
  }

  /**
   * Get permission by ID
   */
  async findOne(id: string) {
    const permission = await this.prisma.permission.findUnique({
      where: { id },
      include: {
        roles: {
          include: {
            role: {
              select: {
                id: true,
                name: true,
                code: true,
              },
            },
          },
        },
      },
    });

    if (!permission) {
      throw new NotFoundException(`Permission with ID ${id} not found`);
    }

    return {
      ...permission,
      roles: permission.roles.map((rp) => rp.role),
    };
  }

  /**
   * Get display name for resource
   */
  private getResourceDisplayName(resource: string): string {
    const resourceNames: Record<string, string> = {
      user: '用户管理',
      role: '角色管理',
      department: '部门管理',
      position: '职位管理',
      organization: '组织同步',
      part: '备件管理',
      approval: '审批流程',
      audit: '审计日志',
      notification: '通知管理',
      workflow: '流程管理',
      automation: '自动化',
    };
    return resourceNames[resource] || resource;
  }
}
