import { ForbiddenException, Injectable, NotFoundException } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { Model, Types } from 'mongoose'
import { AuditService, type AuditActor } from '../audit/audit.service.js'
import { Report, ReportDocument } from '../schemas/report.schema.js'
import type { CreateReportDto } from './dto/create-report.dto.js'

// Saved/custom reports CRUD, scoped to a partner. The live analytics are
// computed in UsersService.partnerReports — this only stores named configs.
@Injectable()
export class PartnerReportsService {
  constructor(
    @InjectModel(Report.name) private readonly model: Model<ReportDocument>,
    private readonly audit: AuditService,
  ) {}

  async list(partnerId: string | Types.ObjectId): Promise<ReportDocument[]> {
    return this.model.find({ partnerId }).sort({ createdAt: -1 }).exec()
  }

  async create(
    partnerId: string | Types.ObjectId,
    dto: CreateReportDto,
    actor?: AuditActor,
  ): Promise<ReportDocument> {
    const report = await this.model.create({
      partnerId,
      name: dto.name,
      kind: dto.kind ?? 'custom',
      description: dto.description,
      definition: dto.definition ?? {},
      createdByEmail: actor?.email,
    })
    void this.audit.record(
      {
        action: 'report.created',
        resourceType: 'partner',
        resourceId: String(report._id),
        resourceName: report.name,
        metadata: { kind: report.kind },
      },
      actor,
    )
    return report
  }

  async remove(
    id: string,
    partnerId: string | Types.ObjectId,
    actor?: AuditActor,
  ): Promise<{ removed: boolean }> {
    const report = await this.model.findById(id).exec()
    if (!report) throw new NotFoundException('Report not found')
    if (String(report.partnerId) !== String(partnerId)) {
      throw new ForbiddenException('Report is not in your portfolio')
    }
    await this.model.deleteOne({ _id: report._id }).exec()
    void this.audit.record(
      {
        action: 'report.deleted',
        resourceType: 'partner',
        resourceId: id,
        resourceName: report.name,
      },
      actor,
    )
    return { removed: true }
  }
}
