# ============================================
# 海龟编辑器图形界面版 - 博客管理工具
# 直接运行，在海龟编辑器里显示窗口
# ============================================

import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import os
from datetime import datetime
import frontmatter
import re
import sys

# 获取程序运行目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
POSTS_DIR = os.path.join(BASE_DIR, 'posts')

# 确保文件夹存在
if not os.path.exists(POSTS_DIR):
    try:
        os.makedirs(POSTS_DIR)
        print("已创建 posts 文件夹: " + POSTS_DIR)
    except Exception as e:
        print("创建文件夹失败: " + str(e))

# 创建示例文章（使用字符串拼接，不用三引号）
def create_sample_post():
    filepath = os.path.join(POSTS_DIR, '2026-08-05-hello-world.md')
    if not os.path.exists(filepath):
        sample_post_lines = [
            "---",
            "title: Hello World！我的第一篇博客",
            "description: 这是我的第一篇技术博客",
            "tags: Python,入门,博客",
            "---",
            "",
            "## 终于开始了！",
            "",
            "今天是 2026年8月5日，我决定开始写技术博客。",
            "",
            "### 为什么要写博客？",
            "",
            "1. 巩固知识 - 教是最好的学",
            "2. 建立个人品牌 - 让更多人认识我",
            "3. 记录成长 - 回头看看自己走过的路",
            "",
            "### Python 代码示例",
            "",
            "```python",
            "def hello_world():",
            "    print('Hello, World!')",
            "    return '欢迎来到我的博客！'",
            "",
            "if __name__ == '__main__':",
            "    hello_world()",
            "```",
            "",
            "### 接下来计划",
            "",
            "- 每周至少更新一篇",
            "- 学习 Flask 进阶",
            "- 分享项目实战经验",
            "",
            "---",
            "",
            "坚持写作，时间会给你答案！"
        ]
        sample_post = "\n".join(sample_post_lines)
        try:
            with open(filepath, 'w', encoding='utf-8') as f:
                f.write(sample_post)
            print("已创建示例文章")
        except Exception as e:
            print("创建示例文章失败: " + str(e))

create_sample_post()

