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

interface CreateUserDto {
  username: string;
  password?: string;
  name: string;
  phone?: string;
  email?: string;
  roleIds?: string[];
  regionIds?: string[];
}

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

  async findAll(user: AuthUser, query: any = {}) {
    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 = {
      tenantId: user.tenantId ?? '__platform-users-hidden__',
      ...(query.keyword ? { OR: [{ username: { contains: query.keyword } }, { name: { contains: query.keyword } }] } : {}),
    };
    const select = {
      id: true,
      username: true,
      name: true,
      phone: true,
      email: true,
      status: true,
      createdAt: true,
      roles: { include: { role: true } },
      regionScopes: { include: { region: true } },
    };

    const [items, total] = await Promise.all([
      this.prisma.user.findMany({
        where,
        select,
        orderBy: { createdAt: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      this.prisma.user.count({ where }),
    ]);

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

  async create(user: AuthUser, dto: CreateUserDto) {
    if (!user.tenantId) {
      throw new ForbiddenException('平台超级管理员不能在用户管理中创建账号');
    }

    return this.prisma.user.create({
      data: {
        username: dto.username,
        passwordHash: await bcrypt.hash(dto.password ?? '123456', 10),
        name: dto.name,
        phone: dto.phone,
        email: dto.email,
        tenantId: user.tenantId,
        roles: { create: dto.roleIds?.map((roleId) => ({ roleId })) ?? [] },
        regionScopes: { create: dto.regionIds?.map((regionId) => ({ regionId })) ?? [] },
      },
    });
  }

  async update(user: AuthUser, id: string, dto: Partial<CreateUserDto> & { status?: 'ACTIVE' | 'DISABLED' }) {
    await this.ensureTenantUser(user, id);
    await this.prisma.userRole.deleteMany({ where: { userId: id } });
    await this.prisma.userRegionScope.deleteMany({ where: { userId: id } });

    return this.prisma.user.update({
      where: { id },
      data: {
        name: dto.name,
        phone: dto.phone,
        email: dto.email,
        status: dto.status,
        roles: { create: dto.roleIds?.map((roleId) => ({ roleId })) ?? [] },
        regionScopes: { create: dto.regionIds?.map((regionId) => ({ regionId })) ?? [] },
      },
    });
  }

  async remove(user: AuthUser, id: string) {
    await this.ensureTenantUser(user, id);
    return this.prisma.user.delete({ where: { id } });
  }

  private async ensureTenantUser(user: AuthUser, id: string) {
    if (!user.tenantId) {
      throw new ForbiddenException('平台超级管理员不能在用户管理中配置账号');
    }
    const target = await this.prisma.user.findFirst({ where: { id, tenantId: user.tenantId } });
    if (!target) {
      throw new NotFoundException('用户不存在或无权限访问');
    }
    return target;
  }
}
