/*
 * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *          http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.micode.notes.tool;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import androidx.core.content.FileProvider;

import net.micode.notes.R;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Markdown工具类
 * 提供文本到Markdown格式的转换、导出和预览功能
 * 支持将普通文本智能转换为Markdown格式并导出为.md文件
 */
public class MarkdownUtils {
    // 日志标签
    private static final String TAG = "MarkdownUtils";

    /**
     * 将普通文本转换为Markdown格式
     * 智能识别标题、列表、代码块等结构
     * @param content 要转换的文本内容
     * @param title 笔记标题
     * @return 转换后的Markdown格式文本
     */
    public static String convertToMarkdown(String content, String title) {
        if (TextUtils.isEmpty(content)) {
            return "";
        }

        StringBuilder markdown = new StringBuilder();

        // 如果提供了标题，添加为一级标题
        if (!TextUtils.isEmpty(title)) {
            markdown.append("# ").append(title).append("\n\n");
        }

        // 添加时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        markdown.append("*Created: ").append(sdf.format(new Date())).append("*\n\n");

        // 逐行处理内容
        String[] lines = content.split("\n");
        boolean inCodeBlock = false;    // 是否在代码块中
        boolean inList = false;         // 是否在列表中
        
        for (String line : lines) {
            String trimmedLine = line.trim();

            // 处理空行
            if (trimmedLine.isEmpty()) {
                markdown.append("\n");
                inList = false;
                continue;
            }

            // 处理代码块（以4个空格或制表符开头的行）
            if (line.startsWith("    ") || line.startsWith("\t")) {
                if (!inCodeBlock) {
                    markdown.append("```\n");
                    inCodeBlock = true;
                }
                markdown.append(line.substring(line.startsWith("    ") ? 4 : 1)).append("\n");
                continue;
            } else if (inCodeBlock) {
                markdown.append("```\n\n");
                inCodeBlock = false;
            }

            // 处理项目符号列表
            if (trimmedLine.startsWith("•") || trimmedLine.startsWith("-") ||
                trimmedLine.startsWith("*") || trimmedLine.matches("^\\d+\\..*")) {
                if (!inList) {
                    inList = true;
                }
                if (trimmedLine.startsWith("•")) {
                    markdown.append("- ").append(trimmedLine.substring(1).trim()).append("\n");
                } else {
                    markdown.append(trimmedLine).append("\n");
                }
                continue;
            } else if (inList) {
                inList = false;
                markdown.append("\n");
            }

            // 处理标题（看起来像标题的行）
            if (isLikelyHeader(trimmedLine)) {
                markdown.append("## ").append(trimmedLine).append("\n\n");
                continue;
            }

            // 处理普通段落
            markdown.append(trimmedLine).append("\n\n");
        }

        // 如果代码块仍然打开，则关闭它
        if (inCodeBlock) {
            markdown.append("```\n");
        }

        return markdown.toString();
    }

    /**
     * 检查一行是否看起来像标题
     * @param line 要检查的文本行
     * @return true表示可能是标题，false表示不是
     */
    private static boolean isLikelyHeader(String line) {
        // 短行且全大写或标题格式
        if (line.length() < 50 && (line.equals(line.toUpperCase()) || isTitleCase(line))) {
            return true;
        }

        // 以冒号结尾的行
        if (line.endsWith(":") && line.length() < 80) {
            return true;
        }

        return false;
    }
    
    /**
     * 检查文本是否为标题格式（首字母大写）
     * @param text 要检查的文本
     * @return true表示是标题格式，false表示不是
     */
    private static boolean isTitleCase(String text) {
        String[] words = text.split("\\s+");
        if (words.length < 2) return false;

        int titleCaseWords = 0;
        for (String word : words) {
            if (word.length() > 0 && Character.isUpperCase(word.charAt(0))) {
                titleCaseWords++;
            }
        }

        return titleCaseWords >= words.length * 0.7; // 至少70%的单词首字母大写
    }

    /**
     * 将内容导出为Markdown文件
     * @param context 上下文对象
     * @param content 要导出的内容
     * @param title 笔记标题
     * @return 导出是否成功
     */
    public static boolean exportToMarkdown(Context context, String content, String title) {
        try {
            // 创建Markdown内容
            String markdownContent = convertToMarkdown(content, title);

            // 生成文件名
            String filename = generateMarkdownFilename(title);

            // 获取外部存储目录
            File exportDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_DOCUMENTS), "Notes");

