/**
 * Use Case: RecordPageViewUseCase
 *
 * Records a page view event when a visitor accesses an entity page.
 */
 
import type { AsyncUseCase } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
import { PageView } from '../../domain/entities/PageView';
import type { EntityType, VisitorType } from '../../domain/types/PageView';
import type { IPageViewRepository } from '../repositories/IPageViewRepository';

export interface RecordPageViewInput {
  entityType: EntityType;
  entityId: string;
  visitorId?: string;
  visitorType: VisitorType;
  sessionId: string;
  referrer?: string;
  userAgent?: string;
  country?: string;
}

export interface RecordPageViewOutput {
  pageViewId: string;
}

export class RecordPageViewUseCase
  implements AsyncUseCase<RecordPageViewInput, RecordPageViewOutput> {
  constructor(
    private readonly pageViewRepository: IPageViewRepository,
    private readonly logger: Logger,
  ) {}

  async execute(input: RecordPageViewInput): Promise<RecordPageViewOutput> {
    this.logger.debug('Executing RecordPageViewUseCase', { input });
    try {
      const pageViewId = `pv-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;

      const baseProps: Omit<Parameters<typeof PageView.create>[0], 'timestamp'> = {
        id: pageViewId,
        entityType: input.entityType,
        entityId: input.entityId,
        visitorType: input.visitorType,
        sessionId: input.sessionId,
      };

      const pageView = PageView.create({
        ...baseProps,
        ...(input.visitorId !== undefined ? { visitorId: input.visitorId } : {}),
        ...(input.referrer !== undefined ? { referrer: input.referrer } : {}),
        ...(input.userAgent !== undefined ? { userAgent: input.userAgent } : {}),
        ...(input.country !== undefined ? { country: input.country } : {}),
      });

      await this.pageViewRepository.save(pageView);
      this.logger.info('Page view recorded successfully', { pageViewId, input });
      return { pageViewId };
    } catch (error) {
      const err = error instanceof Error ? error : new Error(String(error));
      this.logger.error('Error recording page view', err, { input });
      throw error;
    }
  }
}
