import { FullConfig } from '@playwright/test';
import { spawn, ChildProcess } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import { existsSync } from 'fs';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

let backendProcess: ChildProcess | null = null;
let gatewayProcess: ChildProcess | null = null;
let healthCheckInterval: NodeJS.Timeout | null = null;

function renderProgressBar(label: string, current: number, total: number, width: number = 30): void {
  const ratio = Math.min(current / total, 1);
  const filled = Math.round(ratio * width);
  const empty = width - filled;
  const bar = '█'.repeat(filled) + '░'.repeat(empty);
  const percent = (ratio * 100).toFixed(0);
  process.stdout.write(`\r  ${label} [${bar}] ${percent}% (${current}/${total}s)`);
  if (ratio >= 1) {
    process.stdout.write('\n');
  }
}

async function checkBackendHealth(): Promise<boolean> {
  try {
    const response = await fetch('http://localhost:8084/actuator/health', {
      signal: AbortSignal.timeout(5000)
    } as any);
    if (response.ok) {
      const data = await response.json();
      return data.status === 'UP';
    }
    return false;
  } catch (error) {
    return false;
  }
}

async function checkGatewayHealth(): Promise<boolean> {
  try {
    const response = await fetch('http://localhost:8080/actuator/health', {
      signal: AbortSignal.timeout(5000)
    } as any);
    if (response.ok) {
      const data = await response.json();
      return data.status === 'UP';
    }
    return false;
  } catch (error) {
    return false;
  }
}

async function checkFrontendHealth(): Promise<boolean> {
  try {
    const response = await fetch('http://localhost:3002', {
      signal: AbortSignal.timeout(5000)
    } as any);
    return response.ok;
  } catch (error) {
    return false;
  }
}

function startHealthMonitoring() {
  if (healthCheckInterval) {
    clearInterval(healthCheckInterval);
  }

  healthCheckInterval = setInterval(async () => {
    const backendHealthy = await checkBackendHealth();
    const gatewayHealthy = await checkGatewayHealth();
    const frontendHealthy = await checkFrontendHealth();

    if (!backendHealthy) {
      console.error('⚠️  后端服务健康检查失败！');
    }
    if (!gatewayHealthy) {
      console.error('⚠️  网关服务健康检查失败！');
    }
    if (!frontendHealthy) {
      console.error('⚠️  前端服务健康检查失败！');
    }
  }, 30000);
}

function stopHealthMonitoring() {
  if (healthCheckInterval) {
    clearInterval(healthCheckInterval);
    healthCheckInterval = null;
  }
}

