<?php

declare(strict_types=1);

namespace SeoScope\Services;

use PDO;
use SeoScope\Repositories\GscDailyPropertyAggRepository;

final class GscAggregationService
{
    public function __construct(
        private PDO $pdo,
        private GscDailyPropertyAggRepository $aggRepo,
        private string $tablePrefix
    ) {}

    /**
     * Preferred source for dashboard KPI: Search Analytics with dimension `date` (parity with GSC), not a sum of truncated query rows.
     *
     * @param array{keys:list<string>,clicks:float|int,impressions:float|int,ctr:float|int,position:float|int} $apiRow
     */
    public function upsertDailyPropertyAggFromDateApiRow(
        int $propertyId,
        string $siteUrl,
        string $date,
        array $apiRow
    ): void {
        if ($propertyId < 1 || $siteUrl === '' || $date === '') {
            return;
        }
        $clicks = (int) round((float) ($apiRow['clicks'] ?? 0));
        $impr = (int) round((float) ($apiRow['impressions'] ?? 0));
        $ctr = (float) ($apiRow['ctr'] ?? 0);
        $position = (float) ($apiRow['position'] ?? 0);
        if ($impr > 0 && $ctr === 0.0 && $clicks > 0) {
            $ctr = $clicks / $impr;
        }
        $this->aggRepo->upsertOne($propertyId, $siteUrl, $date, $clicks, $impr, $ctr, $position);
    }

    /**
     * @deprecated Sums gsc_daily_query, which is row-cap limited; do not use for production KPI. Kept for diagnostics.
     */
    public function rebuildDailyPropertyAggForDate(int $propertyId, string $siteUrl, string $date): void
    {
        $propertyId = (int) $propertyId;
        if ($propertyId < 1 || $siteUrl === '' || $date === '') {
            return;
        }

        $tq = '`' . str_replace('`', '``', $this->tablePrefix . 'gsc_daily_query') . '`';
        $stmt = $this->pdo->prepare(
            "SELECT
                COALESCE(SUM(clicks), 0) AS clicks,
                COALESCE(SUM(impressions), 0) AS impressions,
                COALESCE(SUM(position * impressions), 0) AS pos_weighted
             FROM {$tq}
             WHERE property_id = ? AND date = ?"
        );
        $stmt->execute([$propertyId, $date]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];

        $clicks = (int) ($row['clicks'] ?? 0);
        $impr = (int) ($row['impressions'] ?? 0);
        $posWeighted = (float) ($row['pos_weighted'] ?? 0);

        $ctr = $impr > 0 ? ($clicks / $impr) : 0.0;
        $position = $impr > 0 ? ($posWeighted / $impr) : 0.0;

        $this->aggRepo->upsertOne($propertyId, $siteUrl, $date, $clicks, $impr, $ctr, $position);
    }
}

