import {
  Injectable,
  ConflictException,
  UnauthorizedException,
  NotFoundException,
  BadRequestException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcrypt';
import { PublicRegisterDto, PublicLoginDto } from './dto/register.dto';
import { CreateChildDto, UpdateChildDto } from './dto/child.dto';
import { PublicRegisterActivityDto } from './dto/registration.dto';

// 公众租户编码（系统内置）
const PUBLIC_TENANT_CODE = 'public';

@Injectable()
export class PublicService {
  constructor(
    private prisma: PrismaService,
    private jwtService: JwtService,
  ) {}

  /**
   * 获取公众租户 ID
   */
  private async getPublicTenantId(): Promise<number> {
    const tenant = await this.prisma.tenant.findUnique({
      where: { code: PUBLIC_TENANT_CODE },
    });
    if (!tenant) {
      throw new BadRequestException('公众租户未初始化，请联系管理员');
    }
    return tenant.id;
  }

  /**
   * 获取公众用户角色 ID
   */
  private async getPublicRoleId(tenantId: number): Promise<number> {
    const role = await this.prisma.role.findFirst({
      where: { tenantId, code: 'public_user' },
    });
    if (!role) {
      throw new BadRequestException('公众用户角色未初始化，请联系管理员');
    }
    return role.id;
  }

  // ==================== 注册 & 登录 ====================

  /**
   * 公众用户注册
   */
  async register(dto: PublicRegisterDto) {
    const tenantId = await this.getPublicTenantId();

    // 检查用户名是否已存在（在公众租户内）
    const existingUser = await this.prisma.user.findFirst({
      where: { username: dto.username, tenantId },
    });
    if (existingUser) {
      throw new ConflictException('用户名已被注册');
    }

    // 检查手机号是否已被使用
    if (dto.phone) {
      const existingPhone = await this.prisma.user.findFirst({
        where: { phone: dto.phone },
      });
      if (existingPhone) {
        throw new ConflictException('该手机号已被注册');
      }
    }

    const hashedPassword = await bcrypt.hash(dto.password, 10);
    const roleId = await this.getPublicRoleId(tenantId);

    const user = await this.prisma.user.create({
      data: {
        tenantId,
        username: dto.username,
        password: hashedPassword,
        nickname: dto.nickname,
        phone: dto.phone || null,
        city: dto.city || null,
        userSource: 'self_registered',
        roles: {
          create: [{ roleId }],
        },
      },
      include: {
        roles: {
          include: {
            role: {
              include: {
                permissions: { include: { permission: true } },
              },
            },
          },
        },
      },
    });

    // 注册成功后自动登录，返回 token
    return this.generateLoginResponse(user, tenantId);
  }

  /**
   * 公众用户登录
   */
  async login(dto: PublicLoginDto) {
    const tenantId = await this.getPublicTenantId();

    const user = await this.prisma.user.findFirst({
      where: { username: dto.username, tenantId },
      include: {
        roles: {
          include: {
            role: {
              include: {
                permissions: { include: { permission: true } },
              },
            },
          },
        },
      },
    });

    if (!user) {
      throw new UnauthorizedException('用户名或密码错误');
    }

    const isPasswordValid = await bcrypt.compare(dto.password, user.password);
    if (!isPasswordValid) {
      throw new UnauthorizedException('用户名或密码错误');
    }

    if (user.status !== 'enabled') {
      throw new UnauthorizedException('账号已被禁用');
    }

    return this.generateLoginResponse(user, tenantId);
  }

  /**
   * 生成登录响应（token + 用户信息）
   */
  private async generateLoginResponse(user: any, tenantId: number) {
    const tenant = await this.prisma.tenant.findUnique({
      where: { id: tenantId },
    });

    // 如果是子女账号，查找家长关系
    let parentUserId: number | null = null;
    if (user.userType === 'child') {
      const parentRelation = await this.prisma.userParentChild.findFirst({
        where: { childUserId: user.id },
      });
      parentUserId = parentRelation?.parentUserId || null;
    }

    const payload = {
      username: user.username,
      sub: user.id,
      tenantId,
      userType: user.userType || 'adult',
      parentUserId,
    };

    const permissions = new Set<string>();
    user.roles?.forEach((ur: any) => {
      ur.role.permissions?.forEach((rp: any) => {
        permissions.add(rp.permission.code);
      });
    });

    return {
      token: this.jwtService.sign(payload),
      user: {
        id: user.id,
        username: user.username,
        nickname: user.nickname,
        phone: user.phone,
        city: user.city,
        avatar: user.avatar,
        tenantId,
        tenantCode: tenant?.code,
        userSource: user.userSource,
        userType: user.userType || 'adult',
        parentUserId,
        roles: user.roles?.map((ur: any) => ur.role.code) || [],
        permissions: Array.from(permissions),
      },
    };
  }

  /**
   * 获取公众用户信息
   */
  async getUserInfo(userId: number) {
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
      include: {
        roles: {
          include: {
            role: {
              include: {
                permissions: { include: { permission: true } },
              },
            },
          },
        },
        children: {
          where: { isDeleted: 0 },
          orderBy: { createTime: 'desc' },
        },
      },
    });

    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    const permissions = new Set<string>();
    user.roles?.forEach((ur: any) => {
      ur.role.permissions?.forEach((rp: any) => {
        permissions.add(rp.permission.code);
      });
    });

    return {
      id: user.id,
      username: user.username,
      nickname: user.nickname,
      phone: user.phone,
      city: user.city,
      avatar: user.avatar,
      birthday: user.birthday,
      gender: user.gender,
      userSource: user.userSource,
      roles: user.roles?.map((ur: any) => ur.role.code) || [],
      permissions: Array.from(permissions),
      children: user.children,
      childrenCount: user.children.length,
    };
  }

  /**
   * 更新公众用户个人信息
   */
  async updateProfile(
    userId: number,
    data: { nickname?: string; city?: string; avatar?: string; gender?: string },
  ) {
    return this.prisma.user.update({
      where: { id: userId },
      data,
      select: {
        id: true,
        username: true,
        nickname: true,
        phone: true,
        city: true,
        avatar: true,
        gender: true,
      },
    });
  }

  // ==================== 子女管理 ====================

  /**
   * 获取子女列表
   */
  async getChildren(parentId: number) {
    return this.prisma.child.findMany({
      where: { parentId, isDeleted: 0 },
      orderBy: { createTime: 'desc' },
    });
  }

  /**
   * 添加子女
   */
  async createChild(parentId: number, dto: CreateChildDto) {
    return this.prisma.child.create({
      data: {
        parentId,
        name: dto.name,
        gender: dto.gender || null,
        birthday: dto.birthday ? new Date(dto.birthday) : null,
        grade: dto.grade || null,
        city: dto.city || null,
        schoolName: dto.schoolName || null,
      },
    });
  }

  /**
   * 获取单个子女详情
   */
  async getChild(parentId: number, childId: number) {
    const child = await this.prisma.child.findFirst({
      where: { id: childId, parentId, isDeleted: 0 },
    });
    if (!child) {
      throw new NotFoundException('子女信息不存在');
    }
    return child;
  }

  /**
   * 更新子女信息
   */
  async updateChild(parentId: number, childId: number, dto: UpdateChildDto) {
    // 验证子女归属
    await this.getChild(parentId, childId);

    const data: any = {};
    if (dto.name !== undefined) data.name = dto.name;
    if (dto.gender !== undefined) data.gender = dto.gender;
    if (dto.birthday !== undefined)
      data.birthday = dto.birthday ? new Date(dto.birthday) : null;
    if (dto.grade !== undefined) data.grade = dto.grade;
    if (dto.city !== undefined) data.city = dto.city;
    if (dto.schoolName !== undefined) data.schoolName = dto.schoolName;

    return this.prisma.child.update({
      where: { id: childId },
      data,
    });
  }

  /**
   * 删除子女（软删除）
   */
  async deleteChild(parentId: number, childId: number) {
    // 验证子女归属
    await this.getChild(parentId, childId);

    // 检查是否有关联的报名记录
    const registrations = await this.prisma.contestRegistration.count({
      where: { childId },
    });

    await this.prisma.child.update({
      where: { id: childId },
      data: { isDeleted: 1 },
    });

    return {
      message: '删除成功',
      hasRegistrations: registrations > 0,
      registrationCount: registrations,
    };
  }

  // ==================== 活动相关 ====================

  /**
   * 获取公众可见的活动列表
   * 支持 public（全量）和 targeted（按城市/年龄定向）两种可见性
   */
  async getPublicActivities(
    query: {
      page?: number;
      pageSize?: number;
      keyword?: string;
      contestType?: string;
    },
    userId?: number,
  ) {
    const page = query.page || 1;
    const pageSize = query.pageSize || 12;
    const skip = (page - 1) * pageSize;

    // 基础条件：已发布 + 有效
    const where: any = {
      visibility: { in: ['public', 'targeted'] },
      contestState: 'published',
      validState: 1,
    };

    if (query.keyword) {
      where.contestName = { contains: query.keyword };
    }

    if (query.contestType) {
      where.contestType = query.contestType;
    }

    const selectFields = {
      id: true,
      contestName: true,
      contestType: true,
      contestState: true,
      status: true,
      startTime: true,
      endTime: true,
      coverUrl: true,
      posterUrl: true,
      registerStartTime: true,
      registerEndTime: true,
      submitStartTime: true,
      submitEndTime: true,
      organizers: true,
      visibility: true,
      targetCities: true,
      ageMin: true,
      ageMax: true,
    };

    const [allList, allTotal] = await Promise.all([
      this.prisma.contest.findMany({
        where,
        orderBy: { createTime: 'desc' },
        select: selectFields,
      }),
      this.prisma.contest.count({ where }),
    ]);

    // 获取用户画像用于 targeted 过滤
    let userCity: string | null = null;
    let childCities: string[] = [];
    if (userId) {
      const user = await this.prisma.user.findUnique({
        where: { id: userId },
        select: { city: true },
      });
      userCity = user?.city || null;

      const children = await this.prisma.child.findMany({
        where: { parentId: userId, isDeleted: 0 },
        select: { city: true },
      });
      childCities = children.map((c) => c.city).filter(Boolean) as string[];
    }

    // 过滤 targeted 活动
    const filteredList = allList.filter((contest) => {
      if (contest.visibility === 'public') return true;

      // targeted: 检查城市匹配
      if (contest.targetCities && Array.isArray(contest.targetCities) && (contest.targetCities as string[]).length > 0) {
        const targets = contest.targetCities as string[];
        const allUserCities = [userCity, ...childCities].filter(Boolean) as string[];
        if (allUserCities.length === 0) return false; // 未登录或无城市信息，不展示
        const match = allUserCities.some((c) => targets.some((t) => c.includes(t) || t.includes(c)));
        if (!match) return false;
      }

      return true;
    });

    const total = filteredList.length;
    const list = filteredList.slice(skip, skip + pageSize);

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

  /**
   * 获取活动详情（支持 public + targeted）
   */
  async getActivityDetail(id: number) {
    const contest = await this.prisma.contest.findFirst({
      where: {
        id,
        visibility: { in: ['public', 'targeted'] },
        contestState: 'published',
        validState: 1,
      },
      include: {
        attachments: {
          where: { validState: 1 },
          select: {
            id: true,
            fileName: true,
            fileUrl: true,
            size: true,
            fileType: true,
          },
        },
        notices: {
          where: { validState: 1 },
          orderBy: { createTime: 'desc' },
          select: {
            id: true,
            title: true,
            content: true,
            publishTime: true,
            createTime: true,
          },
        },
      },
    });

    if (!contest) {
      throw new NotFoundException('活动不存在或未公开');
    }

    return contest;
  }

  // ==================== 公众用户管理（超管端） ====================

  /**
   * 获取公众用户列表（自注册用户）
   */
  async getPublicUsers(query: {
    page?: number;
    pageSize?: number;
    keyword?: string;
  }) {
    const page = query.page || 1;
    const pageSize = query.pageSize || 10;
    const skip = (page - 1) * pageSize;

    const where: any = {
      userSource: 'self_registered',
    };

    if (query.keyword) {
      where.OR = [
        { username: { contains: query.keyword } },
        { nickname: { contains: query.keyword } },
        { phone: { contains: query.keyword } },
        { city: { contains: query.keyword } },
      ];
    }

    const [list, total] = await Promise.all([
      this.prisma.user.findMany({
        where,
        skip,
        take: pageSize,
        orderBy: { createTime: 'desc' },
        select: {
          id: true,
          username: true,
          nickname: true,
          phone: true,
          city: true,
          gender: true,
          avatar: true,
          status: true,
          createTime: true,
          _count: {
            select: {
              children: { where: { isDeleted: 0 } },
              contestRegistrations: true,
            },
          },
        },
      }),
      this.prisma.user.count({ where }),
    ]);

    return {
      list: list.map((u) => ({
        ...u,
        childrenCount: u._count.children,
        registrationCount: u._count.contestRegistrations,
        _count: undefined,
      })),
      total,
      page,
      pageSize,
    };
  }

  /**
   * 获取公众用户详情（含子女和报名记录）
   */
  async getPublicUserDetail(userId: number) {
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
      include: {
        children: {
          where: { isDeleted: 0 },
          orderBy: { createTime: 'desc' },
        },
        contestRegistrations: {
          orderBy: { registrationTime: 'desc' },
          take: 20,
          include: {
            contest: {
              select: { id: true, contestName: true, contestType: true },
            },
            child: {
              select: { id: true, name: true },
            },
          },
        },
      },
    });

    if (!user || user.userSource !== 'self_registered') {
      throw new NotFoundException('公众用户不存在');
    }

    const { password, ...result } = user;
    return result;
  }

  // ==================== 作品提交 ====================

  /**
   * 获取公众用户在某活动中的报名记录（用于作品提交）
   */
  async getMyRegistration(userId: number, contestId: number) {
    const registration = await this.prisma.contestRegistration.findFirst({
      where: {
        userId,
        contestId,
        registrationState: 'passed',
      },
      include: {
        contest: {
          select: {
            id: true,
            contestName: true,
            submitStartTime: true,
            submitEndTime: true,
            submitRule: true,
          },
        },
        child: {
          select: { id: true, name: true },
        },
      },
    });
    return registration;
  }

  /**
   * 公众用户提交作品
   */
  async submitWork(
    userId: number,
    data: {
      registrationId: number;
      title: string;
      description?: string;
      files?: string[];
      previewUrl?: string;
      attachments?: { fileName: string; fileUrl: string; fileType?: string; size?: string }[];
    },
  ) {
    const tenantId = await this.getPublicTenantId();

    // 验证报名记录
    const registration = await this.prisma.contestRegistration.findUnique({
      where: { id: data.registrationId },
      include: { contest: true },
    });

    if (!registration || registration.userId !== userId) {
      throw new NotFoundException('报名记录不存在');
    }

    if (registration.registrationState !== 'passed') {
      throw new BadRequestException('报名未通过审核，无法提交作品');
    }

    // 检查提交时间
    const now = new Date();
    if (now < registration.contest.submitStartTime || now > registration.contest.submitEndTime) {
      throw new BadRequestException('当前不在作品提交时间范围内');
    }

    // 检查提交规则
    if (registration.contest.submitRule === 'once') {
      const existing = await this.prisma.contestWork.findFirst({
        where: { registrationId: data.registrationId, validState: 1 },
      });
      if (existing) {
        throw new ConflictException('该活动只允许提交一次作品');
      }
    }

    // 生成作品编号
    const workCount = await this.prisma.contestWork.count({
      where: { contestId: registration.contestId },
    });
    const workNo = `W${String(workCount + 1).padStart(4, '0')}`;

    // 查找用户信息
    const user = await this.prisma.user.findUnique({ where: { id: userId } });

    // 创建作品
    const work = await this.prisma.contestWork.create({
      data: {
        tenantId,
        contestId: registration.contestId,
        registrationId: data.registrationId,
        workNo,
        title: data.title,
        description: data.description || null,
        files: data.files || [],
        previewUrl: data.previewUrl || null,
        version: 1,
        isLatest: true,
        status: 'submitted',
        submitTime: now,
        submitterUserId: userId,
        submitterAccountNo: user?.username || '',
        submitSource: 'public',
        creator: userId,
      },
    });

    // 创建附件记录
    if (data.attachments?.length) {
      await this.prisma.contestWorkAttachment.createMany({
        data: data.attachments.map((att) => ({
          tenantId,
          contestId: registration.contestId,
          workId: work.id,
          fileName: att.fileName,
          fileUrl: att.fileUrl,
          fileType: att.fileType || null,
          size: att.size || '0',
          creator: userId,
        })),
      });
    }

    return work;
  }

  // ==================== 报名 ====================

  /**
   * 公众用户报名活动
   */
  async registerActivity(userId: number, dto: PublicRegisterActivityDto) {
    const tenantId = await this.getPublicTenantId();

    // 验证活动存在且公开
    const contest = await this.prisma.contest.findFirst({
      where: {
        id: dto.contestId,
        visibility: { in: ['public', 'targeted'] },
        contestState: 'published',
        validState: 1,
      },
    });

    if (!contest) {
      throw new NotFoundException('活动不存在或未公开');
    }

    // 验证报名时间
    const now = new Date();
    if (now < contest.registerStartTime || now > contest.registerEndTime) {
      throw new BadRequestException('当前不在报名时间范围内');
    }

    // 获取用户信息
    const user = await this.prisma.user.findUnique({ where: { id: userId } });
    if (!user) throw new NotFoundException('用户不存在');

    // 年龄校验（如果活动设置了年龄限制）
    if (contest.ageMin || contest.ageMax) {
      // 确定参与者的生日
      let participantBirthday: Date | null = null;
      if (dto.participantType === 'child' && dto.childId) {
        const childInfo = await this.prisma.child.findFirst({
          where: { id: dto.childId, parentId: userId, isDeleted: 0 },
        });
        participantBirthday = childInfo?.birthday || null;
      } else {
        participantBirthday = user.birthday || null;
      }

      if (participantBirthday) {
        const age = Math.floor(
          (now.getTime() - participantBirthday.getTime()) / (365.25 * 24 * 60 * 60 * 1000),
        );
        if (contest.ageMin && age < contest.ageMin) {
          throw new BadRequestException(`参与者年龄不符合要求（最低 ${contest.ageMin} 岁）`);
        }
        if (contest.ageMax && age > contest.ageMax) {
          throw new BadRequestException(`参与者年龄不符合要求（最高 ${contest.ageMax} 岁）`);
        }
      }
    }

    // 如果是代子女报名，验证子女归属
    let child = null;
    if (dto.participantType === 'child') {
      if (!dto.childId) {
        throw new BadRequestException('代子女报名时必须选择子女');
      }
      child = await this.prisma.child.findFirst({
        where: { id: dto.childId, parentId: userId, isDeleted: 0 },
      });
      if (!child) {
        throw new NotFoundException('子女信息不存在');
      }

      // 检查该子女是否已报名此活动
      const existingChildReg = await this.prisma.contestRegistration.findFirst({
        where: {
          contestId: dto.contestId,
          childId: dto.childId,
          registrationState: { not: 'withdrawn' },
        },
      });
      if (existingChildReg) {
        throw new ConflictException('该子女已报名此活动');
      }
    } else {
      // 检查用户自己是否已报名此活动
      const existingSelfReg = await this.prisma.contestRegistration.findFirst({
        where: {
          contestId: dto.contestId,
          userId,
          participantType: 'self',
          registrationState: { not: 'withdrawn' },
        },
      });
      if (existingSelfReg) {
        throw new ConflictException('您已报名此活动');
      }
    }

    // 创建报名记录
    const accountName =
      dto.participantType === 'child' ? child.name : user.nickname;

    const registration = await this.prisma.contestRegistration.create({
      data: {
        contestId: dto.contestId,
        tenantId,
        registrationType: 'individual',
        userId,
        accountNo: user.username,
        accountName,
        participantType: dto.participantType,
        childId: dto.childId || null,
        registrant: userId,
        registrationState: contest.requireAudit ? 'pending' : 'passed',
        registrationTime: now,
      },
      include: {
        contest: {
          select: { contestName: true },
        },
        child: true,
      },
    });

    return registration;
  }

  // ==================== 我的报名 ====================

  /**
   * 获取我的报名列表
   */
  async getMyRegistrations(
    userId: number,
    query: { page?: number; pageSize?: number },
  ) {
    const page = query.page || 1;
    const pageSize = query.pageSize || 10;
    const skip = (page - 1) * pageSize;

    const where = {
      userId,
      registrationState: { not: 'withdrawn' as const },
    };

    const [list, total] = await Promise.all([
      this.prisma.contestRegistration.findMany({
        where,
        skip,
        take: pageSize,
        orderBy: { registrationTime: 'desc' },
        include: {
          contest: {
            select: {
              id: true,
              contestName: true,
              contestType: true,
              coverUrl: true,
              startTime: true,
              endTime: true,
              status: true,
              submitStartTime: true,
              submitEndTime: true,
              resultState: true,
            },
          },
          child: {
            select: {
              id: true,
              name: true,
              grade: true,
            },
          },
        },
      }),
      this.prisma.contestRegistration.count({ where }),
    ]);

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

  // ==================== 我的作品 ====================

  /**
   * 获取我的作品列表
   */
  async getMyWorks(
    userId: number,
    query: { page?: number; pageSize?: number },
  ) {
    const page = query.page || 1;
    const pageSize = query.pageSize || 10;
    const skip = (page - 1) * pageSize;

    // 查询该用户提交的所有作品（包括代子女提交的）
    const where = {
      registration: { userId },
      validState: 1,
    };

    const [list, total] = await Promise.all([
      this.prisma.contestWork.findMany({
        where,
        skip,
        take: pageSize,
        orderBy: { createTime: 'desc' },
        include: {
          contest: {
            select: {
              id: true,
              contestName: true,
              coverUrl: true,
            },
          },
          registration: {
            select: {
              participantType: true,
              child: {
                select: { id: true, name: true },
              },
            },
          },
          attachments: {
            select: {
              id: true,
              fileName: true,
              fileUrl: true,
              fileType: true,
            },
          },
        },
      }),
      this.prisma.contestWork.count({ where }),
    ]);

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

  // ==================== 子女账号管理 ====================

  /**
   * 家长为子女创建独立账号
   */
  async createChildAccount(parentUserId: number, dto: {
    username: string;
    password: string;
    nickname: string;
    gender?: string;
    birthday?: string;
    city?: string;
    avatar?: string;
    relationship?: string;
  }) {
    const tenantId = await this.getPublicTenantId();

    // 验证家长身份
    const parent = await this.prisma.user.findUnique({ where: { id: parentUserId } });
    if (!parent || parent.userType !== 'adult') {
      throw new BadRequestException('仅家长账号可创建子女账号');
    }

    // 检查用户名是否已存在
    const existing = await this.prisma.user.findFirst({
      where: { username: dto.username, tenantId },
    });
    if (existing) {
      throw new ConflictException('用户名已被注册');
    }

    const hashedPassword = await bcrypt.hash(dto.password, 10);
    const roleId = await this.getPublicRoleId(tenantId);

    // 事务：创建子女 User + 创建家长-子女关联
    const result = await this.prisma.$transaction(async (tx) => {
      const childUser = await tx.user.create({
        data: {
          tenantId,
          username: dto.username,
          password: hashedPassword,
          nickname: dto.nickname,
          gender: dto.gender || null,
          birthday: dto.birthday ? new Date(dto.birthday) : null,
          city: dto.city || null,
          avatar: dto.avatar || null,
          userSource: 'child_migrated',
          userType: 'child',
          roles: { create: [{ roleId }] },
        },
      });

      await tx.userParentChild.create({
        data: {
          parentUserId,
          childUserId: childUser.id,
          relationship: dto.relationship || null,
          controlMode: 'open',
        },
      });

      return childUser;
    });

    return {
      id: result.id,
      username: result.username,
      nickname: result.nickname,
      avatar: result.avatar,
      userType: result.userType,
    };
  }

  /**
   * 获取家长创建的子女账号列表
   */
  async getChildAccounts(parentUserId: number) {
    const relations = await this.prisma.userParentChild.findMany({
      where: { parentUserId },
      include: {
        child: {
          select: {
            id: true,
            username: true,
            nickname: true,
            avatar: true,
            gender: true,
            birthday: true,
            city: true,
            status: true,
            userType: true,
            createTime: true,
          },
        },
      },
    });

    return relations.map((r) => ({
      ...r.child,
      relationship: r.relationship,
      controlMode: r.controlMode,
    }));
  }

  /**
   * 家长切换到子女身份（签发子女 JWT）
   */
  async switchToChild(parentUserId: number, childUserId: number) {
    // 验证家长-子女关系
    const relation = await this.prisma.userParentChild.findFirst({
      where: { parentUserId, childUserId },
    });
    if (!relation) {
      throw new BadRequestException('该子女不属于当前家长');
    }

    // 获取子女用户信息
    const childUser = await this.prisma.user.findUnique({
      where: { id: childUserId },
      include: {
        roles: {
          include: {
            role: {
              include: {
                permissions: { include: { permission: true } },
              },
            },
          },
        },
      },
    });

    if (!childUser || childUser.status !== 'enabled') {
      throw new BadRequestException('子女账号不存在或已被禁用');
    }

    const tenantId = childUser.tenantId;
    return this.generateLoginResponse(childUser, tenantId);
  }

  /**
   * 家长更新子女账号信息
   */
  async updateChildAccount(parentUserId: number, childUserId: number, dto: {
    nickname?: string;
    password?: string;
    gender?: string;
    birthday?: string;
    city?: string;
    avatar?: string;
    controlMode?: string;
  }) {
    // 验证家长-子女关系
    const relation = await this.prisma.userParentChild.findFirst({
      where: { parentUserId, childUserId },
    });
    if (!relation) {
      throw new BadRequestException('该子女不属于当前家长');
    }

    const updateData: any = {};
    if (dto.nickname !== undefined) updateData.nickname = dto.nickname;
    if (dto.gender !== undefined) updateData.gender = dto.gender;
    if (dto.birthday !== undefined) updateData.birthday = dto.birthday ? new Date(dto.birthday) : null;
    if (dto.city !== undefined) updateData.city = dto.city;
    if (dto.avatar !== undefined) updateData.avatar = dto.avatar;
    if (dto.password) {
      updateData.password = await bcrypt.hash(dto.password, 10);
    }

    // 更新用户信息
    if (Object.keys(updateData).length > 0) {
      await this.prisma.user.update({
        where: { id: childUserId },
        data: updateData,
      });
    }

    // 更新管控模式
    if (dto.controlMode) {
      await this.prisma.userParentChild.updateMany({
        where: { parentUserId, childUserId },
        data: { controlMode: dto.controlMode },
      });
    }

    return { success: true };
  }

  /**
   * 子女查看自己的家长信息
   */
  async getParentInfo(childUserId: number) {
    const relation = await this.prisma.userParentChild.findFirst({
      where: { childUserId },
      include: {
        parent: {
          select: {
            id: true,
            nickname: true,
            avatar: true,
          },
        },
      },
    });

    return relation
      ? { parentId: relation.parentUserId, nickname: relation.parent.nickname, avatar: relation.parent.avatar, relationship: relation.relationship }
      : null;
  }
}
