import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../common/prisma/prisma.service';
import { ServiceLogger } from '../../common/logging/service-logger';

@Injectable()
export class PublicDashboardService {
  private static readonly VISIT_COOLDOWN_MS = 60 * 60 * 1000;
  private readonly logger = new ServiceLogger(PublicDashboardService.name);

  constructor(private readonly prisma: PrismaService) {}

  async getDashboard(dashboardSlug: string) {
    const client = await this.prisma.client.findFirst({
      where: {
        dashboardSlug,
        isDeleted: false,
      },
      select: {
        companyName: true,
        contactName: true,
        website: true,
        primaryMetricType: true,
        keywords: {
          where: { isDeleted: false, status: 'active' },
          select: {
            id: true,
            keyword: true,
          },
        },
        reports: {
          where: { isDeleted: false },
          orderBy: { reportStartDate: 'desc' },
          select: {
            reportStartDate: true,
            reportEndDate: true,
            businessMetricValue: true,
            traffic: true,
            backlinks: true,
            keywordRanks: {
              select: {
                keywordId: true,
                position: true,
              },
            },
          },
        },
      },
    });

    if (!client) {
      this.logger.warn('public_dashboard.not_found');
      throw new NotFoundException('Client dashboard not found.');
    }

    return client;
  }

  async recordVisit(dashboardSlug: string) {
    const now = new Date();
    const cooldownStart = new Date(
      now.getTime() - PublicDashboardService.VISIT_COOLDOWN_MS,
    );

    // The cooldown condition is part of the update, so refreshes and concurrent
    // page loads cannot increment this client's count more than once per hour.
    const result = await this.prisma.client.updateMany({
      where: {
        dashboardSlug,
        isDeleted: false,
        OR: [
          { lastDashboardVisitedAt: null },
          { lastDashboardVisitedAt: { lte: cooldownStart } },
        ],
      },
      data: {
        dashboardVisitCount: { increment: 1 },
        lastDashboardVisitedAt: now,
      },
    });

    if (result.count > 0) {
      this.logger.log('public_dashboard.visit_counted');
      return { counted: true };
    }

    const client = await this.prisma.client.findFirst({
      where: { dashboardSlug, isDeleted: false },
      select: { id: true },
    });

    if (!client) {
      this.logger.warn('public_dashboard.visit_client_not_found');
      throw new NotFoundException('Client dashboard not found.');
    }

    return { counted: false };
  }
}