            if (!exportDir.exists()) {
                exportDir.mkdirs();
            }

            File markdownFile = new File(exportDir, filename);

            // 写入文件
            FileWriter writer = new FileWriter(markdownFile);
            writer.write(markdownContent);
            writer.close();

            // 显示成功消息并提供分享选项
            Toast.makeText(context,
                context.getString(R.string.export_success) + ": " + markdownFile.getAbsolutePath(),
                Toast.LENGTH_LONG).show();

            // 提供分享文件的选项
            shareMarkdownFile(context, markdownFile);

            return true;

        } catch (IOException e) {
            Log.e(TAG, "Error exporting to markdown", e);
            Toast.makeText(context,
                context.getString(R.string.export_failed) + ": " + e.getMessage(),
                Toast.LENGTH_LONG).show();
            return false;
        }
    }
    
    /**
     * Generate a safe filename for markdown export
     */
    private static String generateMarkdownFilename(String title) {
        String filename;
        
        if (!TextUtils.isEmpty(title)) {
            // Clean title for filename
            filename = title.replaceAll("[^a-zA-Z0-9\\s\\-_]", "")
                          .replaceAll("\\s+", "_")
                          .substring(0, Math.min(title.length(), 50));
        } else {
            filename = "note";
        }
        
        // Add timestamp
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault());
        filename += "_" + sdf.format(new Date());
        
        return filename + ".md";
    }
    
    /**
     * Share markdown file
     */
    private static void shareMarkdownFile(Context context, File file) {
        try {
            Uri fileUri = FileProvider.getUriForFile(context, 
                context.getPackageName() + ".fileprovider", file);
            
            Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.setType("text/markdown");
            shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
            shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Note exported as Markdown");
            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            
            context.startActivity(Intent.createChooser(shareIntent, "Share Markdown File"));
            
        } catch (Exception e) {
            Log.e(TAG, "Error sharing markdown file", e);
        }
    }
    
    /**
     * Convert markdown to HTML for preview
     */
    public static String markdownToHtml(String markdown) {
        if (TextUtils.isEmpty(markdown)) {
            return "";
        }
        
        String html = markdown;
        
        // Headers
        html = html.replaceAll("^### (.*$)", "<h3>$1</h3>");
        html = html.replaceAll("^## (.*$)", "<h2>$1</h2>");
        html = html.replaceAll("^# (.*$)", "<h1>$1</h1>");
        
        // Bold and italic
        html = html.replaceAll("\\*\\*(.*?)\\*\\*", "<strong>$1</strong>");
        html = html.replaceAll("\\*(.*?)\\*", "<em>$1</em>");
        
        // Code blocks
        html = html.replaceAll("```([\\s\\S]*?)```", "<pre><code>$1</code></pre>");
        html = html.replaceAll("`(.*?)`", "<code>$1</code>");
        
        // Lists
        html = html.replaceAll("^- (.*$)", "<li>$1</li>");
        html = html.replaceAll("(<li>.*</li>)", "<ul>$1</ul>");
        
        // Line breaks
        html = html.replaceAll("\n\n", "</p><p>");
        html = "<p>" + html + "</p>";
        
        return html;
    }
    
    /**
     * Check if content contains markdown syntax
     */
    public static boolean containsMarkdown(String content) {
        if (TextUtils.isEmpty(content)) {
            return false;
        }
        
        // Check for common markdown patterns
        Pattern[] patterns = {
            Pattern.compile("^#{1,6}\\s+.*", Pattern.MULTILINE),  // Headers
            Pattern.compile("\\*\\*.*?\\*\\*"),                   // Bold
            Pattern.compile("\\*.*?\\*"),                         // Italic
            Pattern.compile("`.*?`"),                             // Inline code
            Pattern.compile("```[\\s\\S]*?```"),                  // Code blocks
            Pattern.compile("^[-*+]\\s+.*", Pattern.MULTILINE),  // Lists
            Pattern.compile("^\\d+\\.\\s+.*", Pattern.MULTILINE) // Numbered lists
        };
        
        for (Pattern pattern : patterns) {
            if (pattern.matcher(content).find()) {
                return true;
            }
        }
        
        return false;
    }
}
