import * as vscode from 'vscode';
import * as http from 'http';
import * as https from 'https';

// API 响应接口
interface ApiResponse<T> {
    Data: T;
    IsError: boolean;
    Msg: string | null;
}

// 获取文件列表响应
interface FileListResponse {
    Data: string[];
    IsError: boolean;
    Msg: string | null;
}

// 获取文件内容响应
interface FileContentResponse {
    Data: {
        FileContentData: { [key: string]: string };
    };
    IsError: boolean;
    Msg: string | null;
}

export class ApiClient {
    private baseUrl: string;
    private port: number;

    constructor(baseUrl: string = 'http://localhost', port: number = 8080) {
        this.baseUrl = baseUrl;
        this.port = port;
    }

    private getFullUrl(endpoint: string): string {
        return `${this.baseUrl}:${this.port}${endpoint}`;
    }

    // 通用的 HTTP 请求方法
    private async request(url: string, method: string = 'GET', body?: string, headers: Record<string, string> = {}): Promise<any> {
        return new Promise((resolve, reject) => {
            const urlObj = new URL(url);
            const isHttps = urlObj.protocol === 'https:';
            const client = isHttps ? https : http;

            const options: http.RequestOptions = {
                hostname: urlObj.hostname,
                port: urlObj.port || (isHttps ? 443 : 80),
                path: urlObj.pathname + urlObj.search,
                method: method,
                headers: {
                    'User-Agent': 'VSCode-Squirrel-NUT-Explorer/1.0',
                    ...headers
                }
            };

            console.log(`HTTP请求: ${method} ${url}`);
            console.log(`请求选项:`, options);

            const req = client.request(options, (res) => {
                let data = '';

                console.log(`响应状态码: ${res.statusCode}`);
                console.log(`响应头:`, res.headers);

                res.on('data', (chunk) => {
                    data += chunk;
                });

                res.on('end', () => {
                    console.log(`原始响应数据长度: ${data.length}`);
                    console.log(`原始响应数据: ${data}`);

                    if (res.statusCode !== 200) {
                        reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`));
                        return;
                    }

                    try {
                        if (!data || data.trim() === '') {
                            reject(new Error('响应为空'));
                            return;
                        }
                        const result = JSON.parse(data);
                        resolve(result);
                    } catch (error) {
                        reject(new Error(`解析JSON响应失败: ${error}。原始数据: ${data}`));
                    }
                });
            });

            req.on('error', (error) => {
                console.error(`请求错误: ${error.message}`);
                reject(new Error(`请求失败: ${error.message}`));
            });

            req.setTimeout(10000, () => {
                console.error('请求超时');
                req.destroy();
                reject(new Error('请求超时'));
            });

            if (body) {
                console.log(`请求体长度: ${body.length}`);
                req.write(body);
            }

            req.end();
        });
    }

    // 获取 nut 文件列表
    async getFileList(dirName: string = 'sqr', fileType: string = 'nut'): Promise<string> {
        try {
            const url = this.getFullUrl('/Api/PvfUtiltiy/GetFileList');
            const params = new URLSearchParams({
                dirName,
                returnType: '1',
                fileType
            });

            const fullUrl = `${url}?${params}`;
            console.log(`请求URL: ${fullUrl}`);

            const result = await this.request(fullUrl) as { Data: string; IsError: boolean; Msg: string | null };

            if (result.IsError) {
                throw new Error(result.Msg || '获取文件列表失败');
            }

            return result.Data;
        } catch (error) {
            vscode.window.showErrorMessage(`获取文件列表失败: ${error}`);
            throw error;
        }
    }

    // 批量获取文件内容
    async getFileContents(filePaths: string[], encodingType: string | null = null): Promise<{ [key: string]: string }> {
        try {
            const url = this.getFullUrl('/Api/PvfUtiltiy/GetFileContents');

            const requestBody = {
                FileList: filePaths,
                UseCompatibleDecompiler: false,
                EncodingType: encodingType
            };

            const result = await this.request(url, 'POST', JSON.stringify(requestBody), {
                'Content-Type': 'application/json'
            }) as FileContentResponse;

            if (result.IsError) {
                throw new Error(result.Msg || '获取文件内容失败');
            }

            return result.Data.FileContentData;
        } catch (error) {
            vscode.window.showErrorMessage(`获取文件内容失败: ${error}`);
            throw error;
        }
    }

    // 上传文件内容
    async uploadFileContent(filePath: string, content: string): Promise<boolean> {
        try {
            const url = this.getFullUrl(`/Api/PvfUtiltiy/ImportFile?filePath=${encodeURIComponent(filePath)}`);
            console.log(`上传文件URL: ${url}`);
            const result = await this.request(url, 'POST', content, {
                'Content-Type': 'text/plain; charset=utf-8',
            });

            if (result.IsError) {
                throw new Error(result.Msg || '上传文件失败');
            }

            return true;
        } catch (error) {
            vscode.window.showErrorMessage(`上传文件失败: ${error}`);
            throw error;
        }
    }

    // 获取 pvfUtility 版本号
    async getVersion(): Promise<string> {
        try {
            const url = this.getFullUrl('/Api/PvfUtiltiy/getVersion');
            console.log(`版本检查URL: ${url}`);

            const result = await this.request(url) as { Data: string; IsError: boolean; Msg: string | null };

            if (result.IsError) {
                throw new Error(result.Msg || '获取版本号失败');
            }

            return result.Data;
        } catch (error) {
            console.error('获取版本号失败:', error);
            vscode.window.showErrorMessage(`获取 pvfUtility 版本号失败: ${error}`);
            throw error;
        }
    }

    // 更新配置
    updateConfig(baseUrl: string, port: number) {
        this.baseUrl = baseUrl;
        this.port = port;
    }
}