import {
    INodeType,
    INodeTypeDescription,
    IExecuteFunctions,
    INodeExecutionData,
    NodePropertyTypes,
    IDataObject,
  } from 'n8n-workflow';
  
  // 导入腾讯云 COS SDK
  import COS from 'cos-nodejs-sdk-v5';
  // 导入 Node.js 的文件系统模块 (使用 promises API 更方便处理异步)
  import * as fs from 'fs/promises'; // Changed to fs/promises for async readFile
  import * as path from 'path'; // Useful for path manipulation
  
  export class CosUpload implements INodeType {
    description: INodeTypeDescription = {
      displayName: '腾讯云 COS 文件上传',
      name: 'cosUpload',
      icon: 'fa:cloud-arrow-up', // 使用一个更贴切的图标
      group: ['storage'], // 分组为存储类
      version: 1,
      description: '上传本地文件到腾讯云对象存储 COS',
      defaults: {
        name: 'COS 文件上传',
      },
      // 修复 inputs 和 outputs 的类型错误
      inputs: ['main'] as any, // 使用 any 绕过严格的类型检查
      outputs: ['main'] as any, // 使用 any 绕过严格的类型检查
  
      // 定义节点所需的凭证类型
      credentials: [
        {
          name: 'tencentCosApi', // 凭证的内部名称，后续会创建
          required: true,
        },
      ],
  
      properties: [
        // 上传模式选择
        {
          displayName: '上传模式',
          name: 'uploadMode',
          type: 'options' as NodePropertyTypes,
          options: [
            { name: '本地文件上传', value: 'localFile' },
            { name: 'HTML内容上传', value: 'htmlContent' },
          ],
          default: 'localFile',
          description: '选择上传模式：本地文件或HTML内容',
          required: true,
        },
        // 文件路径
        {
          displayName: '本地文件路径',
          name: 'filePath',
          type: 'string' as NodePropertyTypes,
          default: '',
          placeholder: '/path/to/your/file.txt',
          description: '要上传的本地文件的绝对路径',
          required: true,
          displayOptions: {
            show: {
              uploadMode: ['localFile'],
            },
          },
        },
        // HTML内容
        {
          displayName: 'HTML内容',
          name: 'htmlContent',
          type: 'string' as NodePropertyTypes,
          typeOptions: {
            rows: 10,
          },
          default: '',
          placeholder: '<html><body><h1>Hello World</h1></body></html>',
          description: '要上传的HTML内容',
          required: true,
          displayOptions: {
            show: {
              uploadMode: ['htmlContent'],
            },
          },
        },
        // HTML文件名
        {
          displayName: 'HTML文件名',
          name: 'htmlFileName',
          type: 'string' as NodePropertyTypes,
          default: 'index.html',
          placeholder: 'index.html',
          description: '生成的HTML文件名',
          required: true,
          displayOptions: {
            show: {
              uploadMode: ['htmlContent'],
            },
          },
        },
        // 存储桶名称
        {
          displayName: '存储桶名称 (Bucket)',
          name: 'bucket',
          type: 'string' as NodePropertyTypes,
          default: '',
          placeholder: 'your-bucket-name-125xxxxxxxx',
          description: '您的腾讯云 COS 存储桶名称 (包含 APPID)',
          required: true,
        },
        // 存储桶地域
        {
          displayName: '存储桶地域 (Region)',
          name: 'region',
          type: 'options' as NodePropertyTypes, // 使用选项类型
          options: [
            { name: '北京 (ap-beijing)', value: 'ap-beijing' },
            { name: '南京 (ap-nanjing)', value: 'ap-nanjing' },
            { name: '上海 (ap-shanghai)', value: 'ap-shanghai' },
            { name: '广州 (ap-guangzhou)', value: 'ap-guangzhou' },
            { name: '成都 (ap-chengdu)', value: 'ap-chengdu' },
            { name: '重庆 (ap-chongqing)', value: 'ap-chongqing' },
            { name: '香港 (ap-hongkong)', value: 'ap-hongkong' },
            { name: '新加坡 (ap-singapore)', value: 'ap-singapore' },
            { name: '硅谷 (na-siliconvalley)', value: 'na-siliconvalley' },
            // ... 更多地域可以根据需要添加
          ],
          default: 'ap-guangzhou',
          description: '存储桶所在的地域',
          required: true,
        },
        // 存储在桶里的对象键
        {
          displayName: '对象键 (Key)',
          name: 'key',
          type: 'string' as NodePropertyTypes,
          default: '',
          placeholder: 'images/my-photo.jpg',
          description: '文件在 COS 中的路径和名称',
          required: true,
        },
      ],
    };
  
    async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
      const items = this.getInputData(); // 获取输入数据 (如果需要从上一个节点获取文件路径等)
      const returnData: INodeExecutionData[] = [];
  
      // 获取凭证
      const credentials = (await this.getCredentials('tencentCosApi')) as unknown as IDataObject;
      const secretId = credentials.secretId as string;
      const secretKey = credentials.secretKey as string;
  
      // 获取节点参数
      const uploadMode = this.getNodeParameter('uploadMode', 0) as string;
      const bucket = this.getNodeParameter('bucket', 0) as string;
      const region = this.getNodeParameter('region', 0) as string;
      const key = this.getNodeParameter('key', 0) as string;
      
      // 根据上传模式获取相应参数
      let filePath = '';
      let htmlContent = '';
      let htmlFileName = '';
      
      if (uploadMode === 'localFile') {
        filePath = this.getNodeParameter('filePath', 0) as string;
      } else if (uploadMode === 'htmlContent') {
        htmlContent = this.getNodeParameter('htmlContent', 0) as string;
        htmlFileName = this.getNodeParameter('htmlFileName', 0) as string;
      }
  
      // 确保 SecretId 和 SecretKey 存在
      if (!secretId || !secretKey) {
          throw new Error('腾讯云 COS 凭证 (SecretId 和 SecretKey) 未配置或不完整。');
      }
  
      // 初始化 COS 实例
      const cos = new COS({
        SecretId: secretId,
        SecretKey: secretKey,
      });
  
      for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
        try {
          if (uploadMode === 'localFile') { // 本地文件上传

            // 执行文件上传
            const uploadResult = await new Promise<COS.PutObjectResult>((resolve, reject) => {
              cos.uploadFile(
                {
                  Bucket: bucket,
                  Region: region,
                  Key: key,
                  FilePath: filePath, // 本地文件路径
                },
                function (err, data) {
                  if (err) {
                    return reject(err);
                  }
                  resolve(data);
                },
              );
            });

            // 将上传结果添加到输出数据
            returnData.push({
              json: {
                success: true,
                message: `文件 '${filePath}' 成功上传到 COS`,
                cosResponse: uploadResult as unknown as IDataObject,
              },
              pairedItem: {
                item: itemIndex,
              },
            });
          } else if (uploadMode === 'htmlContent') {
            // HTML内容上传
            const htmlFilePath = path.join(process.cwd(), htmlFileName);
            
            // 先写入HTML内容到临时文件
            await fs.writeFile(htmlFilePath, htmlContent);
            
            // 执行文件上传
            const uploadResult = await new Promise<COS.PutObjectResult>((resolve, reject) => {
              cos.uploadFile(
                {
                  Bucket: bucket,
                  Region: region,
                  Key: key,
                  FilePath: htmlFilePath, // 使用刚创建的临时文件路径
                },
                function (err, data) {
                  if (err) {
                    return reject(err);
                  }
                  resolve(data);
                },
              );
            });

            // 将上传结果添加到输出数据
            returnData.push({
              json: {
                success: true,
                message: `HTML内容成功上传到 COS`,
                cosResponse: uploadResult as unknown as IDataObject,
              },
              pairedItem: {
                item: itemIndex,
              },
            });
            
            // 清理临时文件
            await fs.unlink(htmlFilePath);
          }
        } catch (error: unknown) {
          const errorMessage = (error instanceof Error) ? error.message : String(error);
          const files = await fs.readdir('/home/node/.cache/n8n/public');
          returnData.push({
            json: {
              success: false,
              message: `文件上传失败 ${JSON.stringify(files)}`,
              error: errorMessage,
            },
            pairedItem: {
              item: itemIndex,
            },
          });
        }
      }
  
      return this.prepareOutputData(returnData);
    }
  }