import Client from "ssh2-sftp-client";
import { Plugin } from "vite";

export interface FtpSyncTarget {
  host: string;
  port: number;
  username: string;
  password: string;
  remotePath: string;
  localPath?: string;
  clearRemote?: boolean;
}

// 创建日志工具
const logger = {
  pluginName: "vite-plugin-ftp-sync",
  info: (message: string) => {
    console.log(`\x1b[36m[${logger.pluginName}]\x1b[0m \x1b[32m${message}\x1b[0m`);
  },
  warn: (message: string) => {
    console.warn(`\x1b[36m[${logger.pluginName}]\x1b[0m \x1b[33m${message}\x1b[0m`);
  },
  error: (message: string, err?: any) => {
    console.error(`\x1b[36m[${logger.pluginName}]\x1b[0m \x1b[31m${message}\x1b[0m`, err || "");
  },
  success: (message: string) => {
    console.log(`\x1b[36m[${logger.pluginName}]\x1b[0m \x1b[32m${message} ✓\x1b[0m`);
  }
};

export function ftpSync(options: FtpSyncTarget[] | FtpSyncTarget): Plugin {
  return {
    name: "vite-plugin-ftp-sync",
    apply: "build",
    closeBundle: async () => {
      if (!Array.isArray(options)) options = [options];
      const results = await Promise.allSettled(
        options.map(async (target) => {
          const sftp = new Client();
          try {
            await sftp.connect({
              host: target.host,
              port: target.port,
              username: target.username,
              password: target.password,
            });

            const localPath = target.localPath || "dist";
            logger.info(
              `开始同步文件到 SFTP 服务器 ${target.host}:${target.port} -> ${target.remotePath}`,
            );

            if (target.clearRemote) {
              logger.info(`正在清除远程目录 ${target.remotePath}...`);
              try {
                await sftp.rmdir(target.remotePath, true);
                logger.success(`远程目录 ${target.remotePath} 已清除`);
              } catch (err) {
                logger.warn(`清除远程目录失败，可能目录不存在: ${err}`);
              }
            }

            await sftp.uploadDir(localPath, target.remotePath);
            logger.success(`文件同步到 ${target.host} 完成！`);

            sftp.end();
            return { target, success: true };
          } catch (err) {
            logger.error(`SFTP 同步到 ${target.host} 失败:`, err);
            sftp.end();
            return { target, success: false, error: err };
          }
        }),
      );

      const failures = results.filter(
        (result): result is PromiseRejectedResult =>
          result.status === "rejected",
      );

      if (failures.length > 0) {
        logger.error(`部分 SFTP 同步失败: ${failures.length} 个目标`);
        throw new Error(`部分 SFTP 同步失败: ${failures.length} 个目标`);
      } else {
        logger.success("所有同步任务已成功完成");
      }
    },
  };
}
