<?php

declare(strict_types=1);

namespace Bocken\Themes;

use Fisharebest\Webtrees\Module\AbstractModule;
use Fisharebest\Webtrees\Module\ModuleCustomInterface;
use Fisharebest\Webtrees\Module\ModuleCustomTrait;
use Fisharebest\Webtrees\Module\ModuleGlobalInterface;
use Fisharebest\Webtrees\Module\ModuleGlobalTrait;
use Fisharebest\Webtrees\Module\ModuleThemeInterface;
use Fisharebest\Webtrees\Module\ModuleThemeTrait;
use Fisharebest\Webtrees\View;

class BockenTheme extends AbstractModule implements ModuleCustomInterface, ModuleGlobalInterface, ModuleThemeInterface
{
    use ModuleCustomTrait, ModuleGlobalTrait, ModuleThemeTrait;

    public const string MODULE_TITLE = "Bocken";
    public const string MODULE_DESCRIPTION = "Nord-themed dark/light mode family tree theme";
    public const string MODULE_AUTHOR = 'Alexander Bocken';
    public const string MODULE_VERSION = '1.0.0';
    public const string MODULE_RESOURCE_PATH = __DIR__ . '/resources/';

    public function title(): string
    {
        return self::MODULE_TITLE;
    }

    public function description(): string
    {
        return self::MODULE_DESCRIPTION;
    }

    public function customModuleAuthorName(): string
    {
        return self::MODULE_AUTHOR;
    }

    public function customModuleVersion(): string
    {
        return self::MODULE_VERSION;
    }

    public function resourcesFolder(): string
    {
        return self::MODULE_RESOURCE_PATH;
    }

    public function stylesheets(): array
    {
        // imports.css must be built from within the webtrees installation
        // (it references vendor/fisharebest/webtrees/resources/css/_base.css)
        $sheets = [];
        $importsPath = self::MODULE_RESOURCE_PATH . 'css/imports.css';
        if (file_exists($importsPath)) {
            $sheets[] = $this->assetUrl('css/imports.css');
        }
        $sheets[] = $this->assetUrl('css/fonts.css');
        $sheets[] = $this->assetUrl('css/theme.css');
        return $sheets;
    }

    public function headContent(): string
    {
        $faviconUrl = $this->assetUrl('img/favicon.svg');

        return <<<HTML
        <link rel="icon" href="{$faviconUrl}" type="image/svg+xml">
        <script>
        (function() {
            var saved = localStorage.getItem('bocken-theme');
            if (saved === 'dark' || saved === 'light') {
                document.documentElement.setAttribute('data-theme', saved);
            }
        })();
        </script>
        HTML;
    }

