import { AggregateRoot } from '@modules/shared';
import { ReportStatus } from '../enums/report-status.enum';
import { type ReportType } from '../enums/report-type.enum';

export interface ReportProps {
  userId: string;
  type: ReportType;
  title: string;
  params: Record<string, unknown>;
  content: Record<string, unknown> | null;
  pdfUrl: string | null;
  status: ReportStatus;
  errorMsg: string | null;
}

export class ReportEntity extends AggregateRoot<string> {
  private _userId: string;
  private _type: ReportType;
  private _title: string;
  private _params: Record<string, unknown>;
  private _content: Record<string, unknown> | null;
  private _pdfUrl: string | null;
  private _status: ReportStatus;
  private _errorMsg: string | null;

  constructor(id: string, props: ReportProps, createdAt?: Date, updatedAt?: Date) {
    super(id, createdAt, updatedAt);
    this._userId = props.userId;
    this._type = props.type;
    this._title = props.title;
    this._params = props.params;
    this._content = props.content;
    this._pdfUrl = props.pdfUrl;
    this._status = props.status;
    this._errorMsg = props.errorMsg;
  }

  get userId(): string { return this._userId; }
  get type(): ReportType { return this._type; }
  get title(): string { return this._title; }
  get params(): Record<string, unknown> { return this._params; }
  get content(): Record<string, unknown> | null { return this._content; }
  get pdfUrl(): string | null { return this._pdfUrl; }
  get status(): ReportStatus { return this._status; }
  get errorMsg(): string | null { return this._errorMsg; }

  static createNew(
    id: string,
    userId: string,
    type: ReportType,
    title: string,
    params: Record<string, unknown>,
  ): ReportEntity {
    return new ReportEntity(id, {
      userId,
      type,
      title,
      params,
      content: null,
      pdfUrl: null,
      status: ReportStatus.GENERATING,
      errorMsg: null,
    });
  }

  markReady(content: Record<string, unknown>, pdfUrl: string | null): void {
    this._content = content;
    this._pdfUrl = pdfUrl;
    this._status = ReportStatus.READY;
    this.updatedAt = new Date();
  }

  markFailed(errorMsg: string): void {
    this._status = ReportStatus.FAILED;
    this._errorMsg = errorMsg;
    this.updatedAt = new Date();
  }
}
