import * as vscode from 'vscode';
import { FunctionCacheManager, FunctionInfo } from '../functionExtractor';
import { ApiParser, ApiFunction, ApiClass, ApiConstant } from './apiParser';

// 悬停信息提供者类
export class HoverProvider implements vscode.HoverProvider {
    private cacheManager: FunctionCacheManager;
    private apiParser: ApiParser;

    constructor(cacheManager: FunctionCacheManager) {
        this.cacheManager = cacheManager;
        this.apiParser = ApiParser.getInstance();
    }

    // 提供悬停时显示的信息
    async provideHover(
        document: vscode.TextDocument,
        position: vscode.Position,
        token: vscode.CancellationToken
    ): Promise<vscode.Hover | undefined> {
        // 检查是否在注释中，如果在注释中则不提供悬停信息
        const line = document.lineAt(position.line);
        const commentIndex = line.text.indexOf('//');
        if (commentIndex >= 0 && position.character > commentIndex) {
            return undefined;
        }

        // 获取鼠标悬停位置的单词范围
        const range = document.getWordRangeAtPosition(position);
        if (!range) {
            return undefined;
        }

        // 获取单词
        const word = document.getText(range);

        // 首先检查是否是API函数
        const apiFunction = this.apiParser.getFunctionByName(word);
        if (apiFunction) {
            const isFunctionEx = this.apiParser.isFunctionEx(apiFunction.name);
            const signature = this.apiParser.generateFunctionSignature(apiFunction, isFunctionEx);
            let hoverContent = `<span style="color:#4EC9B0;">★</span> <span style="color:#569CD6;">内置函数</span>: <code style="background-color:#2D2D30; color:#D4D4D4;">${signature}</code>\n\n`;
            hoverContent += `<span style="color:#6A9955;">${apiFunction.description}</span>\n\n`;

            if (apiFunction.params.length > 0) {
                hoverContent += `<span style="color:#C586C0;">参数</span>:\n`;
                apiFunction.params.forEach(param => {
                    hoverContent += `- <code style="color:#9CDCFE;">${param.name}</code>: <span style="color:#4EC9B0;">${param.type}</span><span style="color:#808080;">${param.optional ? ' (可选)' : ''}</span> - <span style="color:#6A9955;">${param.description}</span>\n`;
                });
            }

            if (apiFunction.returns) {
                hoverContent += `\n<span style="color:#C586C0;">返回值</span>: <code style="color:#4EC9B0;">${apiFunction.returns.type}</code> - <span style="color:#6A9955;">${apiFunction.returns.description}</span>`;
            }

            const markdownString = new vscode.MarkdownString(hoverContent);
            markdownString.isTrusted = true;
            return new vscode.Hover(markdownString, range);
        }

        // 检查是否是API类
        const apiClass = this.apiParser.getClassByName(word);
        if (apiClass) {
            const signature = this.apiParser.generateClassSignature(apiClass);
            let hoverContent = `<span style="color:#4EC9B0;">★</span> <span style="color:#569CD6;">内置类</span>: <code style="background-color:#2D2D30; color:#D4D4D4;">${signature}</code>\n\n`;
            hoverContent += `<span style="color:#6A9955;">${apiClass.description}</span>\n\n`;

            if (apiClass.methods.length > 0) {
                hoverContent += `<span style="color:#C586C0;">方法</span>:\n`;
                apiClass.methods.forEach(method => {
                    const methodSignature = this.apiParser.generateMethodSignature(method);
                    hoverContent += `- <code style="color:#DCDCAA;">${methodSignature}</code> - <span style="color:#6A9955;">${method.description}</span>\n`;
                });
            }

            if (apiClass.properties.length > 0) {
                hoverContent += `\n<span style="color:#C586C0;">属性</span>:\n`;
                apiClass.properties.forEach(prop => {
                    const propSignature = this.apiParser.generatePropertySignature(prop);
                    hoverContent += `- <code style="color:#9CDCFE;">${propSignature}</code> - <span style="color:#6A9955;">${prop.description}</span>\n`;
                });
            }

            const markdownString = new vscode.MarkdownString(hoverContent);
            markdownString.isTrusted = true;
            return new vscode.Hover(markdownString, range);
        }

        // 检查是否是API常量
        const apiConstant = this.apiParser.getConstantByName(word);
        if (apiConstant) {
            let hoverContent = `<span style="color:#4EC9B0;">★</span> <span style="color:#569CD6;">常量</span>: <code style="background-color:#2D2D30; color:#D4D4D4;">${apiConstant.name}</code>\n\n`;
            hoverContent += `<span style="color:#C586C0;">值</span>: <code style="color:#B5CEA8;">${apiConstant.value}</code>\n\n`;
            hoverContent += `<span style="color:#6A9955;">${apiConstant.description}</span>\n\n`;
            hoverContent += `<span style="color:#C586C0;">类别</span>: <span style="color:#4EC9B0;">${apiConstant.category}</span>`;

            const markdownString = new vscode.MarkdownString(hoverContent);
            markdownString.isTrusted = true;
            return new vscode.Hover(markdownString, range);
        }

        // 查找函数信息
        const functions = this.cacheManager.findFunctionsByName(word);
        if (functions.length > 0) {
            // 创建悬停信息
            let hoverContent = '';

            if (functions.length === 1) {
                // 单个函数
                const func = functions[0];
                hoverContent = `<span style="color:#569CD6;">函数</span>: <code style="background-color:#2D2D30; color:#D4D4D4;">${func.signature}</code>\n\n`;
                hoverContent += `<span style="color:#C586C0;">文件</span>: <span style="color:#4EC9B0;">${func.filePath}</span>\n\n`;
                hoverContent += `<span style="color:#C586C0;">行号</span>: <span style="color:#B5CEA8;">${func.lineNumber}</span>`;
            } else {
                // 多个同名函数
                hoverContent = `<span style="color:#569CD6;">函数</span>: <span style="color:#D4D4D4;">${word}</span>\n\n`;
                hoverContent += `<span style="color:#6A9955;">在多个文件中定义:</span>\n\n`;
                functions.forEach(func => {
                    hoverContent += `- <code style="color:#DCDCAA;">${func.signature}</code> (<span style="color:#4EC9B0;">${func.filePath}</span>:<span style="color:#B5CEA8;">${func.lineNumber}</span>)\n`;
                });
            }

            const markdownString = new vscode.MarkdownString(hoverContent);
            markdownString.isTrusted = true;
            return new vscode.Hover(markdownString, range);
        }

        // 检查是否是关键字
        const keywordInfo = this.getKeywordInfo(word);
        if (keywordInfo) {
            return new vscode.Hover(new vscode.MarkdownString(keywordInfo), range);
        }

        // 检查是否是常量
        const constantInfo = this.getConstantInfo(word);
        if (constantInfo) {
            return new vscode.Hover(new vscode.MarkdownString(constantInfo), range);
        }

        return undefined;
    }

