import {Controller, Get, HttpException, Param, Post, Query, Req} from '@nestjs/common';
import {AppService} from './app.service';
import {AIService} from "./shared/ai.service";
import {PgPostService} from "./shared/pg.post.service";
import {PublishPageService} from "./modules/social-api/publish.page.service";
import {TwitterClient} from "./modules/social-api/twitter.client";
import {normalizeTagsSingleCashtag} from "./shared/helper";
import {XReaderService} from "./modules/x-reader/x-reader.service";
import {XCacheService} from "./modules/x-cache/x-cache.service";
import {SqsPostService} from "./modules/sqs-module/sqs.post.service";

@Controller()
export class AppController {
    constructor(
        private readonly appService: AppService,
        private readonly aiService: AIService,
        private readonly pgPostService: PgPostService,
        private readonly publishPageService: PublishPageService,
        private readonly twitterClient: TwitterClient,
        private readonly cacheService: XCacheService,
        private readonly xReaderService: XReaderService,
        private readonly sqsPostService: SqsPostService,
    ) {
    }

    @Get()
    getHello(): string {
        return this.appService.getHello();
    }

    @Get('test-gemini-ai')
    async testAI() {
        console.log('Test gọi gemini AI trực tiếp...');
        // return await this.aiService.listAvailableModels();
        const title = 'bitcoin bullish';
        const result = await this.aiService.generateContentViaGemini(title, 'crypto', 'en');
        return result;
        console.log({result});
        const newPost = await this.pgPostService.createPost({
            title: title,
            content: result.content,
            style: 'crypto',
            status: 'pending',
            prompt: result.prompt,
        });
        return newPost;
    }

    @Get('test-chatgpt-ai')
    async testChatGPTAi(@Query('input') input: string) {
        console.log(`Test gọi chatgpt AI trực tiếp with input ${input}...`);
        // return await this.aiService.listAvailableModels();
        if (!input) {
            return 'No input';
        }
        const openai = await this.aiService.getChatgptModel();
        const resp = await openai.responses.create({
            model: "gpt-5-nano",
            input,
            store: true,
        });
        return resp.output_text;
    }

    @Get('test-deepseek-ai')
    async testDeepSeekAI() {
        console.log('Test gọi deepseed AI trực tiếp...');
        // return await this.aiService.listAvailableModels();
        const title = 'bitcoin bullish'
        const result = await this.aiService.generateContentViaDeepseek(title, 'crypto',);
        console.log({result});
        return result;

        const newPost = await this.pgPostService.createPost({
            title: title,
            content: result.final,
            style: 'crypto',
            status: 'pending',
            prompt: result.prompt,
        });
        return newPost;
    }

    @Get('test-list-ai')
    async listModelGeminiAI() {
        console.log('Test gọi AI trực tiếp...');
        // return await this.aiService.listAvailableModels();
        return await this.aiService.listAvailableModels();
    }

    @Get('test-save-post')
    async testSavePost() {
        return this.pgPostService.createPost({
            title: 'zz',
            prompt: 'xx',
            content: 'xx',
            imageUrl: 'xx.png',

        })
    }

    @Get('test-publish-post/:id')
    async testPostFb(@Param('id') id: number) {
        console.log({id});
        console.log('testPostFb==>')
        return this.publishPageService.publishToFacebook(1 * id)
    }

    @Get('test-reply-post/:id')
    async testReplyX(@Param('id') id: string, @Query('comment') input: string) {
        console.log({id});
        console.log('testReplyX==>')
        // return this.publishPageService.relyX(input, id)
    }

    @Get('post/:id')
    async showPostFb(@Param('id') id: number) {
        console.log({id});
        let post = await this.pgPostService.post({id: id * 1})
        if (!post) {
            return 'no post';
        }
        const _normalizeTagsSingleCashtagContent = normalizeTagsSingleCashtag(post.content);

        return {
            content: post.content,
            _content: _normalizeTagsSingleCashtagContent
        };
    }

    @Get('tw_callback')
    async twitterAuthCallback(
        @Query('code') code: string,
        @Query('state') state: string,
        @Req() request: Request) {

        console.log('twitterAuthCallback==>')
        const cacheAuthData = await this.cacheService.getCachedData('tw_authorize');
        console.log({cacheAuthData});
        //@ts-ignore
        const {codeVerifier, state: sessionState} = cacheAuthData || {}

        if (!codeVerifier || !state || !sessionState || !code) {
            throw new HttpException('You denied the app or your session expired!', 400)
        }
        if (state !== sessionState) {
            throw new HttpException('Stored tokens didnt match!!', 400)
        }

        const client = await this.twitterClient.getTwitterClientV2();

        const {client: loggedClient, accessToken, refreshToken} = await client.loginWithOAuth2({
            code,
            codeVerifier: codeVerifier,
            redirectUri: 'http://localhost:3000/tw_callback'
        });

        await this.cacheService.setCachedKey('tw_accesstoken_time_add', Date.now(), 3 * 24 * 3600);
        await this.cacheService.setCachedKey('tw_accesstoken', accessToken, 3 * 24 * 3600);
        await this.twitterClient.setCacheRefreshToken('' + refreshToken);
        console.log({loggedClient, accessToken, refreshToken});
        // @ts-ignore
        const {data: userObject} = loggedClient.v2.me();

        return userObject;

    }

    @Get('tw_authorize')
    async twitterAuthorize() {
        const client = await this.twitterClient.getTwitterClientV2();
        const {url, codeVerifier, state} = client.generateOAuth2AuthLink('http://localhost:3000/tw_callback',
            {
                scope:
                    [
                        'tweet.read',
                        'tweet.write',
                        'users.read',
                        'offline.access',
                        'media.write',

                    ]
            });
        // Redirect your client to {url}
        console.log('Please go to', url);
        console.log({codeVerifier, state});
        await this.cacheService.setCachedKey('tw_authorize', {codeVerifier, state});

        return this.cacheService.getCachedData('tw_authorize');

// Redirect your client to authLink.url
//         console.log('Please go to', authLink.url);
    }

    @Get('/tw/post/:id')
    async testPostTwitter(@Param('id') id: number) {
        return this.publishPageService.publishTwitter(id * 1)
    }

    @Get('/tw/me')
    async testTwitterMe() {
        const client = await this.twitterClient.getTwitterClientV2ViaAccessToken();
        const me = client.v2.me();
        return me;
    }

    @Get('/tw/read')
    async getTwitterMe(@Query('url') url: string, @Query('via') via: string = 'api') {
        if (via === 'browser') {
            return this.xReaderService.readXPostViaBrowserV2(url)
        }
        return this.xReaderService.readXPostViaApi(url)
    }

    @Post('/sqs/send')
    async postSqsQueueTest() {
        // return this.sqsPostService.postFlashKaze({
        //     content: 'aaa',
        //     id: 1
        // })

    }
}
