<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}Focomy{% endblock %}</title>
    <script src="https://unpkg.com/htmx.org@1.9.10"></script>
    <style>
        :root {
            --primary: #2563eb;
            --primary-hover: #1d4ed8;
            --bg: #f8fafc;
            --card: #ffffff;
            --text: #1e293b;
            --text-muted: #64748b;
            --border: #e2e8f0;
            --success: #22c55e;
            --error: #ef4444;
            --warning: #f59e0b;
        }

        [data-theme="dark"] {
            --primary: #3b82f6;
            --primary-hover: #2563eb;
            --bg: #0f172a;
            --card: #1e293b;
            --text: #f1f5f9;
            --text-muted: #94a3b8;
            --border: #334155;
            --success: #22c55e;
            --error: #ef4444;
            --warning: #f59e0b;
        }

        * { box-sizing: border-box; margin: 0; padding: 0; }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: var(--bg);
            color: var(--text);
            line-height: 1.6;
        }

        .layout {
            display: grid;
            grid-template-columns: 240px 1fr;
            min-height: 100vh;
        }

        /* Sidebar */
        .sidebar {
            background: var(--card);
            border-right: 1px solid var(--border);
            padding: 1.5rem 0;
        }

        .logo {
            font-size: 1.5rem;
            font-weight: 700;
            padding: 0 1.5rem 1.5rem;
            border-bottom: 1px solid var(--border);
            color: var(--primary);
        }

        .nav { margin-top: 1rem; }

        .nav-section {
            padding: 0.5rem 1.5rem;
            font-size: 0.75rem;
            font-weight: 600;
            text-transform: uppercase;
            color: var(--text-muted);
            letter-spacing: 0.05em;
        }

        .nav-item {
            display: flex;
            align-items: center;
            gap: 0.75rem;
            padding: 0.75rem 1.5rem;
            color: var(--text);
            text-decoration: none;
            transition: background 0.15s;
        }

        .nav-item:hover { background: var(--bg); }
        .nav-item.active { background: var(--bg); color: var(--primary); font-weight: 500; }

        /* Main content */
        .main {
            display: flex;
            flex-direction: column;
        }

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 1rem 2rem;
            background: var(--card);
            border-bottom: 1px solid var(--border);
        }

        .header-title { font-size: 1.25rem; font-weight: 600; }

        .user-menu {
            display: flex;
            align-items: center;
            gap: 0.75rem;
        }

        .user-name { font-weight: 500; }

        .content { padding: 2rem; flex: 1; }

        /* Components */
        .card {
            background: var(--card);
            border-radius: 0.5rem;
            border: 1px solid var(--border);
            padding: 1.5rem;
        }

        .card-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 1rem;
        }

        .card-title { font-size: 1.125rem; font-weight: 600; }

        .btn {
            display: inline-flex;
            align-items: center;
            gap: 0.5rem;
            padding: 0.5rem 1rem;
            border-radius: 0.375rem;
            font-size: 0.875rem;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.15s;
            border: none;
            text-decoration: none;
        }

        .btn-primary {
            background: var(--primary);
            color: white;
        }
        .btn-primary:hover { background: var(--primary-hover); }

        .btn-secondary {
            background: transparent;
            color: var(--text);
            border: 1px solid var(--border);
        }
        .btn-secondary:hover { background: var(--bg); }

        .btn-danger {
            background: var(--error);
            color: white;
        }
        .btn-danger:hover { opacity: 0.9; }

        /* Table */
        .table-container { overflow-x: auto; }

        table {
            width: 100%;
            border-collapse: collapse;
        }

        th, td {
            padding: 0.75rem 1rem;
            text-align: left;
            border-bottom: 1px solid var(--border);
        }

        th {
            font-weight: 600;
            font-size: 0.75rem;
            text-transform: uppercase;
            color: var(--text-muted);
            letter-spacing: 0.05em;
        }

        tr:hover { background: var(--bg); }

        /* Forms */
        .form-group { margin-bottom: 1.25rem; }

        .form-label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: 500;
            font-size: 0.875rem;
        }

        .form-input, .form-select, .form-textarea {
            width: 100%;
            padding: 0.625rem 0.875rem;
            border: 1px solid var(--border);
            border-radius: 0.375rem;
            font-size: 0.875rem;
            transition: border-color 0.15s;
        }

        .form-input:focus, .form-select:focus, .form-textarea:focus {
            outline: none;
            border-color: var(--primary);
        }

        .form-textarea { min-height: 120px; resize: vertical; }

        .form-hint {
            margin-top: 0.375rem;
            font-size: 0.75rem;
            color: var(--text-muted);
        }

        .form-error {
            margin-top: 0.375rem;
            font-size: 0.75rem;
            color: var(--error);
        }

        /* Grid */
        .grid { display: grid; gap: 1.5rem; }
        .grid-2 { grid-template-columns: repeat(2, 1fr); }
        .grid-3 { grid-template-columns: repeat(3, 1fr); }
        .grid-4 { grid-template-columns: repeat(4, 1fr); }

        /* Stats */
        .stat-card {
            background: var(--card);
            border: 1px solid var(--border);
            border-radius: 0.5rem;
            padding: 1.25rem;
        }

        .stat-label {
            font-size: 0.75rem;
            text-transform: uppercase;
            color: var(--text-muted);
            letter-spacing: 0.05em;
        }

        .stat-value {
            font-size: 2rem;
            font-weight: 700;
            margin-top: 0.25rem;
        }

        /* Badge */
        .badge {
            display: inline-block;
            padding: 0.25rem 0.5rem;
            border-radius: 9999px;
            font-size: 0.75rem;
            font-weight: 500;
        }

        .badge-success { background: #dcfce7; color: #166534; }
        .badge-warning { background: #fef3c7; color: #92400e; }
        .badge-error { background: #fee2e2; color: #991b1b; }
        .badge-info { background: #dbeafe; color: #1e40af; }

        /* Alert */
        .alert {
            padding: 1rem;
            border-radius: 0.5rem;
            margin-bottom: 1rem;
        }

        .alert-success { background: #dcfce7; color: #166534; }
        .alert-error { background: #fee2e2; color: #991b1b; }
        .alert-warning { background: #fef3c7; color: #92400e; }
        .alert-info { background: #dbeafe; color: #1e40af; }

        /* HTMX indicators */
        .htmx-indicator { display: none; }
        .htmx-request .htmx-indicator { display: inline-block; }
        .htmx-request.htmx-indicator { display: inline-block; }

        /* Login page */
        .login-container {
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            background: var(--bg);
        }

        .login-card {
            width: 100%;
            max-width: 400px;
            background: var(--card);
            border-radius: 0.5rem;
            border: 1px solid var(--border);
            padding: 2rem;
        }

        .login-logo {
            text-align: center;
            font-size: 2rem;
            font-weight: 700;
            color: var(--primary);
            margin-bottom: 2rem;
        }

        /* Filter Bar */
        .filter-bar {
            display: flex;
            align-items: center;
            gap: 1rem;
            margin-bottom: 1rem;
            padding-bottom: 1rem;
            border-bottom: 1px solid var(--border);
        }

        .filter-form {
            display: flex;
            align-items: center;
            gap: 1rem;
            flex-wrap: wrap;
        }

        .search-box {
            display: flex;
            gap: 0.5rem;
        }

        .filter-group {
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .input {
            padding: 0.5rem 0.75rem;
            border: 1px solid var(--border);
            border-radius: 0.375rem;
            font-size: 0.875rem;
            transition: border-color 0.15s;
        }

        .input:focus {
            outline: none;
            border-color: var(--primary);
        }

        .btn-ghost {
            background: transparent;
            color: var(--text-muted);
            border: none;
            padding: 0.5rem 0.75rem;
        }

        .btn-ghost:hover {
            color: var(--text);
        }

        /* Bulk Actions */
        .bulk-actions {
            display: flex;
            align-items: center;
            gap: 1rem;
            padding: 0.75rem 1rem;
            background: var(--bg);
            border-radius: 0.375rem;
            margin-bottom: 1rem;
        }

        .bulk-count {
            font-weight: 500;
            font-size: 0.875rem;
        }

        .bulk-form {
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .checkbox-col {
            width: 40px;
            text-align: center;
        }

        /* Toast Notifications */
        .toast-container {
            position: fixed;
            top: 1rem;
            right: 1rem;
            z-index: 1000;
            display: flex;
            flex-direction: column;
            gap: 0.5rem;
        }

        .toast {
            padding: 1rem 1.5rem;
            border-radius: 0.5rem;
            background: var(--card);
            border: 1px solid var(--border);
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
            display: flex;
            align-items: center;
            gap: 0.75rem;
            max-width: 400px;
            animation: slideIn 0.3s ease-out;
        }

        .toast.toast-success {
            border-left: 4px solid var(--success);
        }

        .toast.toast-error {
            border-left: 4px solid var(--error);
        }

        .toast.toast-warning {
            border-left: 4px solid var(--warning);
        }

        .toast-message {
            flex: 1;
            font-size: 0.875rem;
        }

        .toast-close {
            background: none;
            border: none;
            cursor: pointer;
            color: var(--text-muted);
            font-size: 1.25rem;
            line-height: 1;
            padding: 0;
        }

        .toast-close:hover {
            color: var(--text);
        }

        @keyframes slideIn {
            from {
                transform: translateX(100%);
                opacity: 0;
            }
            to {
                transform: translateX(0);
                opacity: 1;
            }
        }

        @keyframes fadeOut {
            from {
                opacity: 1;
            }
            to {
                opacity: 0;
            }
        }

        /* Utility */
        .text-muted { color: var(--text-muted); }
        .text-center { text-align: center; }
        .mt-1 { margin-top: 0.5rem; }
        .mt-2 { margin-top: 1rem; }
        .mt-4 { margin-top: 2rem; }
        .mb-2 { margin-bottom: 1rem; }
        .flex { display: flex; }
        .gap-2 { gap: 0.5rem; }
        .justify-between { justify-content: space-between; }
        .items-center { align-items: center; }

        /* Theme Toggle */
        .theme-toggle {
            background: transparent;
            border: 1px solid var(--border);
            border-radius: 0.375rem;
            padding: 0.5rem;
            cursor: pointer;
            color: var(--text-muted);
            font-size: 1.25rem;
            line-height: 1;
            transition: all 0.15s;
        }

        .theme-toggle:hover {
            color: var(--text);
            background: var(--bg);
        }
    </style>
</head>
<body>
    <!-- Toast Container -->
    <div id="toast-container" class="toast-container"></div>

    {% block body %}
    <div class="layout">
        <aside class="sidebar">
            <div class="logo">Focomy</div>
            <a href="/" target="_blank" class="nav-item" style="border-bottom: 1px solid var(--border); margin-bottom: 0.5rem;">
                サイトを表示 ↗
            </a>
            <nav class="nav">
                <a href="/admin" class="nav-item {% if current_page == 'dashboard' %}active{% endif %}">
                    ダッシュボード
                </a>

                <div class="nav-section">コンテンツ</div>
                {# 動的メニュー生成: admin_menu=true のcontent_typesを表示 #}
                {% set sidebar_exclude = ['channel', 'post', 'comment', 'user', 'media', 'menu_item', 'widget', 'audit_log', 'form_submission', 'site_setting', 'edit_lock', 'redirect', 'scheduled_action', 'workflow_history', 'plugin', 'plugin_developer', 'plugin_review', 'category'] %}
                {% for name, ct in content_types.items()|sort(attribute='0') %}
                    {% if ct.admin_menu and name not in sidebar_exclude %}
                <a href="/admin/{{ name }}" class="nav-item {% if current_page == name %}active{% endif %}">
                    {{ ct.label_plural or ct.label or name }}
                </a>
                    {% endif %}
                {% endfor %}

                {% if channels %}
                <div class="nav-section">チャンネル</div>
                <a href="/admin/channel" class="nav-item {% if current_page == 'channel' %}active{% endif %}">
                    チャンネル管理
                </a>
                {% for ch in channels %}
                <a href="{{ AdminURL.entity_list('post', ch.slug) }}" class="nav-item nav-item-sub {% if channel_slug == ch.slug %}active{% endif %}">
                    {{ ch.title }}
                </a>
                {% endfor %}
                {% if orphan_post_count > 0 %}
                <a href="/admin/posts/orphan" class="nav-item nav-item-sub {% if is_orphan_view %}active{% endif %}" style="color: var(--warning);">
                    未分類 ({{ orphan_post_count }})
                </a>
                {% endif %}
                {% else %}
                <div class="nav-section">チャンネル</div>
                <a href="/admin/channel" class="nav-item {% if current_page == 'channel' %}active{% endif %}">
                    チャンネル管理
                </a>
                {% endif %}
                <a href="/admin/media" class="nav-item {% if current_page == 'media' %}active{% endif %}">
                    メディア
                </a>
                <a href="/admin/comments" class="nav-item {% if current_page == 'comments' %}active{% endif %}">
                    コメント
                    {% if pending_comment_count %}<span class="badge">{{ pending_comment_count }}</span>{% endif %}
                </a>

                <div class="nav-section">外観</div>
                <a href="/admin/themes/{{ active_theme }}/customize" class="nav-item {% if current_page == 'customize' %}active{% endif %}">
                    カスタマイズ
                </a>
                <a href="/admin/themes" class="nav-item {% if current_page == 'themes' %}active{% endif %}">
                    テーマ
                </a>
                <a href="/admin/menus" class="nav-item {% if current_page == 'menus' %}active{% endif %}">
                    メニュー
                </a>
                <a href="/admin/widgets" class="nav-item {% if current_page == 'widgets' %}active{% endif %}">
                    ウィジェット
                </a>

                <div class="nav-section">設定</div>
                <a href="/admin/user" class="nav-item {% if current_page == 'user' %}active{% endif %}">
                    ユーザー
                </a>
                <a href="/admin/settings" class="nav-item {% if current_page == 'settings' %}active{% endif %}">
                    サイト設定
                </a>
                <a href="/admin/redirects" class="nav-item {% if current_page == 'redirects' %}active{% endif %}">
                    リダイレクト
                </a>

                <div class="nav-section">ツール</div>
                <a href="/admin/tools/sitemap" class="nav-item {% if current_page == 'tools' and 'sitemap' in request.url.path %}active{% endif %}">
                    サイトマップ
                </a>
                <a href="/admin/tools/link-validator" class="nav-item {% if current_page == 'tools' and 'link-validator' in request.url.path %}active{% endif %}">
                    リンク検証
                </a>
                <a href="/admin/import" class="nav-item {% if current_page == 'import' %}active{% endif %}">
                    インポート
                </a>
                <a href="/admin/system" class="nav-item {% if current_page == 'system' %}active{% endif %}">
                    システム情報
                    <span id="update-badge" class="badge" style="display: none;">NEW</span>
                </a>
            </nav>
            <script>
                // Check for updates on page load
                fetch('/admin/api/update-check')
                    .then(r => r.json())
                    .then(data => {
                        if (data.has_update) {
                            document.getElementById('update-badge').style.display = 'inline';
                        }
                    })
                    .catch(() => {});
            </script>
        </aside>

        <main class="main">
            <header class="header">
                <h1 class="header-title">{% block header_title %}ダッシュボード{% endblock %}</h1>
                <div class="user-menu">
                    <button class="theme-toggle" id="theme-toggle" title="ダークモード切替">
                        <span id="theme-icon">🌙</span>
                    </button>
                    <span class="user-name">{{ current_user.name if current_user else 'ゲスト' }}</span>
                    <a href="/admin/logout" class="btn btn-secondary">ログアウト</a>
                </div>
            </header>

            <div class="content">
                {% block content %}{% endblock %}
            </div>
        </main>
    </div>
    {% endblock %}

    <script>
    // Toast notification system
    const Toast = {
        container: document.getElementById('toast-container'),

        show(message, type = 'success', duration = 5000) {
            const toast = document.createElement('div');
            toast.className = `toast toast-${type}`;
            toast.innerHTML = `
                <span class="toast-message">${message}</span>
                <button class="toast-close" onclick="this.parentElement.remove()">&times;</button>
            `;
            this.container.appendChild(toast);

            // Auto dismiss
            if (duration > 0) {
                setTimeout(() => {
                    toast.style.animation = 'fadeOut 0.3s ease-out forwards';
                    setTimeout(() => toast.remove(), 300);
                }, duration);
            }
        },

        success(message) {
            this.show(message, 'success');
        },

        error(message) {
            this.show(message, 'error');
        },

        warning(message) {
            this.show(message, 'warning');
        }
    };

    // Show flash messages from URL params
    document.addEventListener('DOMContentLoaded', function() {
        const params = new URLSearchParams(window.location.search);
        const message = params.get('message');
        if (message) {
            Toast.success(decodeURIComponent(message.replace(/\+/g, ' ')));
            // Clean URL
            const url = new URL(window.location);
            url.searchParams.delete('message');
            window.history.replaceState({}, '', url);
        }

        const error = params.get('error');
        if (error) {
            Toast.error(decodeURIComponent(error.replace(/\+/g, ' ')));
            const url = new URL(window.location);
            url.searchParams.delete('error');
            window.history.replaceState({}, '', url);
        }
    });

    // HTMX request handler for toast notifications
    document.body.addEventListener('htmx:afterRequest', function(evt) {
        const xhr = evt.detail.xhr;
        const verb = evt.detail.requestConfig.verb;

        if (evt.detail.successful && xhr.status === 200) {
            // Success - check for delete operations
            if (verb === 'delete') {
                Toast.success('Item deleted successfully');
            }
        } else if (xhr.status >= 400) {
            // Error - show response text as error message
            const errorMsg = xhr.responseText || 'An error occurred';
            Toast.error(errorMsg);
            // Prevent HTMX from swapping content on error
            evt.detail.shouldSwap = false;
        }
    });

    // Theme toggle
    const ThemeManager = {
        init() {
            const saved = localStorage.getItem('theme');
            if (saved) {
                this.setTheme(saved);
            } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
                this.setTheme('dark');
            }

            document.getElementById('theme-toggle')?.addEventListener('click', () => {
                const current = document.documentElement.getAttribute('data-theme');
                this.setTheme(current === 'dark' ? 'light' : 'dark');
            });
        },

        setTheme(theme) {
            document.documentElement.setAttribute('data-theme', theme);
            localStorage.setItem('theme', theme);
            const icon = document.getElementById('theme-icon');
            if (icon) {
                icon.textContent = theme === 'dark' ? '☀️' : '🌙';
            }
        }
    };

    ThemeManager.init();

    // Keyboard shortcuts
    document.addEventListener('keydown', function(e) {
        // Ctrl+S or Cmd+S - Save
        if ((e.ctrlKey || e.metaKey) && e.key === 's') {
            const form = document.querySelector('form');
            const submitBtn = form?.querySelector('button[type="submit"]');
            if (submitBtn) {
                e.preventDefault();
                submitBtn.click();
            }
        }

        // / - Focus search
        if (e.key === '/' && !['INPUT', 'TEXTAREA', 'SELECT'].includes(document.activeElement.tagName)) {
            const searchInput = document.querySelector('input[name="q"]');
            if (searchInput) {
                e.preventDefault();
                searchInput.focus();
            }
        }

        // Escape - Cancel/Close
        if (e.key === 'Escape') {
            const cancelBtn = document.querySelector('a.btn-secondary[href*="/admin/"]');
            if (cancelBtn && document.querySelector('form')) {
                cancelBtn.click();
            }
        }
    });
    </script>
</body>
</html>