    public function bodyContent(): string
    {
        $logoSvg = file_get_contents(self::MODULE_RESOURCE_PATH . 'img/logo.svg');
        // Strip XML declaration, collapse to single line for safe JS string embedding
        $logoSvg = preg_replace('/<\?xml[^?]*\?>/', '', $logoSvg);
        $logoSvg = preg_replace('/\s+/', ' ', trim($logoSvg));
        $logoSvgJs = addcslashes($logoSvg, "'\\");

        return <<<HTML
        <script src="https://unpkg.com/lucide@latest"></script>
        <script>
        (function() {
            'use strict';

            // --- Theme toggle ---
            var THEMES = ['auto', 'light', 'dark'];
            var ICONS = {
                auto:  'sun-moon',
                light: 'sun',
                dark:  'moon'
            };

            function getTheme() {
                return localStorage.getItem('bocken-theme') || 'auto';
            }

            function applyTheme(theme) {
                localStorage.setItem('bocken-theme', theme);
                if (theme === 'auto') {
                    document.documentElement.removeAttribute('data-theme');
                } else {
                    document.documentElement.setAttribute('data-theme', theme);
                }
                updateToggleButton();
                updateLogoFill();
            }

            function cycleTheme() {
                var current = getTheme();
                var idx = THEMES.indexOf(current);
                var next = THEMES[(idx + 1) % THEMES.length];
                applyTheme(next);
            }

            function updateToggleButton() {
                var btn = document.getElementById('bocken-theme-toggle');
                if (!btn) return;
                var theme = getTheme();
                btn.setAttribute('title', 'Theme: ' + theme);
                btn.setAttribute('aria-label', 'Toggle theme (' + theme + ')');
                btn.innerHTML = '<i data-lucide="' + ICONS[theme] + '"></i>';
                if (typeof lucide !== 'undefined') {
                    lucide.createIcons({ nodes: [btn] });
                }
            }

            // --- Logo injection ---
            function updateLogoFill() {
                var svg = document.querySelector('.bocken-logo svg');
                if (!svg) return;
                var theme = getTheme();
                var isDark;
                if (theme === 'dark') {
                    isDark = true;
                } else if (theme === 'light') {
                    isDark = false;
                } else {
                    // auto — let the SVG's own prefers-color-scheme handle it
                    svg.style.removeProperty('--fill');
                    return;
                }
                svg.style.setProperty('--fill', isDark ? '#D8DEE9' : '#2E3440');
            }

            function injectLogo() {
                var titleEl = document.querySelector('.wt-site-title');
                if (!titleEl) return;

                var logoContainer = document.createElement('div');
                logoContainer.className = 'bocken-logo-container';
                logoContainer.innerHTML = '<a href="https://bocken.org" class="bocken-logo-link" aria-label="Bocken.org"><div class="bocken-logo">{$logoSvgJs}</div></a>';

                titleEl.parentNode.insertBefore(logoContainer, titleEl);
                updateLogoFill();
            }

            // --- Theme toggle button injection ---
            function injectToggle() {
                var nav = document.querySelector('.wt-secondary-navigation .nav');
                if (!nav) return;

                var li = document.createElement('li');
                li.className = 'nav-item bocken-theme-toggle-item';

                var btn = document.createElement('button');
                btn.id = 'bocken-theme-toggle';
                btn.className = 'bocken-theme-btn';
                btn.type = 'button';
                btn.addEventListener('click', cycleTheme);

                li.appendChild(btn);
                nav.insertBefore(li, nav.firstChild);
                updateToggleButton();
            }

            // --- Language abbreviation ---
            function shortenLanguage() {
                var langItem = document.querySelector('.menu-language > .nav-link');
                if (!langItem) return;

                // Find the active language from dropdown items
                var activeLang = document.querySelector('.menu-language .dropdown-item.active');
                var code = 'EN';
                if (activeLang) {
                    // Extract from class like "menu-language-de" or "menu-language-en-US"
                    var cls = Array.from(activeLang.classList).find(function(c) {
                        return c.startsWith('menu-language-');
                    });
                    if (cls) {
                        code = cls.replace('menu-language-', '').split('-')[0].toUpperCase();
                    }
                }

                // Replace link content with just the abbreviation
                var caret = langItem.querySelector('.caret');
                langItem.textContent = '';
                langItem.appendChild(document.createTextNode(code));
                if (caret) langItem.appendChild(caret);
            }

            // --- Search on start page ---
            function injectPageSearch() {
                // Only on the tree page (start page)
                if (!document.body.classList.contains('wt-route-TreePage')) return;

                var mainContent = document.querySelector('.wt-main-container .flash-messages');
                if (!mainContent) return;

                var csrf = document.querySelector('meta[name="csrf"]');
                var csrfValue = csrf ? csrf.getAttribute('content') : '';

                // Derive the search action URL from the current tree path
                var path = window.location.pathname;
                var searchAction = path.replace(/\/?$/, '/search-quick');

                var searchDiv = document.createElement('div');
                searchDiv.className = 'bocken-page-search';
                searchDiv.innerHTML =
                    '<form method="post" action="' + searchAction + '" class="bocken-search-form" role="search">' +
                        '<input type="search" class="bocken-search-input" name="query" placeholder="Search names, places, sources..." autocomplete="off">' +
                        '<span class="bocken-search-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32"/><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="m338.29 338.29 105.25 105.25"/></svg></span>' +
                        '<input type="hidden" name="_csrf" value="' + csrfValue + '">' +
                    '</form>';

                mainContent.parentNode.insertBefore(searchDiv, mainContent.nextSibling);
            }

            // --- Separator between primary nav and secondary nav ---
            function injectSeparator() {
                var headerContent = document.querySelector('.wt-header-content');
                var secondaryNav = document.querySelector('.wt-secondary-navigation');
                if (!headerContent || !secondaryNav) return;

                // Walk up to find the direct child of headerContent that contains secondaryNav
                var target = secondaryNav;
                while (target.parentNode && target.parentNode !== headerContent) {
                    target = target.parentNode;
                }
                // If we couldn't walk up to a direct child, bail
                if (target.parentNode !== headerContent) return;

                var spacer = document.createElement('div');
                spacer.className = 'bocken-nav-spacer';
                headerContent.insertBefore(spacer, target);
            }

            // --- Highlight active nav item ---
            function highlightActiveNav() {
                // Map body route classes to nav menu classes
                var routeMap = {
                    'TreePage': 'menu-tree',
                    'Chart': 'menu-chart',
                    'Individual': 'menu-tree',
                    'Family': 'menu-tree',
                    'Branches': 'menu-list',
                    'FamilyList': 'menu-list',
                    'IndividualList': 'menu-list',
                    'MediaList': 'menu-list',
                    'NoteList': 'menu-list',
                    'RepositoryList': 'menu-list',
                    'SourceList': 'menu-list',
                    'PlaceList': 'menu-list',
                    'Calendar': 'menu-calendar',
                    'Report': 'menu-report',
                    'Search': 'menu-search',
                    'Story': 'menu-story',
                    'Faq': 'menu-faq',
                    'Clippings': 'menu-clippings'
                };

                var bodyClasses = document.body.className;
                var activeMenu = null;

                // Find matching route
                var keys = Object.keys(routeMap);
                for (var i = 0; i < keys.length; i++) {
                    if (bodyClasses.indexOf('wt-route-' + keys[i]) !== -1) {
                        activeMenu = routeMap[keys[i]];
                        break;
                    }
                }

                if (!activeMenu) return;

                var navItem = document.querySelector('.wt-primary-navigation .' + activeMenu);
                if (navItem) {
                    navItem.classList.add('bocken-nav-active');
                }
            }

            // --- Init ---
            function init() {
                injectLogo();
                injectSeparator();
                injectToggle();
                shortenLanguage();
                injectPageSearch();
                highlightActiveNav();

                // Init all Lucide icons
                if (typeof lucide !== 'undefined') {
                    lucide.createIcons();
                }
            }

            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', init);
            } else {
                init();
            }
        })();
        </script>
        HTML;
    }

    public function boot(): void
    {
        View::registerNamespace($this->name(), $this->resourcesFolder() . 'views/');

        // Views inherited from ArgonLight
        View::registerCustomView('::modules/block-template', $this->name() . '::modules/block-template');
        View::registerCustomView('::modules/recent_changes/changes-list', $this->name() . '::modules/recent_changes/changes-list');
        View::registerCustomView('::modules/lightbox/tab', $this->name() . '::modules/lightbox/tab');
        View::registerCustomView('::modules/descendancy/sidebar', $this->name() . '::modules/descendancy/sidebar');
        View::registerCustomView('::modules/lifespans-chart/chart', $this->name() . '::modules/lifespans-chart/chart');
        View::registerCustomView('::modules/faq/show', $this->name() . '::modules/faq/show');
        View::registerCustomView('::modules/place-hierarchy/list', $this->name() . '::modules/place-hierarchy/list');
        View::registerCustomView('::lists/individuals-table', $this->name() . '::lists/individuals-table');
        View::registerCustomView('::lists/families-table', $this->name() . '::lists/families-table');
        View::registerCustomView('::individual-page-menu', $this->name() . '::individual-page-menu');
    }
}
