#!/usr/bin/env node

import { writeFileSync, existsSync } from "fs";
import { createInterface } from "readline/promises";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
import { execSync } from "child_process";
import open from "open";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = join(__dirname, "..");

class WordPressSetup {
  constructor() {
    this.rl = createInterface({
      input: process.stdin,
      output: process.stdout,
    });
    this.config = {};
    this.envPath = join(rootDir, ".env");
  }

  async run() {
    try {
      console.log("🔧 WordPress MCP Server Setup");
      console.log("==============================\n");

      await this.detectExistingConfig();
      await this.gatherConfiguration();
      await this.testConnection();
      await this.saveConfiguration();
      await this.showNextSteps();
    } catch (error) {
      console.error("❌ Setup failed:", error.message);
      process.exit(1);
    } finally {
      this.rl.close();
    }
  }

  async detectExistingConfig() {
    if (existsSync(this.envPath)) {
      const answer = await this.rl.question("⚠️  Existing configuration found. Overwrite? (y/N): ");
      if (answer.toLowerCase() !== "y") {
        console.log("Setup cancelled.");
        process.exit(0);
      }
    }
  }

  async gatherConfiguration() {
    console.log("📝 WordPress Site Configuration\n");

    // WordPress URL
    this.config.WORDPRESS_URL = await this.rl.question("WordPress Site URL (e.g., https://example.com): ");
    if (!this.config.WORDPRESS_URL.startsWith("http")) {
      this.config.WORDPRESS_URL = "https://" + this.config.WORDPRESS_URL;
    }
    this.config.WORDPRESS_URL = this.config.WORDPRESS_URL.replace(/\/$/, "");

    // Authentication method
    console.log("\n🔐 Authentication Method:");
    console.log("1. Application Password (Recommended)");
    console.log("2. Basic Authentication (Username/Password)");
    console.log("3. JWT Token");
    console.log("4. API Key");

    const authChoice = await this.rl.question("Choose authentication method (1-4): ");

    switch (authChoice) {
      case "1":
        await this.setupApplicationPassword();
        break;
      case "2":
        await this.setupBasicAuth();
        break;
      case "3":
        await this.setupJWT();
        break;
      case "4":
        await this.setupAPIKey();
        break;
      default:
        console.log("Invalid choice, defaulting to Application Password");
        await this.setupApplicationPassword();
    }

    // Optional settings
    console.log("\n⚙️  Optional Settings:");

    const debugAnswer = await this.rl.question("Enable debug logging? (y/N): ");
    this.config.DEBUG = debugAnswer.toLowerCase() === "y" ? "true" : "false";

    const cacheAnswer = await this.rl.question("Enable caching? (Y/n): ");
    this.config.ENABLE_CACHE = cacheAnswer.toLowerCase() === "n" ? "false" : "true";

    const rateLimit = await this.rl.question("Rate limit (requests per minute, default 60): ");
    this.config.RATE_LIMIT = rateLimit || "60";
  }

  async setupApplicationPassword() {
    this.config.AUTH_METHOD = "app-password";
    this.config.USERNAME = await this.rl.question("WordPress Username: ");

    console.log("\n📱 Application Password Setup:");
    console.log("1. Go to your WordPress admin dashboard");
    console.log("2. Navigate to Users > Profile");
    console.log('3. Scroll to "Application Passwords"');
    console.log('4. Enter "MCP WordPress Server" as the name');
    console.log('5. Click "Add New Application Password"');
    console.log("6. Copy the generated password (it will only be shown once)");

    const openBrowser = await this.rl.question("\nOpen WordPress admin in browser? (Y/n): ");
    if (openBrowser.toLowerCase() !== "n") {
      try {
        await open(`${this.config.WORDPRESS_URL}/wp-admin/profile.php#application-passwords-section`);
      } catch {
        console.log("Could not open browser automatically");
      }
    }

    this.config.APPLICATION_PASSWORD = await this.rl.question("\nPaste Application Password: ");
  }

  async setupBasicAuth() {
    this.config.AUTH_METHOD = "basic";
    this.config.USERNAME = await this.rl.question("WordPress Username: ");
    this.config.PASSWORD = await this.rl.question("WordPress Password: ");

    console.log("\n⚠️  Note: Basic authentication may require additional plugin setup");
  }

  async setupJWT() {
    this.config.AUTH_METHOD = "jwt";
    this.config.JWT_SECRET = await this.rl.question("JWT Secret Key: ");
    this.config.USERNAME = await this.rl.question("WordPress Username: ");
    this.config.PASSWORD = await this.rl.question("WordPress Password: ");

    console.log("\n⚠️  Note: JWT authentication requires JWT Authentication plugin");
  }

  async setupAPIKey() {
    this.config.AUTH_METHOD = "api-key";
    this.config.API_KEY = await this.rl.question("API Key: ");
    this.config.API_SECRET = await this.rl.question("API Secret (if required): ");
  }

  async ensureBuild() {
    console.log("🔨 Building TypeScript project...");
    try {
      execSync("npm run build", { cwd: rootDir, stdio: "pipe" });
      console.log("✅ Build successful!");
    } catch (error) {
      throw new Error('TypeScript build failed. Please run "npm run build" manually.');
    }
  }

