<?php
declare(strict_types=1);

function ensure_storage_structure(): void
{
    foreach ([
        DATA_DIR,
        DATA_DIR . '/pages',
        DATA_DIR . '/modules',
        DATA_DIR . '/collections',
        DATA_DIR . '/backups',
        DATA_DIR . '/crm',
        UPLOADS_DIR,
        LOGS_DIR,
    ] as $dir) {
        ensure_dir($dir);
    }
}

function settings_path(): string
{
    return DATA_DIR . '/settings.json';
}

function page_path(string $slug): string
{
    return DATA_DIR . '/pages/' . $slug . '.json';
}

function module_path(string $id): string
{
    return DATA_DIR . '/modules/' . $id . '.json';
}

function collection_path(string $name): string
{
    return DATA_DIR . '/collections/' . $name . '.json';
}

function cms_settings(): array
{
    return read_json_file(settings_path(), []);
}

function cms_save_settings(array $data): bool
{
    backup_file(settings_path(), 'settings');
    return write_json_file(settings_path(), $data);
}


function cms_animals_popup_defaults(): array
{
    return [
        'button_label' => 'Про наших животных',
        'eyebrow' => 'Загородный отдых',
        'title' => 'Про наших животных',
        'text' => 'На территории живут дружелюбные животные. Здесь можно добавить подробный текст из админки.',
    ];
}

function cms_animals_popup_settings(?array $settings = null): array
{
    $settings = $settings ?? cms_settings();
    $defaults = cms_animals_popup_defaults();
    $raw = is_array($settings['animals_popup'] ?? null) ? $settings['animals_popup'] : [];
    $config = array_merge($defaults, $raw);
    foreach (array_keys($defaults) as $key) {
        $config[$key] = trim((string) ($config[$key] ?? $defaults[$key]));
    }
    return $config;
}


function cms_analytics_defaults(): array
{
    return [
        'enabled' => true,
        'head_code' => <<<'HTML'
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
    (function(m,e,t,r,i,k,a){
        m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
        m[i].l=1*new Date();
        for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
        k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
    })(window, document,'script','https://mc.yandex.ru/metrika/tag.js?id=108566032', 'ym');

    ym(108566032, 'init', {ssr:true, webvisor:true, clickmap:true, ecommerce:"dataLayer", referrer: document.referrer, url: location.href, accurateTrackBounce:true, trackLinks:true});
</script>
<!-- /Yandex.Metrika counter -->
HTML,
        'body_code' => <<<'HTML'
<noscript><div><img src="https://mc.yandex.ru/watch/108566032" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
HTML,
    ];
}

function cms_analytics_settings(?array $settings = null): array
{
    $settings = $settings ?? cms_settings();
    $defaults = cms_analytics_defaults();
    $raw = is_array($settings['analytics'] ?? null) ? $settings['analytics'] : [];
    return [
        'enabled' => array_key_exists('enabled', $raw) ? !empty($raw['enabled']) : !empty($defaults['enabled']),
        'head_code' => trim((string) ($raw['head_code'] ?? $defaults['head_code'])),
        'body_code' => trim((string) ($raw['body_code'] ?? $defaults['body_code'])),
    ];
}

function cms_render_head_analytics(?array $settings = null): string
{
    $config = cms_analytics_settings($settings);
    return !empty($config['enabled']) ? trim((string) $config['head_code']) : '';
}

function cms_render_body_open_analytics(?array $settings = null): string
{
    $config = cms_analytics_settings($settings);
    return !empty($config['enabled']) ? trim((string) $config['body_code']) : '';
}

function cms_page(string $slug): array
{
    return read_json_file(page_path($slug), []);
}

function cms_save_page(string $slug, array $data): bool
{
    backup_file(page_path($slug), 'pages');
    return write_json_file(page_path($slug), $data);
}

function cms_module(string $id): array
{
    return read_json_file(module_path($id), []);
}

function cms_save_module(string $id, array $data): bool
{
    backup_file(module_path($id), 'modules');
    return write_json_file(module_path($id), $data);
}

