<?php
if (!defined('__TYPECHO_ROOT_DIR__'))
    exit;

/**
 * SimpleAdmin Pro - 仪表盘增强版
 * 在原版基础上深度整合数据可视化仪表盘系统
 * 
 * @package SimpleAdmin
 * @author gogobody (原作者)
 * @author Y.H.2HANG (二开增强) - https://www.habits.top
 * @version 2.0.0
 * @link https://www.ijkxs.com
 */
class SimpleAdmin_Plugin implements Typecho_Plugin_Interface
{
    public static function activate()
    {
        if (version_compare(phpversion(), '7.0.0', '<')) {
            throw new Typecho_Plugin_Exception('请升级到 php 7 以上');
        }
        Typecho_Plugin::factory('admin/header.php')->header_1000 = array('SimpleAdmin_Plugin', 'renderHeader');
        Typecho_Plugin::factory('admin/footer.php')->end_1000 = array('SimpleAdmin_Plugin', 'renderFooter');

        if (file_exists("var/Widget/Menu.php")) {
            @rename("var/Widget/Menu.php", "var/Widget/Menu.php.bak");
            @copy("usr/plugins/SimpleAdmin/var/Widget/Menu.php", "var/Widget/Menu.php");
        }
        if (file_exists("admin/header.php")) {
            @rename("admin/header.php", "admin/header.php.bak");
            @copy("usr/plugins/SimpleAdmin/admin/header.php", "admin/header.php");
        }

        // 删除旧版本的数据统计菜单项（Pro版已集成到首页仪表盘）
        self::removeOldStatsMenu();
    }

    public static function deactivate()
    {
        if (file_exists("var/Widget/Menu.php.bak")) {
            @unlink("var/Widget/Menu.php");
            @rename("var/Widget/Menu.php.bak", "var/Widget/Menu.php");
        }
        if (file_exists("admin/header.php.bak")) {
            @unlink("admin/header.php");
            @rename("admin/header.php.bak", "admin/header.php");
        }
    }

    /**
     * 删除旧版本的数据统计菜单项
     * Pro版已将所有统计功能集成到首页仪表盘
     */
    private static function removeOldStatsMenu()
    {
        $db = Typecho_Db::get();
        $options = Helper::options();

        // 获取当前的 panelTable
        $panelTable = unserialize($options->panelTable);

        if (!empty($panelTable) && is_array($panelTable)) {
            $modified = false;

            // 删除父菜单中的数据统计项
            if (isset($panelTable['parent'])) {
                foreach ($panelTable['parent'] as $key => $value) {
                    if (strpos($value, '数据统计') !== false || strpos($value, 'Stats') !== false) {
                        unset($panelTable['parent'][$key]);
                        $modified = true;
                    }
                }
            }

            // 删除子菜单中的数据统计项
            if (isset($panelTable['child'])) {
                foreach ($panelTable['child'] as $parentKey => $children) {
                    if (is_array($children)) {
                        foreach ($children as $childKey => $child) {
                            if (
                                is_array($child) && (
                                    (isset($child[0]) && (strpos($child[0], '数据统计') !== false || strpos($child[0], 'Stats') !== false)) ||
                                    (isset($child[2]) && strpos($child[2], 'stats.php') !== false)
                                )
                            ) {
                                unset($panelTable['child'][$parentKey][$childKey]);
                                $modified = true;
                            }
                        }
                    }
                }
            }

            // 如果有修改，更新数据库
            if ($modified) {
                $db->query($db->update('table.options')
                    ->rows(array('value' => serialize($panelTable)))
                    ->where('name = ?', 'panelTable'));
            }
        }
    }

