import {
  Controller,
  Get,
  Post,
  Param,
  HttpCode,
  HttpStatus,
  BadRequestException,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
} from '@nestjs/swagger';
import { IntegrationsService, IntegrationType } from './integrations.service';
import {
  IntegrationsOverviewDto,
  IntegrationStatusDto,
  IntegrationHealthDto,
} from './dto';
import { RequirePermissions } from '../../auth/permissions/permissions.decorator';
import { Permission } from '../../auth/permissions/permissions.enum';

/**
 * Valid integration types for validation
 */
const VALID_INTEGRATION_TYPES: IntegrationType[] = [
  'plentyone', 'zulip', 'todoist', 'freescout', 'nextcloud', 'ecodms', 'gembadocs',
];

@ApiTags('Integrations')
@ApiBearerAuth()
@Controller('integrations')
export class IntegrationsController {
  constructor(private readonly integrationsService: IntegrationsService) {}

  @Get()
  @ApiOperation({
    summary: 'Get overview of all integrations',
    description:
      'Returns a list of all available integrations with their configuration and connection status.',
  })
  @ApiResponse({
    status: 200,
    description: 'Integrations overview',
    type: IntegrationsOverviewDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getOverview(): Promise<IntegrationsOverviewDto> {
    return this.integrationsService.getOverview();
  }

  @Get('status')
  @ApiOperation({
    summary: 'Get status of all integrations',
    description: 'Returns status information for all integration types.',
  })
  @ApiResponse({
    status: 200,
    description: 'All integration statuses',
    type: IntegrationsOverviewDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getAllStatuses(): Promise<IntegrationsOverviewDto> {
    return this.integrationsService.getOverview();
  }

  @Get(':type/status')
  @ApiOperation({
    summary: 'Get status of a specific integration',
    description:
      'Returns detailed status information for a specific integration type.',
  })
  @ApiParam({
    name: 'type',
    description: 'Integration type',
    enum: VALID_INTEGRATION_TYPES,
  })
  @ApiResponse({
    status: 200,
    description: 'Integration status',
    type: IntegrationStatusDto,
  })
  @ApiResponse({ status: 400, description: 'Invalid integration type' })
  @ApiResponse({ status: 404, description: 'Integration not found' })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getStatus(
    @Param('type') type: string,
  ): Promise<IntegrationStatusDto> {
    this.validateIntegrationType(type);
    return this.integrationsService.getIntegrationStatus(type as IntegrationType);
  }

  @Get(':type/health')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: 'Check health of a specific integration',
    description:
      'Performs a health check by testing the connection to the external service.',
  })
  @ApiParam({
    name: 'type',
    description: 'Integration type',
    enum: VALID_INTEGRATION_TYPES,
  })
  @ApiResponse({
    status: 200,
    description: 'Health check result',
    type: IntegrationHealthDto,
  })
  @ApiResponse({ status: 400, description: 'Invalid integration type' })
  @ApiResponse({ status: 404, description: 'Integration not found' })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async checkHealth(
    @Param('type') type: string,
  ): Promise<IntegrationHealthDto> {
    this.validateIntegrationType(type);
    return this.integrationsService.checkHealth(type as IntegrationType);
  }

  @Post(':type/test-connection')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: 'Test connection for a specific integration',
    description: 'Tests the connection to the external service.',
  })
  @ApiParam({
    name: 'type',
    description: 'Integration type',
    enum: VALID_INTEGRATION_TYPES,
  })
  @ApiResponse({ status: 200, description: 'Connection test result' })
  @ApiResponse({ status: 400, description: 'Invalid integration type' })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async testConnection(
    @Param('type') type: string,
  ): Promise<IntegrationHealthDto> {
    this.validateIntegrationType(type);
    return this.integrationsService.checkHealth(type as IntegrationType);
  }

  /**
   * Validate that the provided type is a valid integration type
   */
  private validateIntegrationType(type: string): void {
    if (!VALID_INTEGRATION_TYPES.includes(type as IntegrationType)) {
      throw new BadRequestException(
        `Invalid integration type '${type}'. Valid types are: ${VALID_INTEGRATION_TYPES.join(', ')}`,
      );
    }
  }
}
