<?php
declare(strict_types=1);

namespace Crawl\Controllers;

use Crawl\Lib\Database;
use Crawl\Lib\View;
use Crawl\Repositories\ProjectRepository;

class SerpController
{
    private Database $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
    }

    public function indexPage(): void
    {
        $projectId = (int)($_GET['project_id'] ?? 0);
        $project   = $projectId ? (new ProjectRepository())->find($projectId) : null;

        if ($projectId && !$project) {
            $this->redirect('/serp');
            return;
        }

        $submissions = $project
            ? $this->db->fetchAll(
                'SELECT ss.*, p.business_name AS project_name
                 FROM serp_submissions ss
                 JOIN projects p ON ss.project_id = p.id
                 WHERE ss.project_id = ?
                 ORDER BY ss.created_at DESC',
                [$projectId]
            )
            : $this->db->fetchAll(
                'SELECT ss.*, p.business_name AS project_name
                 FROM serp_submissions ss
                 JOIN projects p ON ss.project_id = p.id
                 ORDER BY ss.created_at DESC'
            );

        $projects = (new ProjectRepository())->all();

        View::render('serp/index', [
            'pageTitle'   => 'SERP Tracker',
            'project'     => $project,
            'projectId'   => $projectId,
            'submissions' => $submissions,
            'projects'    => $projects,
        ]);
    }

    public function detailsPage(): void
    {
        $submissionId = trim($_GET['id'] ?? '');
        $projectId    = (int)($_GET['project_id'] ?? 0);

        if (!$submissionId || !$projectId) {
            $this->redirect('/serp');
            return;
        }

        $project = (new ProjectRepository())->find($projectId);
        if (!$project) {
            $this->redirect('/serp');
            return;
        }

        $submission = $this->db->fetch(
            'SELECT * FROM serp_submissions WHERE TRIM(submission_id) = ? AND project_id = ?',
            [$submissionId, $projectId]
        );

        if (!$submission) {
            $this->redirect('/serp?project_id=' . $projectId);
            return;
        }

        $ranks = $this->db->fetchAll(
            'SELECT * FROM serp_keyword_ranks WHERE TRIM(submission_id) = ? ORDER BY checked_at DESC LIMIT 5',
            [$submissionId]
        );

        $runIds          = [];
        $columnLabels    = [];
        $keywordData     = [];
        $currentKeywords = array_values(array_filter(array_map('trim', explode("\n", $submission['keywords']))));

        foreach ($ranks as $row) {
            $runId              = $row['id'];
            $runIds[]           = $runId;
            $columnLabels[$runId] = date('d M, H:i', strtotime($row['checked_at']));

            $kList = explode("\n", $row['keyword']);
            $rList = explode("\n", $row['keyword_rank']);
            $uList = explode("\n", $row['url'] ?? '');

            foreach ($kList as $idx => $k) {
                $k = trim($k);
                if (!isset($keywordData[$k])) {
                    $keywordData[$k] = ['ranks' => [], 'urls' => []];
                }
                $keywordData[$k]['ranks'][$runId] = $rList[$idx] ?? '-';
                $keywordData[$k]['urls'][$runId]  = $uList[$idx] ?? '';
            }
        }

        foreach ($currentKeywords as $k) {
            if (!isset($keywordData[$k])) {
                $keywordData[$k] = ['ranks' => [], 'urls' => []];
            }
        }

        $chartLabels   = [];
        $chartTop3     = [];
        $chartTop10    = [];
        $chartTop100   = [];
        $chartNotFound = [];

        foreach (array_reverse($runIds) as $rId) {
            $chartLabels[] = $columnLabels[$rId];
            $t3 = $t10 = $t100 = $nf = 0;
            foreach ($currentKeywords as $kw) {
                $r = $keywordData[$kw]['ranks'][$rId] ?? '-';
                if (is_numeric($r)) {
                    if ($r <= 3) $t3++;
                    elseif ($r <= 10) $t10++;
                    else $t100++;
                } else {
                    $nf++;
                }
            }
            $chartTop3[]     = $t3;
            $chartTop10[]    = $t10;
            $chartTop100[]   = $t100;
            $chartNotFound[] = $nf;
        }

        View::render('serp/details', [
            'pageTitle'       => 'SERP Report — ' . $submissionId,
            'project'         => $project,
            'projectId'       => $projectId,
            'submissionId'    => $submissionId,
            'submission'      => $submission,
            'ranks'           => $ranks,
            'runIds'          => $runIds,
            'columnLabels'    => $columnLabels,
            'keywordData'     => $keywordData,
            'currentKeywords' => $currentKeywords,
            'chartLabels'     => $chartLabels,
            'chartTop3'       => $chartTop3,
            'chartTop10'      => $chartTop10,
            'chartTop100'     => $chartTop100,
            'chartNotFound'   => $chartNotFound,
        ]);
    }

    private function redirect(string $path): void
    {
        $base = rtrim(str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? '/')), '/');
        header('Location: ' . $base . $path);
        exit;
    }
}