    // 获取关键字信息
    private getKeywordInfo(word: string): string | undefined {
        const keywordMap: { [key: string]: string } = {
            'if': '<span style="color:#C586C0;">条件语句</span>\n\n<span style="color:#6A9955;">用于条件执行代码块</span>',
            'else': '<span style="color:#C586C0;">条件语句</span>\n\n<span style="color:#6A9955;">与if语句配合使用，当if条件不满足时执行</span>',
            'while': '<span style="color:#C586C0;">循环语句</span>\n\n<span style="color:#6A9955;">当条件为真时重复执行代码块</span>',
            'for': '<span style="color:#C586C0;">循环语句</span>\n\n<span style="color:#6A9955;">用于循环执行代码块</span>',
            'foreach': '<span style="color:#C586C0;">循环语句</span>\n\n<span style="color:#6A9955;">遍历数组或表中的每个元素</span>',
            'function': '<span style="color:#C586C0;">函数定义</span>\n\n<span style="color:#6A9955;">用于定义函数</span>',
            'local': '<span style="color:#C586C0;">变量声明</span>\n\n<span style="color:#6A9955;">声明局部变量</span>',
            'return': '<span style="color:#C586C0;">返回语句</span>\n\n<span style="color:#6A9955;">从函数中返回值</span>',
            'class': '<span style="color:#C586C0;">类定义</span>\n\n<span style="color:#6A9955;">用于定义类</span>',
            'extends': '<span style="color:#C586C0;">继承</span>\n\n<span style="color:#6A9955;">用于指定类的父类</span>',
            'constructor': '<span style="color:#C586C0;">构造函数</span>\n\n<span style="color:#6A9955;">类的构造函数</span>',
            'null': '<span style="color:#C586C0;">空值</span>\n\n<span style="color:#6A9955;">表示空值</span>',
            'true': '<span style="color:#C586C0;">布尔值</span>\n\n<span style="color:#6A9955;">表示真值</span>',
            'false': '<span style="color:#C586C0;">布尔值</span>\n\n<span style="color:#6A9955;">表示假值</span>'
        };

        return keywordMap[word];
    }