    public static function config(Typecho_Widget_Helper_Form $form)
    {
        $options = Helper::options();
        $url = $options->pluginUrl . '/SimpleAdmin/static';
        ?>
        <link rel="stylesheet" href="<?php echo $url . '/css/login.min.css' ?>">
        <?php
        $zz = ['suya' => '素雅山水', 'BlueSkyAndMountains' => '蓝天群山', 'Earlyspringimpression' => '早春印象', 'MarineGiant' => '海洋巨人', 'lv' => '绿意之方', 'black' => '暗之色系', 'white' => '亮之色系', 'heike' => '黑客帝国', 'mohu' => '高斯模糊', 'kongbai' => '空白样式'];
        $form->addInput(new Typecho_Widget_Helper_Form_Element_Radio('bgfengge', array_map(function ($v, $k) use ($url) {
            return _t('<div class="kuai"><img src="' . $url . '/images/' . $k . '.jpg"><div class="zz">' . $v . '</div></div>');
        }, $zz, array_keys($zz)), 'suya', _t('登陆页面样式')));
        $form->addInput(new Typecho_Widget_Helper_Form_Element_Text('bgUrl', NULL, NULL, _t('自定义背景图')));
        $form->addInput(new Typecho_Widget_Helper_Form_Element_Text('beginDate', NULL, '2020-01-01', _t('建站日期'), _t('格式：YYYY-MM-DD')));
        $form->addInput(new Typecho_Widget_Helper_Form_Element_Text('avatar', NULL, NULL, _t('侧边栏头像')));
        $form->addInput(new Typecho_Widget_Helper_Form_Element_Textarea('diyadmincss', NULL, NULL, '自定义后台 CSS'));
    }

    public static function personalConfig(Typecho_Widget_Helper_Form $form)
    {
    }

    public static function renderHeader($hed, $new)
    {
        $hed = !empty($new) ? $new : $hed;
        $url = Helper::options()->pluginUrl . '/SimpleAdmin/static/';
        $options = Helper::options();
        $plugin_options = Helper::options()->plugin('SimpleAdmin');

        if (!Typecho_Widget::widget('Widget_User')->hasLogin()) {
            $skin = $plugin_options->bgfengge;
            if ($skin == 'kongbai') {
                $hed .= '<style>' . $plugin_options->diycss . '</style>';
            } else {
                $bgUrl = $plugin_options->bgUrl;
                $zidingyi = $bgUrl ? "<style>body,body::before{background-image: url(" . $bgUrl . ")}</style>" : "";
                $hed .= '<link rel="stylesheet" href="' . $url . 'skin/' . $skin . '.css?20191125">' . $zidingyi;
            }
            echo $hed;
        } else {
            $user = Typecho_Widget::widget('Widget_User');
            $menu = Typecho_Widget::widget('Widget_Menu');
            $tx = $user->mail ? (strstr(strtolower($user->mail), "qq.com") && is_numeric(str_replace('@qq.com', '', strtolower($user->mail))) ? '//q1.qlogo.cn/g?b=qq&nk=' . str_replace('@qq.com', '', strtolower($user->mail)) . '&' : '//cdn.v2ex.com/gravatar/' . md5(strtolower($user->mail)) . '?') : ($url . 'img/user.png?');
            $avatar = empty($plugin_options->avatar) ? ($tx . 's=100') : $plugin_options->avatar;

            $hed .= '<link rel="stylesheet" href="' . $url . 'css/user.min.css">
            <script>
                const UserLink_="' . $options->adminUrl . 'profile.php";
                const UserPic_="' . $avatar . '";
                const AdminLink_="' . $options->adminUrl . '";
                const SiteLink_="' . $options->siteUrl . '";
                const UserName_="' . $user->screenName . '";
                const UserGroup_="' . $user->group . '";
                const SiteName_="' . $options->title . '";
                const MenuTitle_="' . strip_tags($menu->title) . '";
                const globalConfig = {theme:"' . $options->theme . '",write_post:"' . $options->adminUrl . 'write-post.php' . '",themes:"' . $options->adminUrl . 'themes.php' . '",plugins:"' . $options->adminUrl . 'plugins.php' . '",manage_posts:"' . $options->adminUrl . 'manage-posts.php' . '"};
            </script>';

            $path = $_SERVER['SCRIPT_NAME'];
            if ($path == '/admin/index.php' || ($path == '/admin/' && !$_SERVER['QUERY_STRING'])) {
                $hed .= self::getStatsInjections($plugin_options);
            }
            $hed .= '<style>' . $plugin_options->diyadmincss . '</style>';
        }
        return $hed;
    }