  async testConnection() {
    console.log("\n🔄 Testing WordPress connection...");

    // Ensure TypeScript is compiled
    await this.ensureBuild();

    try {
      // Create a temporary client to test connection
      const { WordPressClient } = await import("../dist/client/api.js");
      const client = new WordPressClient({
        baseUrl: this.config.WORDPRESS_URL,
        auth: this.getAuthConfig(),
      });

      await client.authenticate();
      const sites = await client.get("/wp/v2/");

      console.log("✅ Connection successful!");
      console.log(`   Site: ${sites.name || "WordPress Site"}`);
      console.log(`   URL: ${this.config.WORDPRESS_URL}`);
    } catch (error) {
      console.log("❌ Connection failed:", error.message);
      const retry = await this.rl.question("Retry with different settings? (y/N): ");
      if (retry.toLowerCase() === "y") {
        await this.gatherConfiguration();
        return this.testConnection();
      }
      throw error;
    }
  }

  getAuthConfig() {
    switch (this.config.AUTH_METHOD) {
      case "app-password":
        return {
          method: "app-password",
          username: this.config.USERNAME,
          appPassword: this.config.APPLICATION_PASSWORD,
        };
      case "basic":
        return {
          method: "basic",
          username: this.config.USERNAME,
          password: this.config.PASSWORD,
        };
      case "jwt":
        return {
          method: "jwt",
          secret: this.config.JWT_SECRET,
          username: this.config.USERNAME,
          password: this.config.PASSWORD,
        };
      case "api-key":
        return {
          method: "api-key",
          apiKey: this.config.API_KEY,
          secret: this.config.API_SECRET,
        };
      default:
        throw new Error("Invalid authentication method");
    }
  }

  async saveConfiguration() {
    console.log("\n💾 Saving configuration...");

    // Map config keys to environment variable names
    const envVars = {
      WORDPRESS_SITE_URL: this.config.WORDPRESS_URL,
      WORDPRESS_USERNAME: this.config.USERNAME,
      WORDPRESS_AUTH_METHOD: this.config.AUTH_METHOD,
    };

    if (this.config.APPLICATION_PASSWORD) {
      envVars["WORDPRESS_APP_PASSWORD"] = this.config.APPLICATION_PASSWORD;
    }
    if (this.config.PASSWORD) {
      envVars["WORDPRESS_PASSWORD"] = this.config.PASSWORD;
    }
    if (this.config.JWT_SECRET) {
      envVars["WORDPRESS_JWT_SECRET"] = this.config.JWT_SECRET;
    }
    if (this.config.API_KEY) {
      envVars["WORDPRESS_API_KEY"] = this.config.API_KEY;
    }
    if (this.config.API_SECRET) {
      envVars["WORDPRESS_API_SECRET"] = this.config.API_SECRET;
    }

    const envContent = Object.entries(envVars)
      .map(([key, value]) => `${key}=${value}`)
      .join("\n");

    writeFileSync(this.envPath, envContent);
    console.log("✅ Configuration saved to .env file");
  }

  async showNextSteps() {
    console.log("\n🎉 Setup Complete!");
    console.log("==================");
    console.log("\nNext steps:");
    console.log("1. Test the server: npm run status");
    console.log("2. Run integration tests: npm test");
    console.log("3. Start the MCP server: npm start");
    console.log("\nFor Claude Desktop integration:");
    console.log("Add this to your Claude Desktop MCP settings:");
    console.log(`
{
  "mcpServers": {
    "wordpress": {
      "command": "node",
      "args": ["${join(rootDir, "dist/index.js")}"],
      "env": {
        "WORDPRESS_SITE_URL": "${this.config.WORDPRESS_URL}",
        "WORDPRESS_AUTH_METHOD": "${this.config.AUTH_METHOD}",
        ${this.getEnvVarsForClaudeConfig()}
      }
    }
  }
}
    `);
  }

  getEnvVarsForClaudeConfig() {
    const envVars = [];
    if (this.config.USERNAME) envVars.push(`"WORDPRESS_USERNAME": "${this.config.USERNAME}"`);
    if (this.config.APPLICATION_PASSWORD)
      envVars.push(`"WORDPRESS_APP_PASSWORD": "${this.config.APPLICATION_PASSWORD}"`);
    if (this.config.PASSWORD) envVars.push(`"WORDPRESS_PASSWORD": "${this.config.PASSWORD}"`);
    if (this.config.JWT_SECRET) envVars.push(`"WORDPRESS_JWT_SECRET": "${this.config.JWT_SECRET}"`);
    if (this.config.API_KEY) envVars.push(`"WORDPRESS_API_KEY": "${this.config.API_KEY}"`);
    if (this.config.API_SECRET) envVars.push(`"WORDPRESS_API_SECRET": "${this.config.API_SECRET}"`);
    return envVars.join(",\n        ");
  }
}

// Run setup if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
  const setup = new WordPressSetup();
  setup.run();
}

export { WordPressSetup };