function cms_delete_module(string $id): void
{
    $path = module_path($id);
    if (is_file($path)) {
        backup_file($path, 'modules');
        unlink($path);
    }
}

function cms_all_modules(): array
{
    $files = glob(DATA_DIR . '/modules/*.json') ?: [];
    $items = [];
    foreach ($files as $file) {
        $data = read_json_file($file, []);
        if ($data) {
            $items[] = $data;
        }
    }
    usort($items, static function (array $a, array $b): int {
        return strcmp($a['name'] ?? '', $b['name'] ?? '');
    });
    return $items;
}

function cms_collection(string $name): array
{
    return read_json_file(collection_path($name), ['items' => []]);
}

function cms_save_collection(string $name, array $data): bool
{
    backup_file(collection_path($name), 'collections');
    return write_json_file(collection_path($name), $data);
}

function page_modules(array $page): array
{
    $modules = [];
    foreach (($page['modules'] ?? []) as $moduleId) {
        $module = cms_module((string)$moduleId);
        if ($module) {
            $modules[] = $module;
        }
    }
    return $modules;
}

function new_module_id(string $type): string
{
    return $type . '-' . date('YmdHis') . '-' . substr(bin2hex(random_bytes(3)), 0, 6);
}


function availability_path(): string
{
    return DATA_DIR . '/availability.json';
}

function cms_availability(): array
{
    return read_json_file(availability_path(), ['global' => [], 'houses' => []]);
}

function cms_save_availability(array $data): bool
{
    backup_file(availability_path(), 'availability');
    return write_json_file(availability_path(), $data);
}

function seo_site_url(): string
{
    $settings = cms_settings();
    $configured = trim((string)($settings['seo']['site_url'] ?? APP_URL));
    if ($configured !== '') {
        return rtrim($configured, '/');
    }
    $scheme = is_https() ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'] ?? '';
    return $host ? $scheme . '://' . $host : '';
}

function seo_pages_for_sitemap(): array
{
    return [
        ['loc' => '/', 'priority' => '1.0'],
        ['loc' => '/politica.php', 'priority' => '0.4'],
        ['loc' => '/rools.php', 'priority' => '0.4'],
    ];
}

