<?php
namespace Analytics\Controllers;

use Analytics\Lib\View;
use Analytics\Repositories\ProjectRepository;
use Analytics\Repositories\SnapshotRepository;
use Analytics\Services\AnalyticsFetchService;
use Analytics\Services\ReportBuilderService;

class WebController
{
    private ProjectRepository  $projects;
    private SnapshotRepository $snapshots;
    private AnalyticsFetchService $fetcher;
    private ReportBuilderService $reports;

    public function __construct()
    {
        $this->projects  = new ProjectRepository();
        $this->snapshots = new SnapshotRepository();
        $this->fetcher   = new AnalyticsFetchService();
        $this->reports   = new ReportBuilderService();
    }

    public function dashboard(): void
    {
        $projects    = $this->projects->all();
        $projectIds  = array_map(fn($p) => (int)$p['id'], $projects);
        $latestSnaps = $this->snapshots->latestPerProject($projectIds);
        $globalCpls  = $this->reports->getGlobalCpls();

        // Enrich projects with latest snapshot + computed metrics
        $enriched = array_map(function (array $p) use ($latestSnaps, $globalCpls): array {
            $snap = $latestSnaps[(int)$p['id']] ?? null;
            if (!$snap) return array_merge($p, ['snapshot' => null, 'health_score' => 0, 'roas' => 0]);

            // Previous period for health score
            $prev = $this->snapshots->previous((int)$p['id'], $snap['period_start'], $snap['period_end']);
            $health = $this->reports->calcHealthScore($snap, $prev);
            $roas   = $this->reports->calcRoas($snap, $p);

            return array_merge($p, [
                'snapshot'     => $snap,
                'health_score' => $health,
                'roas'         => $roas,
            ]);
        }, $projects);

        $rollup = $this->reports->buildManagerRollup(
            $projects,
            date('Y-m-d', strtotime('-30 days')),
            date('Y-m-d')
        );

        View::render('dashboard/index', [
            'pageTitle'  => 'Analytics Dashboard',
            'projects'   => $enriched,
            'rollup'     => $rollup,
            'globalCpls' => $globalCpls,
        ]);
    }

    public function projectShow(int $id): void
    {
        $project = $this->projects->find($id);
        if (!$project) { http_response_code(404); echo 'Project not found'; return; }

        $snapshotList = $this->snapshots->listForProject($id, 50);
        $globalCpls   = $this->reports->getGlobalCpls();

        // Group snapshots by period length (days) so comparison is always like-for-like.
        // For each snapshot find its true "previous same-length period" from DB.
        $grouped = [];
        foreach ($snapshotList as $snap) {
            $days = (int)(new \DateTime($snap['period_start']))->diff(new \DateTime($snap['period_end']))->days;
            $prev = $this->snapshots->previous($id, $snap['period_start'], $snap['period_end']);
            $snap['_prev']      = $prev;
            $snap['_days']      = $days;
            $snap['_period_key'] = $this->periodLabel($days);
            $grouped[$snap['_period_key']][] = $snap;
        }
        // Sort groups by most-common / most useful: 30d first, then 90d, 180d, 7d, etc.
        $order = ['30d', '7d', '14d', '90d', '180d', 'YoY', 'Custom'];
        uksort($grouped, function ($a, $b) use ($order) {
            $ia = array_search($a, $order) ?? 99;
            $ib = array_search($b, $order) ?? 99;
            return $ia <=> $ib;
        });

        View::render('project/show', [
            'pageTitle'    => 'Analytics — ' . $project['business_name'],
            'project'      => $project,
            'snapshots'    => $snapshotList,
            'grouped'      => $grouped,
            'globalCpls'   => $globalCpls,
        ]);
    }

    private function periodLabel(int $days): string
    {
        return match(true) {
            $days <= 7   => '7d',
            $days <= 14  => '14d',
            $days <= 31  => '30d',
            $days <= 92  => '90d',
            $days <= 185 => '180d',
            $days <= 370 => 'YoY',
            default      => 'Custom',
        };
    }

    public function reportViewer(): void
    {
        $projectId   = (int)($_GET['project'] ?? 0);
        $start       = $_GET['start']    ?? date('Y-m-d', strtotime('-30 days'));
        $end         = $_GET['end']      ?? date('Y-m-d');
        $audience    = $_GET['audience'] ?? 'client';
        $compareMode = in_array($_GET['compare'] ?? '', ['period', 'month', 'year'])
                       ? $_GET['compare'] : 'period';

        // No project selected → show picker
        if (!$projectId) {
            $projects = $this->projects->all();
            View::render('report/picker', [
                'pageTitle' => 'Select Project — Reports',
                'projects'  => $projects,
                'start'     => $start,
                'end'       => $end,
                'audience'  => $audience,
            ]);
            return;
        }

        $project = $this->projects->find($projectId);
        if (!$project) { http_response_code(404); echo 'Project not found'; return; }

        $report = $this->buildReportWithAutoFetch($projectId, $project, $start, $end, $audience, $compareMode);

        // Pass all project IDs for prev/next navigation
        $allProjects = $this->projects->all();
        $allIds      = array_column($allProjects, 'id');
        $currentIdx  = array_search($projectId, $allIds);
        $prevProject = $currentIdx > 0 ? $allProjects[$currentIdx - 1] : null;
        $nextProject = $currentIdx !== false && $currentIdx < count($allIds) - 1 ? $allProjects[$currentIdx + 1] : null;

        View::render('report/viewer', [
            'pageTitle'   => 'Report — ' . $project['business_name'],
            'report'      => $report,
            'project'     => $project,
            'start'       => $start,
            'end'         => $end,
            'audience'    => $audience,
            'compareMode' => $compareMode,
            'prevProject' => $prevProject,
            'nextProject' => $nextProject,
        ]);
    }

