import { Injectable, NotFoundException } from '@nestjs/common';
import { TenantConnectionService } from '../../database/tenant-connection.service';
import { MemberPhysicalExam } from '../../database/tenant/entities/member-physical-exam.entity';

export interface CreatePhysicalExamDto {
  memberId: string; memberName: string; memberNameNe?: string;
  examDate?: string;
  rightEarCondition?: string; leftEarCondition?: string;
  rightEarPhotoUrl?: string; leftEarPhotoUrl?: string; earNotes?: string;
  rightEyeCondition?: string; leftEyeCondition?: string;
  rightEyePhotoUrl?: string; leftEyePhotoUrl?: string; eyeNotes?: string;
  bloodPressure?: string; bloodGroup?: string; heightCm?: number; weightKg?: number;
  examinerName?: string; officeId?: string; notes?: string;
}
export type UpdatePhysicalExamDto = Partial<CreatePhysicalExamDto>;

@Injectable()
export class PhysicalExamService {
  constructor(private tenantConn: TenantConnectionService) {}

  private async repo(sub: string) {
    const ds = await this.tenantConn.getTenantDataSource(sub);
    return ds.getRepository(MemberPhysicalExam);
  }

  async findAll(sub: string, opts: { memberId?: string; q?: string; page?: number; limit?: number }) {
    const r = await this.repo(sub);
    const { memberId, q, page = 1, limit = 20 } = opts;
    const qb = r.createQueryBuilder('e')
      .where('e.deletedAt IS NULL')
      .orderBy('e.createdAt', 'DESC')
      .skip((page - 1) * limit)
      .take(limit);
    if (memberId) qb.andWhere('e.memberId = :memberId', { memberId });
    if (q) qb.andWhere('(e.memberName LIKE :q OR e.memberNameNe LIKE :q)', { q: `%${q}%` });
    const [items, total] = await qb.getManyAndCount();
    return { items, total, page, limit };
  }

  async findOne(sub: string, id: string) {
    const r = await this.repo(sub);
    const e = await r.findOne({ where: { id } });
    if (!e) throw new NotFoundException('Physical exam record not found');
    return e;
  }

  async create(sub: string, dto: CreatePhysicalExamDto, userId?: string, userName?: string) {
    const r = await this.repo(sub);
    const exam = r.create({
      ...(dto as any),
      rightEarCondition: dto.rightEarCondition ?? 'normal',
      leftEarCondition: dto.leftEarCondition ?? 'normal',
      rightEyeCondition: dto.rightEyeCondition ?? 'normal',
      leftEyeCondition: dto.leftEyeCondition ?? 'normal',
    });
    return r.save(exam as unknown as MemberPhysicalExam);
  }

  async update(sub: string, id: string, dto: UpdatePhysicalExamDto) {
    const r = await this.repo(sub);
    const e = await this.findOne(sub, id);
    Object.assign(e, dto);
    return r.save(e);
  }

  async remove(sub: string, id: string) {
    const r = await this.repo(sub);
    await this.findOne(sub, id);
    await r.softDelete(id);
    return { id };
  }
}