function generate_seo_files(): void
{
    $base = seo_site_url();
    if ($base === '') {
        return;
    }
    $items = [];
    foreach (seo_pages_for_sitemap() as $row) {
        $loc = $base . ($row['loc'] === '/' ? '/' : $row['loc']);
        $items[] = "  <url>\n    <loc>" . htmlspecialchars($loc, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . "</loc>\n    <changefreq>weekly</changefreq>\n    <priority>" . ($row['priority'] ?? '0.6') . "</priority>\n  </url>";
    }
    $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n" . implode("\n", $items) . "\n</urlset>\n";
    @file_put_contents(__DIR__ . '/../sitemap.xml', $xml);
    $robots = "User-agent: *\nAllow: /\nSitemap: {$base}/sitemap.xml\n";
    @file_put_contents(__DIR__ . '/../robots.txt', $robots);
}


function cms_generate_seo_files(): void
{
    $settings = cms_settings();
    $pages = [
        ['loc' => base_url('/'), 'priority' => '1.0', 'changefreq' => 'weekly'],
        ['loc' => base_url('/politica.php'), 'priority' => '0.3', 'changefreq' => 'yearly'],
        ['loc' => base_url('/rools.php'), 'priority' => '0.3', 'changefreq' => 'yearly'],
    ];
    $xml = ['<?xml version="1.0" encoding="UTF-8"?>', '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'];
    foreach ($pages as $page) {
        $xml[] = '  <url>';
        $xml[] = '    <loc>' . htmlspecialchars($page['loc'], ENT_XML1 | ENT_QUOTES, 'UTF-8') . '</loc>';
        $xml[] = '    <changefreq>' . $page['changefreq'] . '</changefreq>';
        $xml[] = '    <priority>' . $page['priority'] . '</priority>';
        $xml[] = '  </url>';
    }
    $xml[] = '</urlset>';
    file_put_contents(ROOT_DIR . '/sitemap.xml', implode(PHP_EOL, $xml));

    $robots = [];
    $robots[] = 'User-agent: *';
    $robots[] = !empty($settings['seo']['noindex']) ? 'Disallow: /' : 'Allow: /';
    $robots[] = 'Sitemap: ' . base_url('/sitemap.xml');
    file_put_contents(ROOT_DIR . '/robots.txt', implode(PHP_EOL, $robots) . PHP_EOL);
}


function cms_booking_form_defaults(): array
{
    return [
        'eyebrow' => 'Выбранный вариант',
        'title' => 'Забронировать отдых',
        'house_description' => 'Выберите домик и даты — мы сразу отправим заявку администратору в Telegram.',
        'summary_nights_label' => 'Ночей',
        'summary_total_label' => 'Стоимость от',
        'summary_total_empty' => 'Выберите даты',
        'summary_hint' => 'Итоговую стоимость подтверждает администратор с учётом выбранного дома, дат, сезона и дополнительных услуг.',
        'lead_text' => 'Выберите домик, отметьте даты заезда и выезда в календаре и оставьте контакты — мы быстро подтвердим бронь в Telegram.',
        'caption' => 'Удобный премиальный формат бронирования: главное о домике слева, контакты и календарь справа.',
        'calendar_label' => 'Календарь бронирования',
        'submit_label' => 'Отправить заявку',
        'consent_prefix' => 'Согласен на обработку персональных данных и принимаю ',
        'privacy_link_label' => 'политику конфиденциальности',
        'privacy_link_url' => '/politica.php',
        'consent_middle' => ' и ',
        'rules_link_label' => 'правила проживания',
        'rules_link_url' => '/rools.php',
        'consent_suffix' => '.',
        'field_order' => ['name', 'phone', 'contact_nick', 'house', 'checkin', 'checkout', 'calendar', 'adults', 'children', 'pet', 'comment'],
        'fields' => [
            'name' => [
                'label' => 'Имя',
                'placeholder' => '',
                'type' => 'text',
                'enabled' => true,
                'required' => true,
                'width' => 'half',
                'locked_enabled' => true,
                'locked_required' => true,
            ],
            'phone' => [
                'label' => 'Телефон',
                'placeholder' => '',
                'type' => 'text',
                'enabled' => true,
                'required' => true,
                'width' => 'half',
                'locked_enabled' => true,
                'locked_required' => true,
            ],
            'contact_nick' => [
                'label' => 'Telegram / WhatsApp',
                'placeholder' => '@username или номер',
                'type' => 'text',
                'enabled' => true,
                'required' => false,
                'width' => 'half',
            ],
            'house' => [
                'label' => 'Домик',
                'placeholder' => 'Выберите домик',
                'type' => 'house_select',
                'enabled' => true,
                'required' => true,
                'width' => 'half',
                'locked_enabled' => true,
                'locked_required' => true,
            ],
            'checkin' => [
                'label' => 'Заезд',
                'placeholder' => 'Выберите дату',
                'type' => 'date_text',
                'enabled' => true,
                'required' => true,
                'width' => 'half',
                'locked_enabled' => true,
                'locked_required' => true,
            ],
            'checkout' => [
                'label' => 'Выезд',
                'placeholder' => 'Выберите дату',
                'type' => 'date_text',
                'enabled' => true,
                'required' => true,
                'width' => 'half',
                'locked_enabled' => true,
                'locked_required' => true,
            ],
            'calendar' => [
                'label' => 'Календарь бронирования',
                'placeholder' => '',
                'type' => 'calendar',
                'enabled' => true,
                'required' => false,
                'width' => 'full',
                'locked_enabled' => true,
                'locked_required' => true,
                'locked_width' => true,
            ],
            'adults' => [
                'label' => 'Взрослые',
                'placeholder' => '',
                'type' => 'number',
                'enabled' => true,
                'required' => false,
                'width' => 'half',
                'min' => 1,
                'max' => 20,
                'value' => '2',
            ],
            'children' => [
                'label' => 'Дети / возраст',
                'placeholder' => 'Например: 2 ребёнка, 4 и 8 лет',
                'type' => 'text',
                'enabled' => true,
                'required' => false,
                'width' => 'half',
            ],
            'pet' => [
                'label' => 'Питомец',
                'placeholder' => '',
                'type' => 'select',
                'enabled' => true,
                'required' => false,
                'width' => 'half',
                'options' => [
                    ['value' => 'Нет', 'label' => 'Нет'],
                    ['value' => 'Да', 'label' => 'Да'],
                ],
            ],
            'comment' => [
                'label' => 'Комментарий',
                'placeholder' => 'Пожелания по домику, бане, чану, отдыху с детьми или животным...',
                'type' => 'textarea',
                'enabled' => true,
                'required' => false,
                'width' => 'full',
                'rows' => 4,
            ],
        ],
    ];
}

function cms_booking_form_settings(?array $settings = null): array
{
    $settings = $settings ?? cms_settings();
    $defaults = cms_booking_form_defaults();
    $raw = is_array($settings['booking_form'] ?? null) ? $settings['booking_form'] : [];
    $config = array_merge($defaults, $raw);

    $config['fields'] = [];
    foreach ($defaults['fields'] as $key => $fieldDefaults) {
        $fieldRaw = is_array($raw['fields'][$key] ?? null) ? $raw['fields'][$key] : [];
        $field = array_merge($fieldDefaults, $fieldRaw);
        $field['label'] = trim((string) ($field['label'] ?? $fieldDefaults['label'] ?? $key));
        $field['placeholder'] = (string) ($field['placeholder'] ?? $fieldDefaults['placeholder'] ?? '');
        $field['type'] = (string) ($field['type'] ?? $fieldDefaults['type'] ?? 'text');
        $field['enabled'] = !empty($field['locked_enabled']) ? true : !empty($field['enabled']);
        $field['required'] = !empty($field['locked_required']) ? true : !empty($field['required']);
        $field['width'] = (string) ($field['width'] ?? $fieldDefaults['width'] ?? 'half');
        if (!in_array($field['width'], ['half', 'full'], true)) {
            $field['width'] = (string) ($fieldDefaults['width'] ?? 'half');
        }
        if (!empty($field['locked_width'])) {
            $field['width'] = (string) ($fieldDefaults['width'] ?? 'full');
        }
        if (isset($fieldDefaults['options'])) {
            $options = [];
            foreach ((array) ($field['options'] ?? []) as $option) {
                if (is_array($option)) {
                    $value = trim((string) ($option['value'] ?? ''));
                    $label = trim((string) ($option['label'] ?? $value));
                } else {
                    $value = trim((string) $option);
                    $label = $value;
                }
                if ($value === '' && $label === '') {
                    continue;
                }
                $options[] = ['value' => $value !== '' ? $value : $label, 'label' => $label !== '' ? $label : $value];
            }
            if ($options === []) {
                $options = $fieldDefaults['options'];
            }
            $field['options'] = $options;
        }
        $config['fields'][$key] = $field;
    }

    $order = [];
    foreach ((array) ($raw['field_order'] ?? $defaults['field_order']) as $key) {
        $key = (string) $key;
        if ($key !== '' && isset($config['fields'][$key])) {
            $order[] = $key;
        }
    }
    foreach (array_keys($config['fields']) as $key) {
        if (!in_array($key, $order, true)) {
            $order[] = $key;
        }
    }
    $config['field_order'] = $order;

    foreach ([
        'eyebrow',
        'title',
        'house_description',
        'summary_nights_label',
        'summary_total_label',
        'summary_total_empty',
        'summary_hint',
        'lead_text',
        'caption',
        'calendar_label',
        'submit_label',
        'consent_prefix',
        'privacy_link_label',
        'privacy_link_url',
        'consent_middle',
        'rules_link_label',
        'rules_link_url',
        'consent_suffix',
    ] as $key) {
        $config[$key] = (string) ($config[$key] ?? $defaults[$key] ?? '');
    }

    return $config;
}

function revenue_dashboard_stats(): array
{
    $leads = cms_leads()['items'] ?? [];
    $stats = [
        'total' => count($leads),
        'new' => 0,
        'in_progress' => 0,
        'confirmed' => 0,
        'done' => 0,
        'cancelled' => 0,
        'hidden' => 0,
        'revenue_confirmed' => 0,
        'revenue_potential' => 0,
        'average_check_confirmed' => 0,
        'average_check_potential' => 0,
    ];
    $confirmedCount = 0;
    $potentialCount = 0;
    foreach ($leads as $lead) {
        $status = (string)($lead['status'] ?? 'new');
        if (isset($stats[$status])) $stats[$status]++;
        $amount = preg_replace('/\D+/u', '', (string)($lead['estimated_total'] ?? ''));
        $amountValue = $amount !== '' ? (int)$amount : 0;
        if (in_array($status, ['confirmed', 'done'], true)) {
            $stats['revenue_confirmed'] += $amountValue;
            if ($amountValue > 0) $confirmedCount++;
        }
        if (in_array($status, ['new', 'in_progress', 'confirmed', 'done'], true)) {
            $stats['revenue_potential'] += $amountValue;
            if ($amountValue > 0) $potentialCount++;
        }
    }
    $stats['average_check_confirmed'] = $confirmedCount ? (int)round($stats['revenue_confirmed'] / $confirmedCount) : 0;
    $stats['average_check_potential'] = $potentialCount ? (int)round($stats['revenue_potential'] / $potentialCount) : 0;
    return $stats;
}


function cms_admin_health(): array
{
    $checks = [];
    $warnings = 0;
    $targets = [
        ['label' => 'data', 'path' => DATA_DIR, 'type' => 'dir'],
        ['label' => 'uploads', 'path' => UPLOADS_DIR, 'type' => 'dir'],
        ['label' => 'logs', 'path' => LOGS_DIR, 'type' => 'dir'],
        ['label' => 'settings.json', 'path' => settings_path(), 'type' => 'file'],
        ['label' => 'leads.json', 'path' => DATA_DIR . '/leads.json', 'type' => 'file'],
    ];

    foreach ($targets as $target) {
        $path = $target['path'];
        $exists = $target['type'] === 'dir' ? is_dir($path) : is_file($path);
        $writable = $exists ? is_writable($path) : is_writable(dirname($path));
        $status = ($exists && $writable) ? 'ok' : 'warn';
        if ($status !== 'ok') {
            $warnings++;
        }
        $checks[] = [
            'label' => $target['label'],
            'path' => $path,
            'exists' => $exists,
            'writable' => $writable,
            'status' => $status,
        ];
    }

    $backupFiles = glob(DATA_DIR . '/backups/*/*') ?: [];
    $recentBackupTs = 0;
    foreach ($backupFiles as $file) {
        $recentBackupTs = max($recentBackupTs, (int) (filemtime($file) ?: 0));
    }

    $uploadCount = 0;
    $uploadBytes = 0;
    if (is_dir(UPLOADS_DIR)) {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator(UPLOADS_DIR, FilesystemIterator::SKIP_DOTS)
        );
        foreach ($iterator as $file) {
            if (!$file->isFile()) {
                continue;
            }
            $uploadCount++;
            $uploadBytes += (int) $file->getSize();
        }
    }

    return [
        'status' => $warnings === 0 ? 'ok' : 'warn',
        'warning_count' => $warnings,
        'checks' => $checks,
        'backup_count' => count($backupFiles),
        'recent_backup_ts' => $recentBackupTs,
        'upload_count' => $uploadCount,
        'upload_bytes' => $uploadBytes,
        'page_count' => count(glob(DATA_DIR . '/pages/*.json') ?: []),
        'module_count' => count(glob(DATA_DIR . '/modules/*.json') ?: []),
    ];
}