class BlogApp:
    def __init__(self, root):
        self.root = root
        self.root.title("博客管理工具")
        self.root.geometry("900x700")
        self.root.configure(bg='#f0f2f5')
        
        # 保存当前选中的文章
        self.current_slug = None
        self.current_filename = None
        
        # 创建主框架
        main_frame = tk.Frame(root, bg='#f0f2f5')
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
        
        # 标题
        title_label = tk.Label(main_frame, text="我的博客管理", 
                               font=('微软雅黑', 24, 'bold'), 
                               bg='#f0f2f5', fg='#2c3e50')
        title_label.pack(pady=(0, 20))
        
        # 创建左右分栏
        left_frame = tk.Frame(main_frame, bg='#f0f2f5')
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
        
        right_frame = tk.Frame(main_frame, bg='#f0f2f5')
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(10, 0))
        
        # ========== 左侧：文章列表 ==========
        list_label = tk.Label(left_frame, text="文章列表", 
                              font=('微软雅黑', 14, 'bold'), bg='#f0f2f5')
        list_label.pack(anchor='w', pady=(0, 10))
        
        # 文章列表
        list_frame = tk.Frame(left_frame, bg='white')
        list_frame.pack(fill=tk.BOTH, expand=True)
        
        self.post_listbox = tk.Listbox(list_frame, font=('微软雅黑', 11), 
                                        bg='white', fg='#2c3e50',
                                        selectmode=tk.SINGLE,
                                        relief=tk.FLAT, highlightthickness=0)
        self.post_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 滚动条
        scrollbar = tk.Scrollbar(list_frame, orient=tk.VERTICAL, 
                                 command=self.post_listbox.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.post_listbox.config(yscrollcommand=scrollbar.set)
        
        # 按钮区域
        btn_frame = tk.Frame(left_frame, bg='#f0f2f5')
        btn_frame.pack(fill=tk.X, pady=10)
        
        self.refresh_btn = tk.Button(btn_frame, text="刷新列表", 
                                     font=('微软雅黑', 10),
                                     bg='#3498db', fg='white',
                                     relief=tk.FLAT, padx=15, pady=5,
                                     command=self.refresh_list)
        self.refresh_btn.pack(side=tk.LEFT, padx=2)
        
        self.delete_btn = tk.Button(btn_frame, text="删除文章", 
                                    font=('微软雅黑', 10),
                                    bg='#e74c3c', fg='white',
                                    relief=tk.FLAT, padx=15, pady=5,
                                    command=self.delete_post)
        self.delete_btn.pack(side=tk.LEFT, padx=2)
        
        # ========== 右侧：编辑区域 ==========
        edit_label = tk.Label(right_frame, text="编辑文章", 
                              font=('微软雅黑', 14, 'bold'), bg='#f0f2f5')
        edit_label.pack(anchor='w', pady=(0, 10))
        
        # 标题输入
        title_frame = tk.Frame(right_frame, bg='#f0f2f5')
        title_frame.pack(fill=tk.X, pady=(0, 10))
        
        tk.Label(title_frame, text="标题：", font=('微软雅黑', 10), 
                bg='#f0f2f5').pack(side=tk.LEFT)
        
        self.title_entry = tk.Entry(title_frame, font=('微软雅黑', 11),
                                   bg='white', relief=tk.FLAT,
                                   highlightthickness=1, highlightcolor='#3498db')
        self.title_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(5, 0))
        
        # 标签输入
        tag_frame = tk.Frame(right_frame, bg='#f0f2f5')
        tag_frame.pack(fill=tk.X, pady=(0, 10))
        
        tk.Label(tag_frame, text="标签：", font=('微软雅黑', 10), 
                bg='#f0f2f5').pack(side=tk.LEFT)
        
        self.tag_entry = tk.Entry(tag_frame, font=('微软雅黑', 10),
                                 bg='white', relief=tk.FLAT,
                                 highlightthickness=1, highlightcolor='#3498db')
        self.tag_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(5, 0))
        
        # 内容编辑框
        content_label = tk.Label(right_frame, text="内容 (支持Markdown)：", 
                                 font=('微软雅黑', 10), bg='#f0f2f5')
        content_label.pack(anchor='w')
        
        self.content_text = scrolledtext.ScrolledText(right_frame, 
                                                     font=('Consolas', 11),
                                                     bg='white', fg='#2c3e50',
                                                     relief=tk.FLAT,
                                                     highlightthickness=1,
                                                     highlightcolor='#3498db',
                                                     height=15)
        self.content_text.pack(fill=tk.BOTH, expand=True, pady=(5, 10))
        
        # 操作按钮
        action_frame = tk.Frame(right_frame, bg='#f0f2f5')
        action_frame.pack(fill=tk.X)
        
        self.save_btn = tk.Button(action_frame, text="保存新文章", 
                                  font=('微软雅黑', 11, 'bold'),
                                  bg='#27ae60', fg='white',
                                  relief=tk.FLAT, padx=20, pady=8,
                                  command=self.save_post)
        self.save_btn.pack(side=tk.LEFT, padx=2)
        
        self.update_btn = tk.Button(action_frame, text="更新文章", 
                                    font=('微软雅黑', 11, 'bold'),
                                    bg='#f39c12', fg='white',
                                    relief=tk.FLAT, padx=20, pady=8,
                                    command=self.update_post)
        self.update_btn.pack(side=tk.LEFT, padx=2)
        
        self.clear_btn = tk.Button(action_frame, text="清空", 
                                   font=('微软雅黑', 10),
                                   bg='#95a5a6', fg='white',
                                   relief=tk.FLAT, padx=15, pady=8,
                                   command=self.clear_form)
        self.clear_btn.pack(side=tk.LEFT, padx=2)
        
        # 状态栏（带路径信息）
        self.status_label = tk.Label(root, text="就绪 | 文章目录: " + POSTS_DIR, 
                                     font=('微软雅黑', 9),
                                     bg='#f0f2f5', fg='#6c757d',
                                     anchor='w', padx=20)
        self.status_label.pack(side=tk.BOTTOM, fill=tk.X, pady=(0, 10))
        
        # 绑定列表点击事件
        self.post_listbox.bind('<<ListboxSelect>>', self.on_select_post)
        
        # 加载文章列表
        self.refresh_list()
    
    def refresh_list(self):
        """刷新文章列表"""
        self.post_listbox.delete(0, tk.END)
        posts = self.get_all_posts()
        if posts:
            for post in posts:
                display_text = post['date_str'] + ' - ' + post['title']
                self.post_listbox.insert(tk.END, display_text)
            self.status_label.config(text="已加载 " + str(len(posts)) + " 篇文章 | 文章目录: " + POSTS_DIR)
        else:
            self.post_listbox.insert(tk.END, "还没有文章")
            self.status_label.config(text="还没有文章 | 文章目录: " + POSTS_DIR)
    
    def get_all_posts(self):
        """获取所有文章"""
        posts = []
        if not os.path.exists(POSTS_DIR):
            return posts
        
        for filename in os.listdir(POSTS_DIR):
            if filename.endswith('.md'):
                filepath = os.path.join(POSTS_DIR, filename)
                try:
                    with open(filepath, 'r', encoding='utf-8') as f:
                        post = frontmatter.load(f)
                        parts = filename.replace('.md', '').split('-', 3)
                        if len(parts) >= 3:
                            date_str = parts[0] + '-' + parts[1] + '-' + parts[2]
                            try:
                                date = datetime.strptime(date_str, '%Y-%m-%d')
                            except:
                                date = datetime.now()
                            title = parts[3] if len(parts) > 3 else filename.replace('.md', '')
                            title = title.replace('-', ' ').title()
                        else:
                            date = datetime.now()
                            title = post.metadata.get('title', filename.replace('.md', ''))
                        
                        posts.append({
                            'filename': filename,
                            'slug': filename.replace('.md', ''),
                            'title': post.metadata.get('title', title),
                            'date': date,
                            'date_str': date.strftime('%Y-%m-%d'),
                            'description': post.metadata.get('description', ''),
                            'content': post.content,
                            'tags': post.metadata.get('tags', '')
                        })
                except Exception as e:
                    print("读取文件失败: " + filename + " - " + str(e))
                    continue
        
        posts.sort(key=lambda x: x['date'], reverse=True)
        return posts
    
    def on_select_post(self, event):
        """选择文章后加载到编辑框"""
        selection = self.post_listbox.curselection()
        if not selection:
            return
        
        index = selection[0]
        posts = self.get_all_posts()
        if index >= len(posts):
            return
        
        post = posts[index]
        self.current_slug = post['slug']
        self.current_filename = post['filename']
        
        # 加载到编辑框
        self.title_entry.delete(0, tk.END)
        self.title_entry.insert(0, post['title'])
        
        self.tag_entry.delete(0, tk.END)
        self.tag_entry.insert(0, post['tags'])
        
        self.content_text.delete(1.0, tk.END)
        self.content_text.insert(1.0, post['content'])
        
        self.status_label.config(text="正在编辑: " + post['title'] + " | 文章目录: " + POSTS_DIR)
    
    def save_post(self):
        """保存新文章"""
        title = self.title_entry.get().strip()
        content = self.content_text.get(1.0, tk.END).strip()
        tags = self.tag_entry.get().strip()
        
        if not title or not content:
            messagebox.showwarning("提示", "标题和内容不能为空！")
            return
        
        # 生成 slug
        slug = re.sub(r'[^\w\s-]', '', title.lower())
        slug = re.sub(r'[-\s]+', '-', slug)
        slug = datetime.now().strftime('%Y-%m-%d') + '-' + slug
        
        filename = slug + '.md'
        filepath = os.path.join(POSTS_DIR, filename)
        
        # 检查是否已存在
        if os.path.exists(filepath):
            messagebox.showwarning("提示", "今天已有一篇同名文章，请修改标题！")
            return
        
        # 构建文章内容
        post_content = '---\n'
        post_content += 'title: ' + title + '\n'
        post_content += 'description: ' + title + '\n'
        post_content += 'tags: ' + tags + '\n'
        post_content += 'date: ' + datetime.now().strftime('%Y-%m-%d') + '\n'
        post_content += '---\n\n'
        post_content += content
        
        try:
            # 确保目录存在
            if not os.path.exists(POSTS_DIR):
                os.makedirs(POSTS_DIR)
            
            # 保存文件
            with open(filepath, 'w', encoding='utf-8') as f:
                f.write(post_content)
            
            self.status_label.config(text="文章已保存: " + title + " | 位置: " + filepath)
            messagebox.showinfo("成功", "文章「" + title + "」已保存！\n保存位置: " + filepath)
            self.refresh_list()
            self.clear_form()
        except Exception as e:
            error_msg = "保存失败: " + str(e)
            self.status_label.config(text=error_msg)
            messagebox.showerror("错误", "保存文章失败！\n\n错误信息: " + str(e) + "\n\n请检查是否有写入权限。")
    
    def update_post(self):
        """更新当前文章"""
        if not self.current_slug:
            messagebox.showwarning("提示", "请先从列表中选择一篇文章！")
            return
        
        title = self.title_entry.get().strip()
        content = self.content_text.get(1.0, tk.END).strip()
        tags = self.tag_entry.get().strip()
        
        if not title or not content:
            messagebox.showwarning("提示", "标题和内容不能为空！")
            return
        
        try:
            # 删除旧文章
            old_filepath = os.path.join(POSTS_DIR, self.current_filename)
            if os.path.exists(old_filepath):
                os.remove(old_filepath)
            
            # 生成新 slug
            slug = re.sub(r'[^\w\s-]', '', title.lower())
            slug = re.sub(r'[-\s]+', '-', slug)
            slug = datetime.now().strftime('%Y-%m-%d') + '-' + slug
            
            filename = slug + '.md'
            filepath = os.path.join(POSTS_DIR, filename)
            
            # 构建文章内容
            post_content = '---\n'
            post_content += 'title: ' + title + '\n'
            post_content += 'description: ' + title + '\n'
            post_content += 'tags: ' + tags + '\n'
            post_content += 'date: ' + datetime.now().strftime('%Y-%m-%d') + '\n'
            post_content += '---\n\n'
            post_content += content
            
            # 保存文件
            with open(filepath, 'w', encoding='utf-8') as f:
                f.write(post_content)
            
            self.current_slug = slug
            self.current_filename = filename
            self.status_label.config(text="文章已更新: " + title)
            messagebox.showinfo("成功", "文章「" + title + "」已更新！")
            self.refresh_list()
        except Exception as e:
            error_msg = "更新失败: " + str(e)
            self.status_label.config(text=error_msg)
            messagebox.showerror("错误", "更新文章失败！\n\n错误信息: " + str(e))
    
    def delete_post(self):
        """删除选中的文章"""
        selection = self.post_listbox.curselection()
        if not selection:
            messagebox.showwarning("提示", "请先选择一篇文章！")
            return
        
        if not messagebox.askyesno("确认删除", "确定要删除这篇文章吗？\n\n此操作不可恢复！"):
            return
        
        index = selection[0]
        posts = self.get_all_posts()
        if index >= len(posts):
            return
        
        post = posts[index]
        filepath = os.path.join(POSTS_DIR, post['filename'])
        
        try:
            if os.path.exists(filepath):
                os.remove(filepath)
                self.status_label.config(text="已删除: " + post['title'])
                self.refresh_list()
                self.clear_form()
                self.current_slug = None
                self.current_filename = None
                messagebox.showinfo("成功", "文章「" + post['title'] + "」已删除！")
            else:
                messagebox.showwarning("提示", "文件不存在！")
        except Exception as e:
            error_msg = "删除失败: " + str(e)
            self.status_label.config(text=error_msg)
            messagebox.showerror("错误", "删除文章失败！\n\n错误信息: " + str(e))
    
    def clear_form(self):
        """清空表单"""
        self.title_entry.delete(0, tk.END)
        self.tag_entry.delete(0, tk.END)
        self.content_text.delete(1.0, tk.END)
        self.current_slug = None
        self.current_filename = None
        self.status_label.config(text="表单已清空 | 文章目录: " + POSTS_DIR)

# 运行
if __name__ == '__main__':
    print("=" * 60)
    print("博客管理工具启动...")
    print("文章目录: " + POSTS_DIR)
    print("=" * 60)
    
    root = tk.Tk()
    app = BlogApp(root)
    root.mainloop()