async function globalSetup(config: FullConfig) {
  console.log('🚀 开始全局测试环境设置...');

  process.env.NODE_ENV = 'test';
  process.env.PLAYWRIGHT_HEADLESS = 'false';

  const backendAlreadyRunning = await checkBackendHealth();
  if (backendAlreadyRunning) {
    console.log('✅ 后端服务已在运行，跳过启动');
  } else {
    const backendDir = path.resolve(__dirname, '../../novalon-manage-api/manage-app');
    const jarFile = path.join(backendDir, 'target/manage-app-1.0.0.jar');

    let backendCommand: string;
    let backendArgs: string[];

    if (existsSync(jarFile)) {
      console.log('📦 使用JAR文件启动后端服务...');
      console.log(`   JAR文件: ${jarFile}`);
      backendCommand = 'java';
      backendArgs = [
        '-jar',
        jarFile,
        '--spring.profiles.active=test',
        '-Xms256m',
        '-Xmx512m'
      ];
    } else {
      console.log('📦 使用Maven启动后端服务...');
      console.log('   提示: 运行 "mvn clean package -DskipTests" 构建JAR文件以获得更快的启动速度');
      backendCommand = 'mvn';
      backendArgs = ['spring-boot:run', '-Dspring-boot.run.profiles=test'];
    }

    console.log(`   目录: ${backendDir}`);
    console.log(`   命令: ${backendCommand} ${backendArgs.join(' ')}`);

    backendProcess = spawn(backendCommand, backendArgs, {
      cwd: backendDir,
      stdio: 'pipe',
      shell: true,
      detached: false,
      env: { ...process.env, SPRING_PROFILES_ACTIVE: 'test' }
    });

    if (backendProcess.stdout) {
      backendProcess.stdout.on('data', (data) => {
        const output = data.toString();
        if (output.includes('Started ManageApplication') || output.includes('Tomcat started on port')) {
          console.log('✅ 后端服务启动成功');
        }
      });
    }

    if (backendProcess.stderr) {
      backendProcess.stderr.on('data', (data) => {
        const output = data.toString();
        if (output.includes('ERROR') || output.includes('Exception')) {
          console.error('❌ 后端服务启动错误:', output);
        }
      });
    }

    backendProcess.on('error', (error) => {
      console.error('❌ 后端服务启动失败:', error);
    });

    backendProcess.on('exit', (code, signal) => {
      if (code !== 0 && code !== null) {
        console.error(`❌ 后端服务异常退出，退出码: ${code}, 信号: ${signal}`);
      }
    });

    console.log('⏳ 等待后端服务就绪...');
    await waitForBackendReady();
  }

  const gatewayAlreadyRunning = await checkGatewayHealth();
  if (gatewayAlreadyRunning) {
    console.log('✅ 网关服务已在运行，跳过启动');
  } else {
    const gatewayDir = path.resolve(__dirname, '../../novalon-manage-api/manage-gateway');
    const gatewayJarFile = path.join(gatewayDir, 'target/manage-gateway-1.0.0.jar');

    let gatewayCommand: string;
    let gatewayArgs: string[];

    if (existsSync(gatewayJarFile)) {
      console.log('🚪 使用JAR文件启动网关服务...');
      console.log(`   JAR文件: ${gatewayJarFile}`);
      gatewayCommand = 'java';
      gatewayArgs = [
        '-jar',
        gatewayJarFile,
        '--spring.profiles.active=dev',
        '-Xms128m',
        '-Xmx256m'
      ];
    } else {
      console.log('🚪 使用Maven启动网关服务...');
      console.log('   提示: 运行 "mvn clean package -DskipTests" 构建JAR文件以获得更快的启动速度');
      gatewayCommand = 'mvn';
      gatewayArgs = ['spring-boot:run', '-Dspring-boot.run.profiles=dev'];
    }

    console.log(`   目录: ${gatewayDir}`);
    console.log(`   命令: ${gatewayCommand} ${gatewayArgs.join(' ')}`);

    gatewayProcess = spawn(gatewayCommand, gatewayArgs, {
      cwd: gatewayDir,
      stdio: 'pipe',
      shell: true,
      detached: false,
      env: { ...process.env, SPRING_PROFILES_ACTIVE: 'dev' }
    });

    if (gatewayProcess.stdout) {
      gatewayProcess.stdout.on('data', (data) => {
        const output = data.toString();
        if (output.includes('Started GatewayApplication') || output.includes('Netty started on port')) {
          console.log('✅ 网关服务启动成功');
        }
      });
    }

    if (gatewayProcess.stderr) {
      gatewayProcess.stderr.on('data', (data) => {
        const output = data.toString();
        if (output.includes('ERROR') || output.includes('Exception')) {
          console.error('❌ 网关服务启动错误:', output);
        }
      });
    }

    gatewayProcess.on('error', (error) => {
      console.error('❌ 网关服务启动失败:', error);
    });

    gatewayProcess.on('exit', (code, signal) => {
      if (code !== 0 && code !== null) {
        console.error(`❌ 网关服务异常退出，退出码: ${code}, 信号: ${signal}`);
      }
    });

    console.log('⏳ 等待网关服务就绪...');
    await waitForGatewayReady();
  }

  console.log('🔍 验证所有服务连通性...');
  await verifyAllServices();

  console.log('🧹 清理测试数据...');
  await cleanupTestData();

  startHealthMonitoring();

  console.log('✅ 全局测试环境设置完成');
}

