<?php

declare(strict_types=1);

HookSystem::addAction('admin.sidebar_menu', function (string $activeMenu): void {
    ?>
    <a href="/admin/ads" class="flex items-center gap-2.5 px-5 py-2.5 text-sm no-underline transition-all duration-150 <?= $activeMenu === 'ads' ? 'text-white bg-primary-600' : 'text-gray-400 hover:text-white hover:bg-gray-800' ?>">
        <svg viewBox="0 0 24 24" class="w-[18px] h-[18px] shrink-0" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/><path d="M9 21V9"/></svg>
        Advertising
    </a>
    <?php
}, 15);

class AdminAdController
{
    public static function routes(): void
    {
        Router::get('/admin/ads', [self::class, 'index']);
        Router::post('/admin/ads/zone/toggle', [self::class, 'toggleZone']);
        Router::get('/admin/ads/zone/{id}', [self::class, 'editZone']);
        Router::get('/admin/ads/zone/{zoneId}/spot/new', [self::class, 'newSpot']);
        Router::get('/admin/ads/zone/{zoneId}/spot/{id}/edit', [self::class, 'editSpot']);
        Router::post('/admin/ads/spot/save', [self::class, 'saveSpot']);
        Router::post('/admin/ads/spot/{id}/toggle', [self::class, 'toggleSpot']);
        Router::post('/admin/ads/spot/{id}/delete', [self::class, 'deleteSpot']);
        Router::post('/admin/ads/settings', [self::class, 'saveSettings']);
    }

    public static function index(): void
    {
        Auth::requireAdmin();

        $zones = Database::fetchAll('SELECT z.*, (SELECT COUNT(*) FROM ad_spots s WHERE s.zone_id = z.id) as spot_count, (SELECT COUNT(*) FROM ad_spots s WHERE s.zone_id = z.id AND s.is_active = 1) as active_spot_count FROM ad_zones z ORDER BY z.position, z.id');

        Router::render('admin/ads', [
            'pageTitle' => 'Advertising',
            'activeMenu' => 'ads',
            'contentTemplate' => '_ads',
            'zones' => $zones,
            'globalEnabled' => Setting::get('ads_enabled', '1') === '1',
            'popunderEnabled' => Setting::get('ads_popunder_enabled', '0') === '1',
            'accentColor' => Setting::get('ads_accent_color', '#dc2626'),
            'adsCloseable' => Setting::get('ads_closeable', '1') === '1',
            'adsTxt' => Setting::get('ads_txt', ''),
        ]);
    }

    public static function editZone(): void
    {
        Auth::requireAdmin();
        $zoneId = (int) Router::param('id');
        $zone = Database::fetchOne('SELECT * FROM ad_zones WHERE id = ?', [$zoneId]);
        if (!$zone) {
            $_SESSION['flash'] = ['type' => 'error', 'message' => 'Zone not found.'];
            Router::redirect('/admin/ads');
            return;
        }

        $spots = Database::fetchAll('SELECT * FROM ad_spots WHERE zone_id = ? ORDER BY position, id', [$zoneId]);

        Router::render('admin/ads', [
            'pageTitle' => 'Advertising — ' . $zone['name'],
            'activeMenu' => 'ads',
            'contentTemplate' => '_ads_zone',
            'zone' => $zone,
            'spots' => $spots,
        ]);
    }

    public static function newSpot(): void
    {
        Auth::requireAdmin();
        $zoneId = (int) Router::param('zoneId');
        $zone = Database::fetchOne('SELECT * FROM ad_zones WHERE id = ?', [$zoneId]);
        if (!$zone) { Router::redirect('/admin/ads'); return; }

        Router::render('admin/ads', [
            'pageTitle' => 'New Ad Spot — ' . $zone['name'],
            'activeMenu' => 'ads',
            'contentTemplate' => '_ads_spot_form',
            'zone' => $zone,
            'spot' => null,
        ]);
    }

    public static function editSpot(): void
    {
        Auth::requireAdmin();
        $zoneId = (int) Router::param('zoneId');
        $spotId = (int) Router::param('id');
        $zone = Database::fetchOne('SELECT * FROM ad_zones WHERE id = ?', [$zoneId]);
        $spot = Database::fetchOne('SELECT * FROM ad_spots WHERE id = ? AND zone_id = ?', [$spotId, $zoneId]);
        if (!$zone || !$spot) { Router::redirect('/admin/ads'); return; }

        Router::render('admin/ads', [
            'pageTitle' => 'Edit Ad Spot — ' . $zone['name'],
            'activeMenu' => 'ads',
            'contentTemplate' => '_ads_spot_form',
            'zone' => $zone,
            'spot' => $spot,
        ]);
    }