    private static function getStatsInjections($plugin_options)
    {
        $db = Typecho_Db::get();
        $beginDate = isset($plugin_options->beginDate) ? $plugin_options->beginDate : '2020-01-01';
        $recordedDays = floor((time() - strtotime($beginDate)) / 86400);
        $postsCount = $db->fetchObject($db->select('COUNT(*) AS count')->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish'))->count;
        $commentsCount = $db->fetchObject($db->select('COUNT(*) AS count')->from('table.comments')->where('status = ?', 'approved'))->count;
        $postsRes = $db->fetchAll($db->select('text')->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish'));
        $totalWords = 0;
        foreach ($postsRes as $p) {
            $totalWords += mb_strlen(strip_tags($p['text']), 'UTF-8');
        }
        $displayWords = $totalWords > 10000 ? round($totalWords / 10000, 1) . 'w' : $totalWords;

        $allPostsRaw = $db->fetchAll($db->select('created')->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish'));
        $heatmapYearly = [];
        foreach ($allPostsRaw as $row) {
            $y = date('Y', $row['created']);
            $d = date('Y-m-d', $row['created']);
            if (!isset($heatmapYearly[$y]))
                $heatmapYearly[$y] = [];
            $heatmapYearly[$y][$d] = ($heatmapYearly[$y][$d] ?? 0) + 1;
        }
        $heatmapData = [];
        foreach ($heatmapYearly as $yr => $data) {
            $tmp = [];
            foreach ($data as $d => $c) {
                $tmp[] = [$d, $c];
            }
            $heatmapData[$yr] = $tmp;
        }
        $years = array_keys($heatmapData);
        rsort($years);
        $currentYear = !empty($years) ? $years[0] : date('Y');

        $metas = $db->fetchAll($db->select('name', 'count')->from('table.metas')->where('type = ?', 'category'));
        $categoryJson = [];
        foreach ($metas as $m) {
            if ($m['count'] > 0)
                $categoryJson[] = ['name' => $m['name'], 'value' => (int) $m['count']];
        }

        $hoursDistrib = array_fill(0, 24, 0);
        foreach ($allPostsRaw as $row) {
            $h = (int) date('G', $row['created']);
            if ($h >= 0 && $h < 24)
                $hoursDistrib[$h]++;
        }

        $viewField = 'commentsNum';
        try {
            $db->fetchRow($db->select('views')->from('table.contents')->limit(1));
            $viewField = 'views';
        } catch (Exception $e) {
            try {
                $db->fetchRow($db->select('viewsNum')->from('table.contents')->limit(1));
                $viewField = 'viewsNum';
            } catch (Exception $e2) {
            }
        }

        $topViews = $db->fetchAll($db->select('title', 'cid', $viewField)->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish')->order($viewField, Typecho_Db::SORT_DESC)->limit(10));
        $recentComments = $db->fetchAll($db->select('author', 'text', 'cid', 'created')->from('table.comments')->where('status = ?', 'approved')->order('created', Typecho_Db::SORT_DESC)->limit(10));
        $recentPosts = $db->fetchAll($db->select('title', 'cid', 'created')->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish')->order('created', Typecho_Db::SORT_DESC)->limit(10));

        $adminUrl = Helper::options()->adminUrl;
        $yrOptions = '';
        foreach ($years as $yr) {
            $yrOptions .= '<option value="' . $yr . '">' . $yr . '年</option>';
        }

        return '
        <style>
            .container { max-width: none !important; width: auto !important; margin: 0 !important; }
            #typecho-welcome, .typecho-page-title, .typecho-page-main > .row, .typecho-page-main > div:not(.pro-dashboard-wrap) { display: none !important; }
            .typecho-page-main { padding: 0 !important; width: 100% !important; }
            .pro-dashboard-wrap { width: 100% !important; box-sizing: border-box; padding: 25px 35px; display: flex; flex-direction: column; gap: 24px; }
            
            /* 旗舰核心三层架构 */
            .dash-tier { width: 100% !important; display: grid; gap: 24px; }
            .tier-stats { grid-template-columns: 1fr; }
            .tier-charts { grid-template-columns: repeat(3, 1fr); }
            .tier-lists { grid-template-columns: repeat(3, 1fr); }
            
            .card { background: #fff; border-radius: 22px; padding: 24px; box-shadow: 0 4px 25px rgba(0,0,0,0.03); border: 1px solid #f1f5f9; box-sizing: border-box; overflow: hidden; display: flex; flex-direction: column; height: 100%; transition: all 0.3s ease; }
            .card-primary { background: linear-gradient(135deg, #4f46e5, #6366f1); color: #fff; border: none; display: flex; justify-content: space-around; align-items: center; box-shadow: 0 12px 35px rgba(79,70,229,0.25); height: 140px; flex-direction: row; width: 100% !important; margin: 0 !important; }
            
            .stat-item { text-align: center; flex: 1; } 
            .stat-item label { font-size: 13px; opacity: 0.95; margin-bottom: 8px; display: block; text-transform: uppercase; letter-spacing: 1.2px; font-weight: 700; color: rgba(255,255,255,0.9); } 
            .stat-item div { font-size: 40px; font-weight: 950; line-height: 1; text-shadow: 0 2px 10px rgba(0,0,0,0.15); }
            .stat-sep { width: 1px; height: 65px; background: rgba(255,255,255,0.25); }
            
            .chart-box { flex: 1; width: 100%; min-height: 360px; position: relative; }
            .card-title { font-weight: 800; color: #1e293b; font-size: 16px; margin-bottom: 22px; display: flex; align-items: center; padding-bottom: 12px; border-bottom: 2px solid #f8fafc; flex-shrink: 0; }
            .card-title span { flex: 1; display: flex; align-items: center; }
            .dot { width: 6px; height: 18px; background: #6366f1; border-radius: 4px; margin-right: 14px; }
            
            /* 旗舰年份选择器 4.0: 超大 Indigo 风格 */
            .year-select { 
                appearance: none; -webkit-appearance: none;
                background: linear-gradient(135deg, #4f46e5, #6366f1);
                color: #fff; font-size: 16px; font-weight: 900; 
                padding: 10px 48px 10px 20px; border-radius: 14px; cursor: pointer; 
                border: none; outline: none; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                box-shadow: 0 6px 15px rgba(79,70,229,0.3);
                background-image: url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' fill=\'none\' viewBox=\'0 0 24 24\' stroke=\'white\' stroke-width=\'4\'%3E%3Cpath stroke-linecap=\'round\' stroke-linejoin=\'round\' d=\'M19.5 8.25l-7.5 7.5-7.5-7.5\' /%3E%3C/svg%3E");
                background-repeat: no-repeat; background-position: right 18px center; background-size: 18px;
                line-height: normal; min-width: 100px;
            }
            .year-select:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(79,70,229,0.4); filter: brightness(1.1); }
            .year-select:active { transform: scale(0.98); }
            .year-select option { background: #fff; color: #1e293b; font-weight: 600; padding: 12px; }
            
            /* 底部列表样式 */
            .data-list { list-style: none; padding: 0; margin: 0; }
            .data-list li { padding: 12px 0; border-bottom: 1px solid #f8fafc; display: flex; justify-content: space-between; align-items: center; font-size: 13px; }
            .data-list a { color: #475569; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
            .rank-badge { width: 22px; height: 22px; border-radius: 6px; background: #f1f5f9; color: #94a3b8; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 800; margin-right: 10px; flex-shrink: 0; }
            .top-rank { background: #6366f1; color: #fff; }
            .rank-val { font-weight: 800; color: #1e293b; font-size: 10.5px; background: #f8fafc; padding: 2px 8px; border-radius: 4px; }
            
            @media (max-width: 1600px) { .tier-charts { grid-template-columns: repeat(2, 1fr); } .tier-lists { grid-template-columns: repeat(2, 1fr); } }
            @media (max-width: 1100px) { .tier-charts { grid-template-columns: 1fr; } .tier-lists { grid-template-columns: 1fr; } }
        </style>
        <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
        <script>
        document.addEventListener("DOMContentLoaded", function() {
            const container = document.querySelector(".typecho-page-main");
            if (!container) return;
            const wrap = document.createElement("div"); wrap.className = "pro-dashboard-wrap";
            wrap.innerHTML = `
                <div class="dash-tier tier-stats">
                    <div class="card card-primary">
                        <div class="stat-item"><label>文章总数</label><div>' . $postsCount . '</div></div>
                        <div class="stat-sep"></div>
                        <div class="stat-item"><label>创作字数</label><div>' . $displayWords . '</div></div>
                        <div class="stat-sep"></div>
                        <div class="stat-item"><label>互动评论</label><div>' . $commentsCount . '</div></div>
                        <div class="stat-sep"></div>
                        <div class="stat-item"><label>建站天数</label><div>' . $recordedDays . '</div></div>
                    </div>
                </div>
                <!-- 核心齐平图表区 -->
                <div class="dash-tier tier-charts">
                    <div class="card"><div class="card-title"><span><i class="dot"></i>年度写作热力图</span><select class="year-select" id="yr-sel">' . $yrOptions . '</select></div><div id="gt-hm" class="chart-box"></div></div>
                    <div class="card"><div class="card-title"><span><i class="dot"></i>内容分类占比</span></div><div id="ct-pie" class="chart-box"></div></div>
                    <div class="card"><div class="card-title"><span><i class="dot"></i>发布频率波动</span></div><div id="pb-tr" class="chart-box"></div></div>
                </div>
                <!-- 三列平铺数据区 -->
                <div class="dash-tier tier-lists">
                    <div class="card"><div class="card-title"><span><i class="dot"></i>最新互动评论</span></div><ul class="data-list">' . self::renderComments($recentComments) . '</ul></div>
                    <div class="card"><div class="card-title"><span><i class="dot"></i>最近发布文章</span></div><ul class="data-list">' . self::renderList($recentPosts, "created", $adminUrl, false) . '</ul></div>
                    <div class="card"><div class="card-title"><span><i class="dot"></i>人气Top 10</span></div><ul class="data-list">' . self::renderList($topViews, $viewField, $adminUrl, true) . '</ul></div>
                </div>`;
            container.prepend(wrap);

            const cO = {textStyle:{fontFamily:"Inter, sans-serif"}, animationDuration: 1000};
            
            // 彻底修复热力图交互逻辑
            const hData = ' . json_encode($heatmapData) . '; 
            const hm = echarts.init(document.getElementById("gt-hm"));
            
            const updHM = (y) => {
                const year = String(y);
                // 同时尝试字符串键和数字键
                const data = hData[year] || hData[parseInt(year)] || [];
                console.log("切换到年份:", year, "数据条数:", data.length);
                hm.setOption({
                    ...cO,
                    tooltip: { position: "top", formatter: p => p.data[0] + ": " + p.data[1] + " 篇" },
                    visualMap: { min: 0, max: 4, show: false, inRange: { color: ["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"] } },
                    calendar: { 
                        top: 40, left: 55, right: 25, bottom: 20,
                        range: year, cellSize: ["auto", 15], 
                        itemStyle: { borderWidth: 2, borderColor: "#fff", borderRadius: 4 }, 
                        yearLabel: { show: false }, 
                        dayLabel: { nameMap: "cn", fontSize: 10, color: "#64748b" }, 
                        monthLabel: { nameMap: "cn", fontSize: 11, color: "#64748b" }, 
                        splitLine: { show: false } 
                    },
                    series: [{ type: "heatmap", coordinateSystem: "calendar", data: data }]
                }, true); // true 表示不与旧配置合并，强制全新渲染
            };
            
            
            updHM("' . $currentYear . '");
            
            // 调试信息
            console.log("热力图数据结构:", hData);
            console.log("可用年份:", Object.keys(hData));
            
            // 使用setTimeout确保DOM完全加载后再绑定事件
            setTimeout(function() {
                const yearSelector = document.getElementById("yr-sel");
                if (yearSelector) {
                    console.log("年份选择器已找到，当前值:", yearSelector.value);
                    yearSelector.addEventListener("change", function(e) {
                        console.log("年份切换事件触发，新年份:", e.target.value);
                        updHM(e.target.value);
                    });
                } else {
                    console.error("未找到年份选择器元素！");
                }
            }, 100);

            // Pie
            const pie = echarts.init(document.getElementById("ct-pie"));
            pie.setOption({ 
                ...cO, tooltip:{trigger:"item"}, 
                series:[{ type:"pie", radius:["40%","65%"], center:["50%","45%"], itemStyle:{borderRadius:12,borderColor:"#fff",borderWidth:5}, label:{show:true,position:"outer",alignTo:"edge",formatter:"{b}\\n{d}%",fontSize:11,edgeDistance:"10%",color:"#475569"}, labelLine:{length:15,length2:8}, data:' . json_encode($categoryJson) . ' }]
            });

            // Trend
            const trend = echarts.init(document.getElementById("pb-tr"));
            trend.setOption({ 
                ...cO, tooltip:{trigger:"axis"}, grid:{top:45,bottom:40,left:55,right:35},
                xAxis:{type:"category",boundaryGap:false,data:Array.from({length:24},(_,i)=>i+"h"),axisLine:{show:false},axisLabel:{color:"#94a3b8",fontSize:11}},
                yAxis:{type:"value",minInterval:1,splitLine:{lineStyle:{type:"dashed",color:"#f1f5f9"}}},
                series:[{type:"line",smooth:true,symbolSize:0,lineStyle:{width:6,color:"#6366f1"},areaStyle:{color:new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:"rgba(99,102,241,0.25)"},{offset:1,color:"transparent"}])},data:' . json_encode($hoursDistrib) . '}]
            });
            
            window.addEventListener("resize", () => { hm.resize(); pie.resize(); trend.resize(); });
        });
        </script>';
    }

    private static function renderList($data, $field, $adminUrl, $isRank)
    {
        $html = '';
        foreach ($data as $i => $item) {
            $val = ($field == "created") ? date('m-d', $item[$field]) : $item[$field];
            $rank = $isRank ? '<span class="rank-badge ' . ($i < 3 ? 'top-rank' : '') . '">' . ($i + 1) . '</span>' : '';
            $html .= '<li><div style="display:flex;align-items:center;flex:1;overflow:hidden">' . $rank . '<a href="' . $adminUrl . 'write-post.php?cid=' . $item['cid'] . '">' . $item['title'] . '</a></div><span class="rank-val">' . $val . '</span></li>';
        }
        return $html;
    }

    private static function renderComments($data)
    {
        $html = '';
        foreach ($data as $item) {
            $txt = mb_substr(strip_tags($item['text']), 0, 22, 'UTF-8') . '...';
            $html .= '<li><div style="display:flex;flex-direction:column;flex:1;overflow:hidden"><span style="font-weight:700;font-size:14px;color:#1e293b;margin-bottom:3px">' . $item['author'] . '</span><span style="color:#64748b;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' . $txt . '</span></div><span class="rank-val">' . date('m-d', $item['created']) . '</span></li>';
        }
        return $html;
    }

    public static function renderFooter()
    {
        if (Typecho_Widget::widget('Widget_User')->hasLogin()) {
            echo '<script src="' . Helper::options()->pluginUrl . '/SimpleAdmin/static/js/user.min.js"></script>';
        }
    }
}