<?php

declare(strict_types=1);

namespace SeoScope\Services;

use PDO;

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

    private function t(string $name): string
    {
        return '`' . str_replace('`', '``', $this->tablePrefix . $name) . '`';
    }

    /**
     * Delete all imported data for selected properties (scoped to user).
     *
     * @param list<int> $propertyIds
     */
    public function resetProperties(int $userId, array $propertyIds): void
    {
        $propertyIds = array_values(array_unique(array_values(array_filter($propertyIds, static fn ($v) => is_int($v) && $v > 0))));
        if ($userId < 1 || $propertyIds === []) {
            return;
        }

        $ph = implode(',', array_fill(0, count($propertyIds), '?'));

        // 1) Jobs/cache/logs (scoped by user_id).
        $this->pdo->prepare("DELETE FROM {$this->t('sync_jobs')} WHERE user_id = ? AND property_id IN ({$ph})")
            ->execute(array_merge([$userId], $propertyIds));
        $this->pdo->prepare("DELETE FROM {$this->t('dashboard_cache')} WHERE user_id = ? AND property_id IN ({$ph})")
            ->execute(array_merge([$userId], $propertyIds));

        // sync_run_items has no user_id; it stores site_url and (in newer code) property_id in logs payload elsewhere.
        // Best-effort: delete items by property_id when present.
        try {
            $this->pdo->prepare("DELETE FROM {$this->t('sync_run_items')} WHERE property_id IN ({$ph})")
                ->execute($propertyIds);
        } catch (\Throwable) {
            // Column may not exist in older schema; ignore.
        }

        // 2) Imported facts/aggregates keyed by property_id.
        foreach ([
            'gsc_daily_query_page',
            'gsc_daily_page',
            'gsc_daily_query',
            'gsc_daily_property_device',
            'gsc_daily_property_country',
            'gsc_daily_property_agg',
        ] as $table) {
            try {
                $this->pdo->prepare("DELETE FROM {$this->t($table)} WHERE property_id IN ({$ph})")
                    ->execute($propertyIds);
            } catch (\Throwable) {
                // Some installs may not have newer tables yet.
            }
        }

        // 3) Reset per-property sync metadata (keep enabled state).
        $this->pdo->prepare(
            "UPDATE {$this->t('gsc_properties')}
             SET last_sync_date = NULL, last_sync_at = NULL, last_sync_error = NULL
             WHERE id IN ({$ph})"
        )->execute($propertyIds);
    }

    /**
     * Wipe all application data, including users.
     */
    public function resetAllData(): void
    {
        // Delete in FK-safe order. Use best-effort so the admin sees an error instead of white screen.
        $tables = [
            // derived/caches
            'dashboard_cache',
            'seo_ai_token_usage',
            // sync/logs
            'sync_jobs',
            'sync_run_items',
            'sync_runs',
            // gsc facts/aggregates
            'gsc_daily_query_page',
            'gsc_daily_page',
            'gsc_daily_query',
            'gsc_daily_property_device',
            'gsc_daily_property_country',
            'gsc_daily_property_agg',
            // user preferences keyed by property (must drop before gsc_properties)
            'tracked_queries',
            'tracked_pages',
            'tracked_categories',
            // google accounts & properties
            'gsc_properties',
            'google_accounts',
            // projects/settings
            'projects',
            'settings',
            // users are intentionally preserved so the admin can log back in after a global reset.
        ];

        foreach ($tables as $name) {
            try {
                $this->pdo->exec("DELETE FROM {$this->t($name)}");
            } catch (\Throwable) {
                // Ignore missing tables (older installs) but do not halt.
            }
        }
    }
}

