"""HTML templates for the web UI."""


def get_index_html() -> str:
    """Get the main index page HTML."""
    return """
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>NoticeCard Manager</title>
    <link href="https://cdn.jsdelivr.net/npm/@tabler/core@1.0.0-beta17/dist/css/tabler.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css" rel="stylesheet">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary: #3b82f6;
            --primary-hover: #2563eb;
            --secondary: #8b5cf6;
            --success: #10b981;
            --danger: #ef4444;
            --bg-light: #f8fafc;
            --text-dark: #0f172a;
            --text-muted: #475569;
            --border: #e2e8f0;
        }
        
        * {
            font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, sans-serif;
        }
        
        h1, h2, h3, h4, h5, h6, .heading {
            font-family: 'Poppins', -apple-system, BlinkMacSystemFont, sans-serif;
            font-weight: 600;
        }
        
        body {
            background: var(--bg-light);
            color: var(--text-dark);
        }
        
        .card-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
            gap: 1.5rem;
            margin-top: 1.5rem;
        }
        
        @media (max-width: 768px) {
            .card-grid {
                grid-template-columns: 1fr;
                gap: 1rem;
            }
        }
        
        .loading {
            text-align: center;
            padding: 3rem;
        }
        
        .notice-card {
            background: white;
            border: 1px solid var(--border);
            border-radius: 12px;
            transition: all 0.2s ease-out;
            cursor: default;
        }
        
        .notice-card:hover {
            box-shadow: 0 4px 12px rgba(59, 130, 246, 0.1);
            border-color: var(--primary);
        }
        
        .btn-primary {
            background: var(--primary);
            border-color: var(--primary);
            transition: all 0.2s ease-out;
        }
        
        .btn-primary:hover {
            background: var(--primary-hover);
            border-color: var(--primary-hover);
            transform: translateY(-1px);
        }
        
        .btn-icon {
            transition: all 0.2s ease-out;
            cursor: pointer;
        }
        
        .btn-icon:hover {
            transform: scale(1.05);
        }
        
        .navbar {
            background: white;
            border-bottom: 1px solid var(--border);
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
        }
        
        .empty-state {
            padding: 4rem 2rem;
            text-align: center;
        }
        
        .empty-icon {
            font-size: 4rem;
            color: var(--text-muted);
            opacity: 0.5;
        }
        
        @media (prefers-reduced-motion: reduce) {
            *, *::before, *::after {
                animation-duration: 0.01ms !important;
                animation-iteration-count: 1 !important;
                transition-duration: 0.01ms !important;
            }
        }
    </style>
</head>
<body>
    <div class="page">
        <header class="navbar navbar-expand-md navbar-light d-print-none" role="banner">
            <div class="container-xl">
                <h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3 heading">
                    <a href="/" aria-label="NoticeCard Manager 首页">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon" aria-hidden="true">
                            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                            <polyline points="14 2 14 8 20 8"></polyline>
                            <line x1="16" y1="13" x2="8" y2="13"></line>
                            <line x1="16" y1="17" x2="8" y2="17"></line>
                            <polyline points="10 9 9 9 8 9"></polyline>
                        </svg>
                        <span class="ms-2">NoticeCard Manager</span>
                    </a>
                </h1>
                <div class="navbar-nav flex-row order-md-last">
                    <a href="/docs" class="btn btn-primary" target="_blank" rel="noopener noreferrer" aria-label="查看 API 文档">
                        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-1" aria-hidden="true">
                            <circle cx="12" cy="12" r="10"></circle>
                            <line x1="2" y1="12" x2="22" y2="12"></line>
                            <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
                        </svg>
                        API 文档
                    </a>
                </div>
            </div>
        </header>
        
        <div class="page-wrapper">
            <div class="page-body">
                <div class="container-xl">
                    <div class="row mb-4">
                        <div class="col">
                            <button class="btn btn-primary" onclick="showCreateModal()" aria-label="新建卡片">
                                <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-1" aria-hidden="true">
                                    <line x1="12" y1="5" x2="12" y2="19"></line>
                                    <line x1="5" y1="12" x2="19" y2="12"></line>
                                </svg>
                                新建卡片
                            </button>
                        </div>
                    </div>
                    
                    <div id="cards-container" class="card-grid" role="list" aria-label="卡片列表">
                        <div class="loading" role="status" aria-live="polite">
                            <div class="spinner-border text-primary" aria-hidden="true"></div>
                            <p class="mt-2">加载中...</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- Create/Edit Modal -->
    <div class="modal modal-blur fade" id="cardModal" tabindex="-1" role="dialog" aria-labelledby="modalTitle" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title heading" id="modalTitle">新建卡片</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭对话框"></button>
                </div>
                <div class="modal-body">
                    <form id="cardForm" novalidate>
                        <input type="hidden" id="cardId" aria-hidden="true">
                        <div class="mb-3">
                            <label for="title" class="form-label required">标题</label>
                            <input type="text" class="form-control" id="title" name="title" required maxlength="200" aria-required="true" aria-describedby="titleHint">
                            <small id="titleHint" class="form-hint">必填，最多200字符</small>
                        </div>
                        <div class="mb-3">
                            <label for="description" class="form-label">描述</label>
                            <textarea class="form-control" id="description" name="description" rows="4" maxlength="1000" aria-describedby="descriptionHint"></textarea>
                            <small id="descriptionHint" class="form-hint">可选，最多1000字符</small>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn" data-bs-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-primary" onclick="saveCard()" aria-label="保存卡片">
                        <span class="spinner-border spinner-border-sm me-2 d-none" id="saveSpinner" role="status" aria-hidden="true"></span>
                        保存
                    </button>
                </div>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/@tabler/core@1.0.0-beta17/dist/js/tabler.min.js"></script>
    <script>
        let modal;
        
        document.addEventListener('DOMContentLoaded', function() {
            modal = new bootstrap.Modal(document.getElementById('cardModal'));
            loadCards();
        });
        
        async function loadCards() {
            try {
                const response = await fetch('/cards/');
                if (!response.ok) throw new Error('Failed to load cards');
                const cards = await response.json();
                displayCards(cards);
            } catch (error) {
                console.error('Error loading cards:', error);
                showError('加载卡片失败，请刷新页面重试');
            }
        }
        
        function displayCards(cards) {
            const container = document.getElementById('cards-container');
            if (cards.length === 0) {
                container.innerHTML = `
                    <div class="empty-state" role="status">
                        <div class="empty-icon" aria-hidden="true">
                            <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                                <polyline points="14 2 14 8 20 8"></polyline>
                                <line x1="16" y1="13" x2="8" y2="13"></line>
                                <line x1="16" y1="17" x2="8" y2="17"></line>
                            </svg>
                        </div>
                        <h3 class="heading mt-3">暂无卡片</h3>
                        <p class="text-muted">点击"新建卡片"按钮创建第一张卡片</p>
                    </div>
                `;
                return;
            }
            
            container.innerHTML = cards.map(card => `
                <article class="notice-card" data-card-id="${card.id}" role="listitem">
                    <div class="card-body">
                        <h3 class="card-title heading">${escapeHtml(card.title)}</h3>
                        ${card.description ? `<p class="text-muted mb-0">${escapeHtml(card.description)}</p>` : ''}
                    </div>
                    <div class="card-footer">
                        <div class="d-flex justify-content-between align-items-center">
                            <small class="text-muted" title="创建时间: ${new Date(card.created_at).toLocaleString('zh-CN')}">
                                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-1" aria-hidden="true">
                                    <circle cx="12" cy="12" r="10"></circle>
                                    <polyline points="12 6 12 12 16 14"></polyline>
                                </svg>
                                ${formatRelativeTime(card.created_at)}
                            </small>
                            <div class="btn-group" role="group" aria-label="卡片操作">
                                <button class="btn btn-sm btn-primary btn-icon" onclick="editCard(${card.id})" aria-label="编辑卡片 ${escapeHtml(card.title)}">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                                        <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
                                        <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
                                    </svg>
                                </button>
                                <button class="btn btn-sm btn-danger btn-icon" onclick="deleteCard(${card.id})" aria-label="删除卡片 ${escapeHtml(card.title)}">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                                        <polyline points="3 6 5 6 21 6"></polyline>
                                        <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
                                    </svg>
                                </button>
                            </div>
                        </div>
                    </div>
                </article>
            `).join('');
        }
        
        function showCreateModal() {
            document.getElementById('modalTitle').textContent = '新建卡片';
            document.getElementById('cardForm').reset();
            document.getElementById('cardId').value = '';
            modal.show();
        }
        
        async function editCard(id) {
            try {
                const response = await fetch(`/cards/${id}`);
                if (!response.ok) throw new Error('Failed to load card');
                const card = await response.json();
                
                document.getElementById('modalTitle').textContent = '编辑卡片';
                document.getElementById('cardId').value = card.id;
                document.getElementById('title').value = card.title;
                document.getElementById('description').value = card.description || '';
                
                modal.show();
            } catch (error) {
                console.error('Error loading card:', error);
                showError('加载卡片失败');
            }
        }
        
        async function saveCard() {
            const titleInput = document.getElementById('title');
            if (!titleInput.value.trim()) {
                titleInput.focus();
                showError('标题不能为空');
                return;
            }
            
            const id = document.getElementById('cardId').value;
            const data = {
                title: document.getElementById('title').value.trim(),
                description: document.getElementById('description').value.trim() || null
            };
            
            const spinner = document.getElementById('saveSpinner');
            spinner.classList.remove('d-none');
            
            try {
                const url = id ? `/cards/${id}` : '/cards/';
                const method = id ? 'PUT' : 'POST';
                
                const response = await fetch(url, {
                    method: method,
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify(data)
                });
                
                if (!response.ok) {
                    const error = await response.json();
                    throw new Error(error.detail || 'Failed to save card');
                }
                
                modal.hide();
                await loadCards();
                showSuccess(id ? '卡片更新成功' : '卡片创建成功');
            } catch (error) {
                console.error('Error saving card:', error);
                showError(error.message || '保存失败');
            } finally {
                spinner.classList.add('d-none');
            }
        }
        
        async function deleteCard(id) {
            if (!confirm('确定要删除这张卡片吗？此操作无法撤销。')) return;
            
            try {
                const response = await fetch(`/cards/${id}`, {method: 'DELETE'});
                if (!response.ok) throw new Error('Failed to delete card');
                
                await loadCards();
                showSuccess('卡片删除成功');
            } catch (error) {
                console.error('Error deleting card:', error);
                showError('删除失败');
            }
        }
        
        function escapeHtml(text) {
            if (!text) return '';
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }
        
        function formatRelativeTime(dateString) {
            const date = new Date(dateString);
            const now = new Date();
            const diffMs = now - date;
            const diffMins = Math.floor(diffMs / 60000);
            const diffHours = Math.floor(diffMs / 3600000);
            const diffDays = Math.floor(diffMs / 86400000);
            
            if (diffMins < 1) return '刚刚';
            if (diffMins < 60) return `${diffMins}分钟前`;
            if (diffHours < 24) return `${diffHours}小时前`;
            if (diffDays < 7) return `${diffDays}天前`;
            return date.toLocaleDateString('zh-CN');
        }
        
        function showError(message) {
            // Simple alert for now, could be replaced with toast notifications
            alert('❌ ' + message);
        }
        
        function showSuccess(message) {
            // Simple alert for now, could be replaced with toast notifications
            console.log('✅ ' + message);
        }
    </script>
</body>
</html>
    """
