// src/modules/x-router/x-router.service.ts
import {Injectable, Logger} from '@nestjs/common';
import {XCookieAccount} from "./interfaces/x-cookie.interface";
import {BrowserAccount, XBrowserService} from "./x-browser.service";
import {TwitterClient} from "./twitter.client";
import {XCookieService} from "./x-cookie.service";

export enum XStrategy {
    COOKIE_FIRST = 'cookie_first',   // rẻ nhất → fallback browser → api
    API_FIRST = 'api_first',         // ổn định nhất → fallback cookie → browser
    BROWSER_FIRST = 'browser_first', // khi cần chống bot nặng
    COOKIE_ONLY = 'cookie_only',
    API_ONLY = 'api_only',
    BROWSER_ONLY = 'browser_only',
    AUTO = 'auto',                   // dựa vào health account
    BROWSER_API = 'browser_api',
    BROWSER_COOKIE='browser_cookie'// khi cần chống bot nặng
}

export interface UnifiedAccount {
    id: string;
    api?: { accessToken: string; accessSecret: string; appKey: string; appSecret: string };
    cookie?: XCookieAccount;
    browser?: BrowserAccount;
}

export interface RouterResult {
    success: boolean;
    tweetId?: string;
    via: 'api' | 'cookie' | 'browser';
    attempts: Array<{ method: string; error?: string }>;
    error?: string;
}

@Injectable()
export class XRouterService {
    private readonly logger = new Logger(XRouterService.name);

    constructor(
        private readonly apiSvc: TwitterClient,
        private readonly cookieSvc: XCookieService,
        private readonly browserSvc: XBrowserService,
    ) {
    }

    async verifyCookie(account: XCookieAccount): Promise<any> {
        return this.cookieSvc.verifyCookie('UserByScreenName')
    }

    async postTweet(params: {
        account: UnifiedAccount;
        text: string;
        strategy?: XStrategy;
    }): Promise<RouterResult> {
        const strategy = params.strategy ?? XStrategy.COOKIE_FIRST;
        const chain = this.buildChain(strategy, params.account);
        const attempts: RouterResult['attempts'] = [];

        for (const method of chain) {
            this.logger.log(`[${params.account.id}] Trying via ${method}`);
            const result = await this.execute(method, params.account, params.text);
            attempts.push({method, error: result.error});

            if (result.success) {
                return {
                    success: true,
                    tweetId: result.tweetId,
                    via: method,
                    attempts,
                };
            }

            // Nếu lỗi không fallback được (vd: text quá dài) → dừng
            if (this.isFatalError(result.error)) {
                return {
                    success: false,
                    via: method,
                    attempts,
                    error: result.error,
                };
            }
        }

        return {
            success: false,
            via: chain[chain.length - 1],
            attempts,
            error: 'All methods failed',
        };
    }

    /** Xây chain dựa trên strategy + account capabilities */
    private buildChain(
        strategy: XStrategy,
        account: UnifiedAccount,
    ): Array<'api' | 'cookie' | 'browser'> {
        const has = {
            api: !!account.api,
            cookie: !!account.cookie,
            browser: !!account.browser,
        };

        const chains: Record<XStrategy, Array<'api' | 'cookie' | 'browser'>> = {
            [XStrategy.BROWSER_API]: ['browser', 'api'],
            [XStrategy.COOKIE_FIRST]: ['cookie', 'browser', 'api'],
            [XStrategy.API_FIRST]: ['api', 'cookie', 'browser'],
            [XStrategy.BROWSER_FIRST]: ['browser', 'cookie', 'api'],
            [XStrategy.COOKIE_ONLY]: ['cookie'],
            [XStrategy.API_ONLY]: ['api'],
            [XStrategy.BROWSER_ONLY]: ['browser'],
            [XStrategy.BROWSER_COOKIE]: ['browser', 'cookie'],
            [XStrategy.AUTO]: ['cookie', 'browser', 'api'], // có thể dựa health store
        };

        return chains[strategy].filter((m) => has[m]);
    }

    private async execute(
        method: 'api' | 'cookie' | 'browser',
        account: UnifiedAccount,
        text: string,
    ): Promise<{ success: boolean; tweetId?: string; error?: string }> {
        try {
            if (method === 'api' && account.api) {
                const {data: r} = await this.apiSvc.postSimpleTwitte(text);
                return {
                    tweetId: r.id,
                    success: true,
                }
            }
            if (method === 'cookie' && account.cookie) {
                // return await this.cookieSvc.createTweet(account.cookie, {text});
            }
            if (method === 'browser' && account.browser) {
                return await this.browserSvc.postTweet(account.browser, text);
            }
            return {success: false, error: `Method ${method} not configured`};
        } catch (e: any) {
            return {success: false, error: e.message};
        }
    }

    private isFatalError(error?: string): boolean {
        if (!error) return false;
        const fatalPatterns = [
            /duplicate/i,
            /too long/i,
            /forbidden content/i,
            /suspended/i,
        ];
        return fatalPatterns.some((p) => p.test(error));
    }
}
