/**
 * AdsPower Provider实现
 */

import { BaseBrowserProvider } from '../../core/base/BaseBrowserProvider';
import { IBrowserCapabilities, ILaunchOptions, ILaunchResult } from '../../core/types';
import { AdsPowerActionFactory } from './core/ActionFactory';
import axios from 'axios';
const puppeteer = require('puppeteer');

export interface IAdsPowerConfig {
  profileId?: string;
  apiBase?: string;
  apiKey?: string;
  siteName?: string;
  incognitoMode?: boolean;
}

export class AdsPowerProvider extends BaseBrowserProvider {
  private profileId: string;
  private apiBase: string;
  private apiKey?: string;
  private siteName: string;
  private incognitoMode: boolean;

  constructor(config: IAdsPowerConfig = {}) {
    super(config);
    
    this.profileId = config.profileId || process.env.ADSPOWER_USER_ID || '';
    this.apiBase = config.apiBase || process.env.ADSPOWER_API || 'http://127.0.0.1:50325';
    this.apiKey = config.apiKey || process.env.ADSPOWER_API_KEY || '35de43696f6241f3df895f2f48777a99';
    this.siteName = config.siteName || 'AdsPower';
    this.incognitoMode = config.incognitoMode !== false;
  }

  getName(): string {
    return 'AdsPower';
  }

  getVersion(): string {
    return '1.0.0';
  }

  isFree(): boolean {
    return false;
  }

  getCapabilities(): IBrowserCapabilities {
    return {
      stealth: true,
      fingerprint: true,
      proxy: true,
      incognito: true,
      profiles: true,
      cloudflareBypass: true,
      stripeCompatible: true
    };
  }

  async validateConfig(): Promise<boolean> {
    if (!this.profileId) {
      throw new Error('AdsPower Profile ID is required (ADSPOWER_USER_ID)');
    }
    return true;
  }

  async launch(options?: ILaunchOptions): Promise<ILaunchResult> {
    console.log(`[${this.siteName}] Launching AdsPower browser...`);
    
    await this.validateConfig();

    const startUrl = this.buildStartUrl();
    const headers = this.buildHeaders();

    try {
      const response = await axios.get(startUrl, { headers });
      const data = response.data;

      if (data.code !== 0) {
        throw new Error(`AdsPower API error: ${data.msg || JSON.stringify(data)}`);
      }

      const wsEndpoint = this.extractWsEndpoint(data);
      console.log(`[${this.siteName}] WebSocket: ${wsEndpoint}`);

      this.browser = await puppeteer.connect({
        browserWSEndpoint: wsEndpoint,
        defaultViewport: options?.viewport || null
      });

      await this.setupPage();

      console.log(`[${this.siteName}] ✅ AdsPower browser connected`);

      return {
        browser: this.browser,
        page: this.page,
        wsEndpoint
      };

    } catch (error: any) {
      console.error(`[${this.siteName}] ❌ Failed to launch: ${error.message}`);
      throw error;
    }
  }

  async close(): Promise<void> {
    if (!this.browser) {
      console.warn(`[${this.siteName}] Browser not initialized`);
      return;
    }

    try {
      await this.closeAllPages();
      await this.browser.disconnect();
      await this.stopBrowserProcess();

      this.browser = null;
      this.page = null;

      console.log(`[${this.siteName}] ✅ Browser closed`);
    } catch (error: any) {
      console.error(`[${this.siteName}] Error closing browser: ${error.message}`);
      throw error;
    }
  }

  getActionFactory(): AdsPowerActionFactory {
    return new AdsPowerActionFactory();
  }

  // ========== Private Methods ==========

  private buildStartUrl(): string {
    const params = new URLSearchParams({
      user_id: this.profileId
    });

    if (this.incognitoMode) {
      params.append('clear_cache_after_closing', '1');
    }

    return `${this.apiBase}/api/v1/browser/start?${params.toString()}`;
  }

  private buildHeaders(): Record<string, string> {
    const headers: Record<string, string> = {};
    if (this.apiKey) {
      headers['Authorization'] = `Bearer ${this.apiKey}`;
    }
    return headers;
  }

  private extractWsEndpoint(data: any): string {
    const wsEndpoint = data.data.ws?.puppeteer || 
                      data.data.ws?.selenium || 
                      data.data.ws?.ws || 
                      data.data.ws;

    if (!wsEndpoint) {
      throw new Error('AdsPower did not return WebSocket endpoint');
    }

    return wsEndpoint;
  }

  private async setupPage(): Promise<void> {
    const pages = await this.browser.pages();
    this.page = pages[0] || await this.browser.newPage();

    if (pages.length > 1) {
      for (let i = 1; i < pages.length; i++) {
        try {
          await pages[i].close();
        } catch (e) {
          // Ignore
        }
      }
    }
  }

  private async closeAllPages(): Promise<void> {
    try {
      const pages = await this.browser.pages();
      for (const page of pages) {
        try {
          await page.close();
        } catch (e) {
          // Ignore
        }
      }
    } catch (e) {
      // Ignore
    }
  }

  private async stopBrowserProcess(): Promise<void> {
    if (!this.profileId) return;

    const stopUrl = `${this.apiBase}/api/v1/browser/stop?user_id=${encodeURIComponent(this.profileId)}`;
    const headers = this.buildHeaders();

    try {
      const response = await axios.get(stopUrl, { headers });
      const data = response.data;

      if (data.code === 0) {
        console.log(`[${this.siteName}] ✅ Browser process stopped`);
      }
    } catch (e: any) {
      console.warn(`[${this.siteName}] Failed to stop browser process: ${e.message}`);
    }
  }
}