    // 获取常量信息
    private getConstantInfo(word: string): string | undefined {
        const constantMap: { [key: string]: string } = {
            'PI': '<span style="color:#C586C0;">数学常量</span>\n\n<span style="color:#6A9955;">圆周率 π ≈ 3.14159</span>',
            'E': '<span style="color:#C586C0;">数学常量</span>\n\n<span style="color:#6A9955;">自然常数 e ≈ 2.71828</span>',
            'RAND_MAX': '<span style="color:#C586C0;">随机数</span>\n\n<span style="color:#6A9955;">随机数生成器的最大值</span>',
            'CHAR_BIT': '<span style="color:#C586C0;">字符</span>\n\n<span style="color:#6A9955;">一个字节的位数</span>',
            'CHAR_MAX': '<span style="color:#C586C0;">字符</span>\n\n<span style="color:#6A9955;">char类型的最大值</span>',
            'CHAR_MIN': '<span style="color:#C586C0;">字符</span>\n\n<span style="color:#6A9955;">char类型的最小值</span>',
            'SHRT_MAX': '<span style="color:#C586C0;">短整型</span>\n\n<span style="color:#6A9955;">short类型的最大值</span>',
            'SHRT_MIN': '<span style="color:#C586C0;">短整型</span>\n\n<span style="color:#6A9955;">short类型的最小值</span>',
            'INT_MAX': '<span style="color:#C586C0;">整型</span>\n\n<span style="color:#6A9955;">int类型的最大值</span>',
            'INT_MIN': '<span style="color:#C586C0;">整型</span>\n\n<span style="color:#6A9955;">int类型的最小值</span>',
            'LONG_MAX': '<span style="color:#C586C0;">长整型</span>\n\n<span style="color:#6A9955;">long类型的最大值</span>',
            'LONG_MIN': '<span style="color:#C586C0;">长整型</span>\n\n<span style="color:#6A9955;">long类型的最小值</span>',
            'FLT_MAX': '<span style="color:#C586C0;">浮点型</span>\n\n<span style="color:#6A9955;">float类型的最大值</span>',
            'FLT_MIN': '<span style="color:#C586C0;">浮点型</span>\n\n<span style="color:#6A9955;">float类型的最小值</span>',
            'DBL_MAX': '<span style="color:#C586C0;">双精度浮点型</span>\n\n<span style="color:#6A9955;">double类型的最大值</span>',
            'DBL_MIN': '<span style="color:#C586C0;">双精度浮点型</span>\n\n<span style="color:#6A9955;">double类型的最小值</span>'
        };

        return constantMap[word];
    }
}