import { BadRequestException, ForbiddenException, Injectable, NotFoundException } from '@nestjs/common';
import * as bcrypt from 'bcryptjs';
import { AuthUser } from '../../common/current-user.decorator';
import { PrismaService } from '../prisma/prisma.service';

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

  async findAll(user: AuthUser, query: any = {}) {
    this.ensurePlatformAdmin(user);
    const page = Math.max(Number(query.page ?? 1), 1);
    const pageSize = Math.min(Math.max(Number(query.pageSize ?? query.limit ?? 20), 1), 100);
    const where = query.keyword
      ? { OR: [{ code: { contains: query.keyword } }, { name: { contains: query.keyword } }] }
      : undefined;

    const [items, total] = await Promise.all([
      this.prisma.tenant.findMany({
        where,
        orderBy: { createdAt: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
        include: { users: { where: { username: query.adminUsername ?? 'admin' }, select: { id: true, username: true, name: true } } },
      }),
      this.prisma.tenant.count({ where }),
    ]);

    return { items, total, page, pageSize };
  }

  async create(user: AuthUser, dto: any) {
    this.ensurePlatformAdmin(user);
    const adminUsername = dto.adminUsername || 'admin';
    const adminPassword = dto.adminPassword || 'admin123456';
    const adminName = dto.adminName || '租户管理员';
    const region = await this.prisma.region.findFirst({ where: { level: 0 }, orderBy: { code: 'asc' } });
    if (!region) {
      throw new BadRequestException('请先初始化全国区域数据');
    }

    return this.prisma.$transaction(async (tx) => {
      const tenant = await tx.tenant.create({
        data: {
          name: dto.name,
          code: dto.code,
          enabled: dto.enabled ?? true,
        },
      });

      const permissions = await tx.permission.findMany({ where: { code: { not: 'tenants:manage' } } });
      const role = await tx.role.create({
        data: {
          name: '租户管理员',
          code: 'tenant_admin',
          description: '租户初始化管理员角色',
          tenantId: tenant.id,
          permissions: { create: permissions.map((permission) => ({ permissionId: permission.id })) },
          regionScopes: { create: [{ regionId: region.id }] },
        },
      });

      await tx.user.create({
        data: {
          username: adminUsername,
          passwordHash: await bcrypt.hash(adminPassword, 10),
          name: adminName,
          tenantId: tenant.id,
          roles: { create: [{ roleId: role.id }] },
          regionScopes: { create: [{ regionId: region.id }] },
        },
      });

      return { tenant, admin: { username: adminUsername, name: adminName } };
    });
  }

  async update(user: AuthUser, id: string, dto: any) {
    this.ensurePlatformAdmin(user);
    const tenant = await this.prisma.tenant.findUnique({ where: { id } });
    if (!tenant) {
      throw new NotFoundException('租户不存在');
    }

    return this.prisma.tenant.update({
      where: { id },
      data: {
        name: dto.name,
        enabled: dto.enabled,
      },
    });
  }

  private ensurePlatformAdmin(user: AuthUser) {
    if (user.tenantId || !user.permissions.includes('tenants:manage')) {
      throw new ForbiddenException('仅平台超级管理员可访问租户管理');
    }
  }
}
