import { Injectable } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { Model, Types } from 'mongoose'
import { AuditService, type AuditActor } from '../audit/audit.service.js'
import {
  PartnerBranding,
  PartnerBrandingDocument,
} from '../schemas/partner-branding.schema.js'
import type { PartnerBrandingDto } from './dto/partner-branding.dto.js'

@Injectable()
export class PartnerBrandingService {
  constructor(
    @InjectModel(PartnerBranding.name)
    private readonly model: Model<PartnerBrandingDocument>,
    private readonly audit: AuditService,
  ) {}

  // Return the partner's branding doc, or a default-shaped (unsaved) doc so the
  // portal always has a stable shape to render before anything is saved.
  async get(
    partnerId: string | Types.ObjectId,
  ): Promise<PartnerBrandingDocument | PartnerBranding> {
    const existing = await this.model.findOne({ partnerId }).exec()
    if (existing) return existing
    // No saved branding yet — return a default-shaped plain object (no persisted
    // _id) so the portal renders a stable shape without mistaking it for a
    // saved document.
    return {
      partnerId: new Types.ObjectId(String(partnerId)),
      identity: {},
      customerDefaults: [],
      emailTemplates: [],
    }
  }

  // Full replace (upsert) of the partner's branding. The page edits the whole
  // object and PUTs it back.
  async put(
    partnerId: string | Types.ObjectId,
    dto: PartnerBrandingDto,
    actor?: AuditActor,
  ): Promise<PartnerBrandingDocument> {
    const updated = await this.model
      .findOneAndUpdate(
        { partnerId },
        {
          $set: {
            identity: dto.identity ?? {},
            customerDefaults: dto.customerDefaults ?? [],
            emailTemplates: dto.emailTemplates ?? [],
          },
        },
        { new: true, upsert: true, runValidators: true, setDefaultsOnInsert: true },
      )
      .exec()

    void this.audit.record(
      {
        action: 'partner.branding_updated',
        resourceType: 'partner',
        resourceId: String(partnerId),
        metadata: {
          templates: dto.emailTemplates?.length ?? 0,
          defaults: dto.customerDefaults?.length ?? 0,
        },
      },
      actor,
    )
    return updated!
  }
}