    public static function toggleZone(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::json(['error' => 'CSRF'], 403); return; }
        $input = json_decode(file_get_contents('php://input'), true) ?: [];
        $id = (int) ($input['id'] ?? 0);
        $active = !empty($input['active']) ? 1 : 0;
        Database::query('UPDATE ad_zones SET is_active = ? WHERE id = ?', [$active, $id]);
        Router::json(['ok' => true]);
    }

    public static function createZone(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::redirect('/admin/ads'); return; }
        $name = trim($_POST['zone_name'] ?? '');
        if ($name === '') {
            $_SESSION['flash'] = ['type' => 'error', 'message' => 'Zone name is required.'];
            Router::redirect('/admin/ads');
            return;
        }
        $slug = Slug::generate($name);
        $existing = Database::fetchOne('SELECT id FROM ad_zones WHERE slug = ?', [$slug]);
        if ($existing) {
            $slug .= '-' . time();
        }
        $page = $_POST['zone_page'] ?? 'all';
        $validPages = ['all', 'homepage', 'watch', 'listing', 'category', 'performer'];
        if (!in_array($page, $validPages, true)) $page = 'all';
        $maxPos = (int) Database::fetchOne('SELECT MAX(position) as m FROM ad_zones')['m'];
        Database::insert('ad_zones', [
            'slug' => $slug,
            'name' => $name,
            'description' => trim($_POST['zone_description'] ?? ''),
            'page' => $page,
            'position' => $maxPos + 1,
        ]);
        $_SESSION['flash'] = ['type' => 'success', 'message' => 'Zone created.'];
        Router::redirect('/admin/ads');
    }

    public static function deleteZone(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::redirect('/admin/ads'); return; }
        $id = (int) Router::param('id');
        Database::delete('ad_zones', 'id = ?', [$id]);
        $_SESSION['flash'] = ['type' => 'success', 'message' => 'Zone deleted.'];
        Router::redirect('/admin/ads');
    }

    public static function reorderZones(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::json(['error' => 'CSRF'], 403); return; }
        $input = json_decode(file_get_contents('php://input'), true) ?: [];
        $order = $input['order'] ?? [];
        foreach ($order as $pos => $id) {
            Database::query('UPDATE ad_zones SET position = ? WHERE id = ?', [(int) $pos, (int) $id]);
        }
        Router::json(['ok' => true]);
    }

    public static function saveSpot(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::redirect('/admin/ads'); return; }

        $spotId = (int) ($_POST['spot_id'] ?? 0);
        $zoneId = (int) ($_POST['zone_id'] ?? 0);

        if ($zoneId <= 0) {
            $_SESSION['flash'] = ['type' => 'error', 'message' => 'Invalid zone.'];
            Router::redirect('/admin/ads');
            return;
        }

        $data = [
            'zone_id' => $zoneId,
            'name' => trim($_POST['spot_name'] ?? ''),
            'headline' => (trim($_POST['headline'] ?? '') !== '') ? mb_substr(trim($_POST['headline']), 0, 120) : null,
            'ad_type' => in_array($_POST['ad_type'] ?? '', ['code', 'image', 'vast'], true) ? $_POST['ad_type'] : 'code',
            'ad_code' => $_POST['ad_code'] ?? '',
            'image_url' => trim($_POST['image_url'] ?? ''),
            'click_url' => trim($_POST['click_url'] ?? ''),
            'vast_url' => preg_match('#^https?://#i', trim($_POST['vast_url'] ?? '')) ? trim($_POST['vast_url']) : '',
            'device' => in_array($_POST['device'] ?? '', ['all', 'desktop', 'mobile'], true) ? $_POST['device'] : 'all',
            'geo' => implode(',', array_values(array_filter(array_map(static fn($c) => preg_match('/^[A-Za-z]{2}$/', trim($c)) ? strtoupper(trim($c)) : '', explode(',', (string) ($_POST['geo'] ?? '')))))),
            'is_active' => isset($_POST['is_active']) ? 1 : 0,
            'is_house' => isset($_POST['is_house']) ? 1 : 0,
            'weight' => max(1, min(10, (int) ($_POST['weight'] ?? 5))),
            'start_date' => !empty($_POST['start_date']) ? $_POST['start_date'] : null,
            'start_time' => !empty($_POST['start_time']) ? $_POST['start_time'] : null,
            'end_date' => !empty($_POST['end_date']) ? $_POST['end_date'] : null,
            'end_time' => !empty($_POST['end_time']) ? $_POST['end_time'] : null,
            'player_position' => in_array($_POST['player_position'] ?? '', ['preroll', 'midroll', 'postroll', 'overlay'], true) ? $_POST['player_position'] : null,
            'midroll_at' => max(1, min(99, (int) ($_POST['midroll_at'] ?? 50))),
            'skip_after' => max(0, min(30, (int) ($_POST['skip_after'] ?? 5))),
             
            'pop_mode' => in_array($_POST['pop_mode'] ?? 'url', ['url', 'code'], true) ? ($_POST['pop_mode'] ?? 'url') : 'url',
            'popunder_url' => preg_match('#^https?://#i', trim($_POST['popunder_url'] ?? ''))
                                ? trim($_POST['popunder_url']) : null,
            'pop_delay' => max(0, min(3600, self::popVal('pop_delay_preset', 'pop_delay', 0))),
            'pop_cap' => max(0, min(50, self::popVal('pop_cap_preset', 'pop_cap', 1))),
            'pop_window' => in_array((int) ($_POST['pop_window'] ?? 24), [0, 1, 24, 168, 720], true)
                                ? (int) ($_POST['pop_window'] ?? 24) : 24,
            'pop_trigger' => self::popTriggers(),
        ];

         
        if (!empty($_FILES['image_file']['tmp_name']) && $_FILES['image_file']['error'] === UPLOAD_ERR_OK) {
            $allowedMimes = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp'];
             
            $mime = Mime::fromFile($_FILES['image_file']['tmp_name'], $_FILES['image_file']['name'] ?? null);
            if ($mime && isset($allowedMimes[$mime])) {
                $ext = $allowedMimes[$mime];
                $filename = 'ad_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
                $dest = APP_ROOT . '/public/uploads/media/' . $filename;
                if (!is_dir(dirname($dest))) {
                    mkdir(dirname($dest), 0775, true);
                }
                move_uploaded_file($_FILES['image_file']['tmp_name'], $dest);
                $data['image_url'] = '/uploads/media/' . $filename;
            }
        }

        if ($spotId > 0) {
            Database::update('ad_spots', $data, 'id = ?', [$spotId]);
        } else {
            $maxPos = (int) Database::fetchOne('SELECT MAX(position) as m FROM ad_spots WHERE zone_id = ?', [$zoneId])['m'];
            $data['position'] = $maxPos + 1;
            Database::insert('ad_spots', $data);
        }

         
        $flash = ['type' => 'success', 'message' => 'Ad spot saved.'];
        $zoneSlug = (string) (Database::fetchOne('SELECT slug FROM ad_zones WHERE id = ?', [$zoneId])['slug'] ?? '');
        if ($data['ad_type'] === 'vast' && $data['vast_url'] === '') {
            $flash = ['type' => 'error', 'message' => 'Ad spot saved, but the VAST tag URL is missing or does not start with http(s):// — nothing will be shown until you fix it.'];
        }
        if ($zoneSlug === 'popup') {
            if ($data['pop_mode'] === 'url' && $data['popunder_url'] === null) {
                $flash = ['type' => 'error', 'message' => 'Popunder saved, but the web address is missing or not http(s):// — it won\'t open until you fix it.'];
            } elseif ($data['pop_mode'] === 'code' && trim((string) $data['ad_code']) === '') {
                $flash = ['type' => 'error', 'message' => 'Popunder saved, but the ad-network code is empty — it won\'t open until you add it.'];
            }
        }
        $_SESSION['flash'] = $flash;
        Router::redirect('/admin/ads/zone/' . $zoneId);
    }

     
    private static function popVal(string $presetKey, string $customKey, int $default): int
    {
        $p = $_POST[$presetKey] ?? (string) $default;
        return $p === 'custom' ? (int) ($_POST[$customKey] ?? $default) : (int) $p;
    }

     
    private static function popTriggers(): string
    {
        $pt = $_POST['pop_trigger'] ?? null;
        if (is_array($pt)) {
            $valid = array_values(array_intersect(array_map('strval', $pt), ['player_click', 'player_pause', 'player_play']));
            return implode(',', $valid ?: ['player_click']);
        }
        return in_array((string) ($pt ?? 'click'), ['click', 'player_click', 'player_pause', 'player_play'], true) ? (string) $pt : 'click';
    }

    public static function toggleSpot(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::json(['error' => 'CSRF'], 403); return; }
        $id = (int) Router::param('id');
        Database::query('UPDATE ad_spots SET is_active = NOT is_active WHERE id = ?', [$id]);
        Router::json(['ok' => true]);
    }

    public static function deleteSpot(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::json(['error' => 'CSRF'], 403); return; }
        $id = (int) Router::param('id');
        $spot = Database::fetchOne('SELECT zone_id FROM ad_spots WHERE id = ?', [$id]);
        if (!$spot) {
            Router::json(['error' => 'That ad spot no longer exists.'], 404);
            return;
        }

        $removed = Database::delete('ad_spots', 'id = ?', [$id]);
        if ($removed < 1) {
            Router::json(['error' => 'The ad spot could not be deleted.'], 500);
            return;
        }

        Router::json(['ok' => true, 'zone_id' => (int) $spot['zone_id']]);
    }

    public static function saveSettings(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::redirect('/admin/ads'); return; }
        Setting::set('ads_enabled', isset($_POST['ads_enabled']) ? '1' : '0');
        Setting::set('ads_popunder_enabled', isset($_POST['ads_popunder_enabled']) ? '1' : '0');
        Setting::set('ads_closeable', isset($_POST['ads_closeable']) ? '1' : '0');
        $col = trim($_POST['ads_accent_color'] ?? '');
        Setting::set('ads_accent_color', preg_match('/^#[0-9a-fA-F]{6}$/', $col) ? $col : '#dc2626');
        Setting::set('ads_txt', mb_substr((string) ($_POST['ads_txt'] ?? ''), 0, 20000));
        $_SESSION['flash'] = ['type' => 'success', 'message' => 'Ad settings saved.'];
        Router::redirect('/admin/ads');
    }
}