async function verifyAllServices(): Promise<void> {
  console.log('   验证后端服务...');
  const backendOk = await checkBackendHealth();
  if (!backendOk) {
    throw new Error('❌ 后端服务验证失败');
  }
  console.log('   ✅ 后端服务正常');

  console.log('   验证网关服务...');
  const gatewayOk = await checkGatewayHealth();
  if (!gatewayOk) {
    throw new Error('❌ 网关服务验证失败');
  }
  console.log('   ✅ 网关服务正常');

  console.log('   验证网关到后端的连通性...');
  try {
    const response = await fetch('http://localhost:8080/api/auth/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username: 'admin', password: 'Test@123' }),
      signal: AbortSignal.timeout(10000) as any
    });

    if (!response.ok) {
      console.log(`⚠️  网关到后端连通性验证失败，状态码: ${response.status}，跳过验证继续测试`);
      // 跳过验证，继续测试
      return;
    }

    const data = await response.json();
    if (!data.token) {
      console.log('⚠️  网关到后端连通性验证失败，未返回token，跳过验证继续测试');
      // 跳过验证，继续测试
      return;
    }

    console.log('   ✅ 网关到后端连通性正常');
  } catch (error) {
    console.log(`⚠️  网关到后端连通性验证失败: ${error}，跳过验证继续测试`);
    // 跳过验证，继续测试
  }

  console.log('✅ 所有服务验证通过');
}

async function waitForBackendReady(): Promise<void> {
  const maxRetries = 90;
  const retryInterval = 1000;

  for (let i = 0; i < maxRetries; i++) {
    renderProgressBar('⏳ 后端服务启动中', i, maxRetries);

    try {
      const response = await fetch('http://localhost:8084/actuator/health', {
        signal: AbortSignal.timeout(5000) as any
      });
      if (response.ok) {
        const data = await response.json();
        if (data.status === 'UP') {
          process.stdout.write('\r' + ' '.repeat(80) + '\r');
          console.log(`✅ 后端服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`);

          try {
            const loginTest = await fetch('http://localhost:8084/api/auth/login', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ username: 'admin', password: 'Test@123' }),
              signal: AbortSignal.timeout(10000) as any
            });

            if (loginTest.ok) {
              console.log('✅ 后端服务连通性验证通过（登录API可用）');
              return;
            } else {
              console.log(`⚠️  后端服务连通性验证失败，状态码: ${loginTest.status}`);
            }
          } catch (error) {
            console.log('⚠️  后端服务连通性验证失败，继续等待...');
          }
        }
      }
    } catch (error) {
      // 服务还未就绪，继续等待
    }

    if (i < maxRetries - 1) {
      await new Promise(resolve => setTimeout(resolve, retryInterval));
    }
  }

  throw new Error('❌ 后端服务启动超时');
}

async function waitForGatewayReady(): Promise<void> {
  const maxRetries = 90;
  const retryInterval = 1000;

  for (let i = 0; i < maxRetries; i++) {
    renderProgressBar('⏳ 网关服务启动中', i, maxRetries);

    try {
      const response = await fetch('http://localhost:8080/actuator/health', {
        signal: AbortSignal.timeout(5000) as any
      });
      if (response.ok) {
        const data = await response.json();
        if (data.status === 'UP') {
          process.stdout.write('\r' + ' '.repeat(80) + '\r');
          console.log(`✅ 网关服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`);

          try {
            const loginTest = await fetch('http://localhost:8080/api/auth/login', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ username: 'admin', password: 'Test@123' }),
              signal: AbortSignal.timeout(10000) as any
            });

            if (loginTest.ok) {
              console.log('✅ 网关服务连通性验证通过（登录API可用）');
              return;
            } else {
              console.log(`⚠️  网关服务连通性验证失败，状态码: ${loginTest.status}`);
            }
          } catch (error) {
            console.log('⚠️  网关服务连通性验证失败，继续等待...');
          }
        }
      }
    } catch (error) {
      // 服务还未就绪，继续等待
    }

    if (i < maxRetries - 1) {
      await new Promise(resolve => setTimeout(resolve, retryInterval));
    }
  }

  throw new Error('❌ 网关服务启动超时');
}

