import { Controller, Get, Query, Res, HttpStatus, Logger } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { ConfigService } from '@nestjs/config';
import type { Response } from 'express';
import { MetaAdsService } from '../meta-ads/services/meta-ads.service';
import { TikTokAdsService } from '../tiktok-ads/services/tiktok-ads.service';
import { GoogleAdsService } from '../google-ads/services/google-ads.service';

@ApiTags('auth')
@Controller('auth')
export class AuthController {
  private readonly logger = new Logger(AuthController.name);

  constructor(
    private readonly configService: ConfigService,
    private readonly metaAdsService: MetaAdsService,
    private readonly tiktokAdsService: TikTokAdsService,
    private readonly googleAdsService: GoogleAdsService,
  ) {}

  async loginToMeta(@Query('userId') userId: string, @Res() res: Response) {
    const appId = this.configService.get<string>('meta.appId');
    const redirectUri = this.configService.get<string>('meta.redirectUri');
    const state = userId || 'default';
    const url = `https://www.facebook.com/v19.0/dialog/oauth?client_id=${appId}&redirect_uri=${redirectUri}&scope=ads_management,ads_read,public_profile,email&state=${state}`;
    return res.redirect(url);
  }

  async metaCallback(@Query('code') code: string, @Query('state') state: string, @Res() res: Response) {
    if (!code) return res.status(HttpStatus.BAD_REQUEST).json({ message: 'No code provided' });
    try {
      this.logger.log(`Received Meta OAuth callback. State: ${state}`);
      const shortToken = await this.metaAdsService.exchangeCodeForToken(code);
      const longToken = await this.metaAdsService.getLongLivedToken(shortToken);
      const adAccounts = await this.metaAdsService.getAdAccounts(longToken);
      
      // If we have a userId in state, automatically save first account
      if (state && state !== 'default' && adAccounts.length > 0) {
        await this.metaAdsService.connectAccount({
          userId: state,
          platform: 'meta',
          accessToken: longToken,
          adAccountId: adAccounts[0].id,
          name: adAccounts[0].name || 'Meta Account (OAuth)'
        });
      }

      // Redirect back to dashboard with success
      const frontendUrl = 'http://localhost:5001'; // Should be dynamic in prod
      return res.redirect(`${frontendUrl}?auth=success&platform=meta`);
    } catch (error) {
      this.logger.error('Meta Auth failed:', error.message);
      return res.redirect('http://localhost:5001?auth=failed');
    }
  }

  @Get('tiktok')
  @ApiOperation({ summary: 'Redirect to TikTok Login | التوجيه لتسجيل الدخول بتيك توك' })
  async loginToTikTok(@Res() res: Response) {
    const appId = this.configService.get<string>('tiktok.appId');
    const redirectUriRaw = this.configService.get<string>('tiktok.redirectUri');
    
    if (!appId || !redirectUriRaw) {
      return res.status(HttpStatus.BAD_REQUEST).json({ 
        message: 'TikTok OAuth is not configured. Please add TIKTOK_APP_ID and TIKTOK_REDIRECT_URI to .env' 
      });
    }

    const redirectUri = btoa(redirectUriRaw);
    const url = `https://business-api.tiktok.com/portal/auth?app_id=${appId}&state=state&redirect_uri=${redirectUri}`;
    return res.redirect(url);
  }

  @Get('tiktok/callback')
  @ApiOperation({ summary: 'TikTok OAuth Callback | استقبال كود تيك توك' })
  async tiktokCallback(@Query('auth_code') code: string, @Res() res: Response) {
    if (!code) return res.status(HttpStatus.BAD_REQUEST).json({ message: 'No code provided' });
    try {
      const token = await this.tiktokAdsService.exchangeCodeForToken(code);
      const accounts = await this.tiktokAdsService.getAdAccounts(token);
      return res.status(HttpStatus.OK).json({ message: 'TikTok Connected', accessToken: token, accounts });
    } catch (error) {
      return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: 'TikTok Auth failed' });
    }
  }

  @Get('google')
  @ApiOperation({ summary: 'Redirect to Google Login | التوجيه لتسجيل الدخول بجوجل' })
  async loginToGoogle(@Res() res: Response) {
    const clientId = this.configService.get<string>('google.clientId');
    const redirectUri = this.configService.get<string>('google.redirectUri');
    
    if (!clientId || !redirectUri) {
      return res.status(HttpStatus.BAD_REQUEST).json({ 
        message: 'Google Ads OAuth is not configured. Please add GOOGLE_CLIENT_ID and GOOGLE_REDIRECT_URI to .env' 
      });
    }

    const url = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=code&scope=https://www.googleapis.com/auth/adwords&access_type=offline&prompt=consent`;
    return res.redirect(url);
  }

  @Get('google/callback')
  @ApiOperation({ summary: 'Google OAuth Callback | استقبال كود جوجل' })
  async googleCallback(@Query('code') code: string, @Res() res: Response) {
    if (!code) return res.status(HttpStatus.BAD_REQUEST).json({ message: 'No code provided' });
    try {
      const token = await this.googleAdsService.exchangeCodeForToken(code);
      const accounts = await this.googleAdsService.getAdAccounts(token);
      return res.status(HttpStatus.OK).json({ message: 'Google Connected', accessToken: token, accounts });
    } catch (error) {
      return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: 'Google Auth failed' });
    }
  }
}