    public function reportSlides(): void
    {
        $projectId = (int)($_GET['project'] ?? 0);
        $start     = $_GET['start']    ?? date('Y-m-d', strtotime('-30 days'));
        $end       = $_GET['end']      ?? date('Y-m-d');
        $audience  = $_GET['audience'] ?? 'client';

        $project = $projectId ? $this->projects->find($projectId) : null;
        if (!$project) { http_response_code(404); echo 'Project not found'; return; }

        $report = $this->buildReportWithAutoFetch($projectId, $project, $start, $end, $audience);

        // Slides view has its own full-page layout (no sidebar)
        require ANALYTICS_VIEWS . '/report/slides.php';
    }

    public function aiOverviewIndex(int $projectId): void
    {
        $project = $this->projects->find($projectId);
        if (!$project) { http_response_code(404); echo 'Project not found'; return; }

        View::render('ai-overview/index', [
            'pageTitle' => 'AI Overview — ' . $project['business_name'],
            'project'   => $project,
        ]);
    }

    public function aiOverviewDetail(int $projectId, int $promptId): void
    {
        $project = $this->projects->find($projectId);
        if (!$project) { http_response_code(404); echo 'Project not found'; return; }

        $db     = \Analytics\Lib\Database::getInstance();
        $prompt = $db->fetch('SELECT * FROM brand_prompts WHERE id = ? AND brand_id = ?', [$promptId, $projectId]);
        if (!$prompt) { http_response_code(404); echo 'Prompt not found'; return; }

        $latestRun   = $db->fetch('SELECT * FROM prompt_runs WHERE prompt_id = ? ORDER BY created_at DESC LIMIT 1', [$promptId]);
        $latestLinks = $latestRun
            ? $db->fetchAll('SELECT * FROM prompt_run_links WHERE run_id = ? ORDER BY `rank` ASC', [$latestRun['id']])
            : [];

        View::render('ai-overview/detail', [
            'pageTitle'   => 'Prompt Details — ' . $project['business_name'],
            'project'     => $project,
            'prompt'      => $prompt,
            'latestRun'   => $latestRun,
            'latestLinks' => $latestLinks,
        ]);
    }

    public function migrate(): void
    {
        $migrDir = ANALYTICS_ROOT . '/database/migrations';
        $db      = \Analytics\Lib\Database::getInstance();

        // Ensure schema_migrations table exists (shared with Audit)
        $db->query("CREATE TABLE IF NOT EXISTS schema_migrations (
            id          INT AUTO_INCREMENT PRIMARY KEY,
            filename    VARCHAR(200) NOT NULL UNIQUE,
            applied_at  DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
        )");

        $applied  = array_column($db->fetchAll('SELECT filename FROM schema_migrations'), 'filename');
        $files    = glob($migrDir . '/*.sql');
        sort($files);
        $results  = [];

        foreach ($files as $file) {
            $name = basename($file);
            if (in_array($name, $applied, true)) {
                $results[] = ['file' => $name, 'status' => 'already_applied'];
                continue;
            }
            try {
                $sql = file_get_contents($file);
                foreach (array_filter(array_map('trim', explode(';', $sql))) as $stmt) {
                    $db->query($stmt);
                }
                $db->insert('schema_migrations', ['migration' => $name, 'filename' => $name, 'applied_at' => date('Y-m-d H:i:s')]);
                $results[] = ['file' => $name, 'status' => 'applied'];
            } catch (\Throwable $e) {
                $msg = $e->getMessage();
                if (str_contains($msg, '1060') || str_contains($msg, 'Duplicate column')) {
                    $db->insert('schema_migrations', ['migration' => $name, 'filename' => $name, 'applied_at' => date('Y-m-d H:i:s')]);
                    $results[] = ['file' => $name, 'status' => 'warning', 'message' => $msg];
                } else {
                    $results[] = ['file' => $name, 'status' => 'error', 'message' => $msg];
                }
            }
        }

        $errors = array_filter($results, fn($r) => $r['status'] === 'error');
        $banner = count($errors) > 0 ? '❌ ' . count($errors) . ' error(s)' : '✅ All migrations applied';
        echo '<pre style="font-family:monospace;padding:20px;">' . $banner . "\n\n";
        foreach ($results as $r) {
            $icon = ['applied' => '✅', 'already_applied' => '⏭', 'warning' => '⚠️', 'error' => '❌'][$r['status']];
            echo $icon . ' ' . $r['file'] . ($r['message'] ?? '') . "\n";
        }
        echo '</pre>';
    }

    private function buildReportWithAutoFetch(int $projectId, array $project, string $start, string $end, string $audience, string $compareMode = 'period'): array
    {
        $report = $this->reports->buildReport($projectId, $project, $start, $end, $audience, $compareMode);

        // Auto-fetch current period if no snapshot exists yet
        if (($report['error'] ?? '') === 'No data for this period. Please run the tracker first.') {
            try {
                $result = $this->fetcher->fetchProject($projectId, $project, $start, $end, 'custom');
                if (!($result['success'] ?? false)) {
                    return $report;
                }
            } catch (\Throwable) {
                return $report;
            }
            $report = $this->reports->buildReport($projectId, $project, $start, $end, $audience, $compareMode);
        }

        return $report;
    }
}