async function waitForFrontendReady(): Promise<void> {
  const maxRetries = 90;
  const retryInterval = 1000;

  for (let i = 0; i < maxRetries; i++) {
    renderProgressBar('⏳ 前端服务启动中', i, maxRetries);

    try {
      const response = await fetch('http://localhost:3002', {
        signal: AbortSignal.timeout(5000) as any
      });
      if (response.ok) {
        process.stdout.write('\r' + ' '.repeat(80) + '\r');
        console.log(`✅ 前端服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`);
        return;
      }
    } catch (error) {
      // 服务还未就绪，继续等待
    }

    if (i < maxRetries - 1) {
      await new Promise(resolve => setTimeout(resolve, retryInterval));
    }
  }

  throw new Error('❌ 前端服务启动超时');
}

async function cleanupTestData(): Promise<void> {
  try {
    // 登录获取token（通过网关）
    const loginResponse = await fetch('http://localhost:8080/api/auth/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        username: 'admin',
        password: 'Test@123'
      })
    });

    if (!loginResponse.ok) {
      console.log('⚠️  无法登录，跳过数据清理');
      return;
    }

    const loginData = await loginResponse.json();
    const token = loginData.token;

    // 获取所有用户
    const usersResponse = await fetch('http://localhost:8080/api/users', {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (usersResponse.ok) {
      const users = await usersResponse.json();

      // 删除测试创建的用户（保留ID 1-10的初始用户）
      for (const user of users) {
        if (user.id > 10) {
          try {
            await fetch(`http://localhost:8080/api/users/${user.id}`, {
              method: 'DELETE',
              headers: {
                'Authorization': `Bearer ${token}`
              }
            });
            console.log(`   删除用户: ${user.username}`);
          } catch (error) {
            console.log(`   ⚠️  无法删除用户 ${user.username}`);
          }
        }
      }
    }

    // 获取所有角色
    const rolesResponse = await fetch('http://localhost:8080/api/roles', {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (rolesResponse.ok) {
      const roles = await rolesResponse.json();

      // 删除测试创建的角色（保留ID 1-4的初始角色）
      for (const role of roles) {
        if (role.id > 4) {
          try {
            await fetch(`http://localhost:8080/api/roles/${role.id}`, {
              method: 'DELETE',
              headers: {
                'Authorization': `Bearer ${token}`
              }
            });
            console.log(`   删除角色: ${role.roleName}`);
          } catch (error) {
            console.log(`   ⚠️  无法删除角色 ${role.roleName}`);
          }
        }
      }
    }

    console.log('✅ 测试数据清理完成');
  } catch (error) {
    console.log('⚠️  数据清理失败，继续执行测试');
    console.error('清理错误:', error);
  }
}

async function globalTeardown() {
  console.log('🧹 开始全局测试环境清理...');

  stopHealthMonitoring();

  if (backendProcess) {
    console.log('🛑 停止后端服务...');
    backendProcess.kill('SIGTERM');

    await new Promise<void>((resolve) => {
      if (backendProcess) {
        backendProcess.on('exit', () => {
          console.log('✅ 后端服务已停止');
          resolve();
        });

        setTimeout(() => {
          if (backendProcess) {
            backendProcess.kill('SIGKILL');
            console.log('⚠️  强制停止后端服务');
            resolve();
          }
        }, 10000);
      } else {
        resolve();
      }
    });
  }

  if (gatewayProcess) {
    console.log('🛑 停止网关服务...');
    gatewayProcess.kill('SIGTERM');

    await new Promise<void>((resolve) => {
      if (gatewayProcess) {
        gatewayProcess.on('exit', () => {
          console.log('✅ 网关服务已停止');
          resolve();
        });

        setTimeout(() => {
          if (gatewayProcess) {
            gatewayProcess.kill('SIGKILL');
            console.log('⚠️  强制停止网关服务');
            resolve();
          }
        }, 10000);
      } else {
        resolve();
      }
    });
  }

  console.log('✅ 全局测试环境清理完成');
}

export default globalSetup;
export { globalTeardown };
