import {
  Controller,
  Get,
  Post,
  Param,
  Body,
  UseGuards,
  HttpCode,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import { LaravelApiService } from './laravel-api.service';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { UserJwtGuard } from '../auth/guards/user-jwt.guard';
import { ClientJwtGuard } from '../auth/guards/client-jwt.guard';
import { User } from '../auth/decorators/user.decorator';
import {
  Token,
  TokenData,
  JwtPayload,
  UserUuid,
  UserEmail,
  UserName,
} from '../auth/decorators/token.decorator';
import { AuthenticatedUser } from '../auth/interfaces/jwt-payload.interface';
import { ApiKeyGuard } from '../common/guards/api-key/api-key.guard';
import { DevOnlyGuard } from '../common/guards/dev-only/dev-only.guard';

@Controller('laravel-api')
@UseGuards(ApiKeyGuard)
export class LaravelApiController {
  private readonly logger = new Logger(LaravelApiController.name);

  constructor(private readonly laravelApiService: LaravelApiService) {}

  /**
   * Endpoint de teste para verificar a integração com Laravel
   */
  @Get('health')
  @UseGuards(JwtAuthGuard)
  checkHealth(@User() user: AuthenticatedUser, @Token() token: string) {
    return {
      message: 'Integração BFF -> Laravel API funcionando',
      user: {
        id: user.id,
        type: user.type,
        tokenData: user.tokenData as Record<string, unknown>,
      },
      tokenAvailable: !!token,
    };
  }

  /**
   * Valida token diretamente com a API Laravel
   */
  @Post('validate-token')
  @UseGuards(JwtAuthGuard)
  @HttpCode(HttpStatus.OK)
  async validateToken(@Token() token: string, @User() user: AuthenticatedUser) {
    try {
      const laravelResponse =
        await this.laravelApiService.validateTokenWithLaravel(token);

      return {
        valid: true,
        bffUser: user,
        laravelUser: laravelResponse,
        message: 'Token válido em ambos os sistemas',
      };
    } catch (error: unknown) {
      return {
        valid: false,
        error: error instanceof Error ? error.message : 'Erro desconhecido',
        bffUser: user,
      };
    }
  }

  /**
   * Obtém dados do usuário da API Laravel
   */
  @Get('user/profile')
  @UseGuards(UserJwtGuard)
  async getUserProfile(
    @Token() token: string,
    @UserUuid() uuid: string,
    @UserEmail() email: string,
    @UserName() name: string,
  ) {
    const laravelResponse =
      await this.laravelApiService.getUserFromLaravel(token);

    return {
      source: 'Laravel API',
      tokenData: {
        uuid,
        email,
        name,
      },
      laravelData: laravelResponse.data,
    };
  }

  /**
   * Obtém dados do client da API Laravel
   */
  @Get('client/profile')
  @UseGuards(ClientJwtGuard)
  async getClientProfile(
    @Token() token: string,
    @TokenData() tokenData: Record<string, any>,
  ) {
    const laravelResponse =
      await this.laravelApiService.getClientFromLaravel(token);

    return {
      source: 'Laravel API',
      tokenData,
      laravelData: laravelResponse.data,
    };
  }

  /**
   * Proxy genérico para qualquer endpoint da API Laravel
   */
  @Post('proxy/*path')
  @HttpCode(200)
  @UseGuards(JwtAuthGuard)
  async proxyRequest(
    @Param('path') endpoint: string,
    @Body()
    body: {
      method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
      data?: any;
      params?: Record<string, any>;
      headers?: Record<string, string>;
    },
    @Token() token: string,
    @User() user: AuthenticatedUser,
  ) {
    const method = body.method || 'GET';

    this.logger.log(`🔄 Proxying ${method} request to Laravel: /${endpoint}`);

    const response = await this.laravelApiService.proxyRequest(
      token,
      method,
      `/${endpoint}`,
      body.data,
      body.params,
      body.headers,
    );

    return {
      source: 'Laravel API via BFF Proxy',
      endpoint: `/${endpoint}`,
      method,
      bffUser: {
        id: user.id,
        type: user.type,
        tokenData: user.tokenData as Record<string, unknown>,
      },
      response: response.data,
      status: response.status,
    };
  }

  /**
   * Endpoint para debugar todos os dados disponíveis do token
   */
  @Get('debug/token')
  @UseGuards(DevOnlyGuard, JwtAuthGuard)
  debugToken(
    @User() user: AuthenticatedUser,
    @Token() token: string,
    @TokenData() tokenData: Record<string, any>,
    @JwtPayload() jwtPayload: Record<string, any>,
    @UserUuid() uuid: string,
    @UserEmail() email: string,
    @UserName() name: string,
  ) {
    return {
      message: 'Debug completo do token JWT',
      data: {
        user: {
          id: user.id,
          type: user.type,
          expiresAt: user.expiresAt,
          issuedAt: user.issuedAt,
        },
        rawToken: token,
        tokenData,
        jwtPayload,
        extractedFields: {
          uuid,
          email,
          name,
        },
        tokenLength: token?.length || 0,
        tokenParts: token ? token.split('.').length : 0,
      },
    };
  }

  /**
   * Testa requisição específica para endpoint de usuário da API Laravel
   */
  @Get('test/user-endpoint')
  @UseGuards(UserJwtGuard)
  async testUserEndpoint(@Token() token: string) {
    const response = await this.laravelApiService.proxyRequest(
      token,
      'GET',
      '/api/user',
    );

    return {
      message: 'Teste de endpoint de usuário da API Laravel',
      response: response.data,
      status: response.status,
    };
  }

  /**
   * Testa requisição específica para endpoint de client da API Laravel
   */
  @Get('test/client-endpoint')
  @UseGuards(ClientJwtGuard)
  async testClientEndpoint(@Token() token: string) {
    const response = await this.laravelApiService.proxyRequest(
      token,
      'GET',
      '/api/client/me',
    );

    return {
      message: 'Teste de endpoint de client da API Laravel',
      response: response.data,
      status: response.status,
    };
  }
}
