import {
  Controller,
  Get,
  Post,
  Delete,
  Body,
  Query,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiBody,
} from '@nestjs/swagger';
import { ZulipService } from './zulip.service';
import {
  GetMessagesQueryDto,
  SendStreamMessageDto,
  SendPrivateMessageDto,
  GetStreamsQueryDto,
  SubscribeRequestDto,
  GetUsersQueryDto,
  MessageResponseDto,
  MessagesListResponseDto,
  SendMessageResponseDto,
  StreamResponseDto,
  StreamSubscriptionResponseDto,
  UserResponseDto,
} from './dto';
import { ConnectionTestResult } from '../base-connector';
import { RequirePermissions } from '../../../../auth/permissions/permissions.decorator';
import { Permission } from '../../../../auth/permissions/permissions.enum';

@ApiTags('Integrations - ZULIP')
@ApiBearerAuth()
@Controller('integrations/zulip')
export class ZulipController {
  constructor(private readonly zulipService: ZulipService) {}

  @Post('test')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Test ZULIP connection' })
  @ApiResponse({
    status: 200,
    description: 'Connection test result',
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async testConnection(): Promise<ConnectionTestResult> {
    return this.zulipService.testConnection();
  }

  // ===========================================================================
  // Messages
  // ===========================================================================

  @Get('messages')
  @ApiOperation({ summary: 'Get messages' })
  @ApiResponse({
    status: 200,
    description: 'List of messages',
    type: MessagesListResponseDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getMessages(
    @Query() query: GetMessagesQueryDto,
  ): Promise<MessagesListResponseDto> {
    return this.zulipService.getMessages(query);
  }

  @Post('messages')
  @ApiOperation({ summary: 'Send a message to a stream' })
  @ApiResponse({
    status: 201,
    description: 'Message sent successfully',
    type: SendMessageResponseDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async sendStreamMessage(
    @Body() dto: SendStreamMessageDto,
  ): Promise<SendMessageResponseDto> {
    return this.zulipService.sendStreamMessage(dto);
  }

  @Post('messages/private')
  @ApiOperation({ summary: 'Send a private message' })
  @ApiResponse({
    status: 201,
    description: 'Message sent successfully',
    type: SendMessageResponseDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async sendPrivateMessage(
    @Body() dto: SendPrivateMessageDto,
  ): Promise<SendMessageResponseDto> {
    return this.zulipService.sendPrivateMessage(dto);
  }

  // ===========================================================================
  // Streams
  // ===========================================================================

  @Get('streams')
  @ApiOperation({ summary: 'Get list of streams' })
  @ApiResponse({
    status: 200,
    description: 'List of streams',
    type: [StreamResponseDto],
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getStreams(
    @Query() query: GetStreamsQueryDto,
  ): Promise<StreamResponseDto[]> {
    return this.zulipService.getStreams(query);
  }

  @Get('streams/subscriptions')
  @ApiOperation({ summary: 'Get subscribed streams' })
  @ApiResponse({
    status: 200,
    description: 'List of subscribed streams',
    type: [StreamSubscriptionResponseDto],
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getSubscriptions(): Promise<StreamSubscriptionResponseDto[]> {
    return this.zulipService.getSubscriptions();
  }

  @Post('streams/subscribe')
  @ApiOperation({ summary: 'Subscribe to streams' })
  @ApiResponse({
    status: 201,
    description: 'Subscription result',
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async subscribe(@Body() dto: SubscribeRequestDto): Promise<{
    subscribed: string[];
    alreadySubscribed: string[];
  }> {
    return this.zulipService.subscribe(dto);
  }

  @Delete('streams/unsubscribe')
  @ApiOperation({ summary: 'Unsubscribe from streams' })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        streamNames: {
          type: 'array',
          items: { type: 'string' },
          example: ['general', 'announcements'],
        },
      },
    },
  })
  @ApiResponse({
    status: 200,
    description: 'Unsubscription result',
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async unsubscribe(
    @Body('streamNames') streamNames: string[],
  ): Promise<{ success: boolean }> {
    return this.zulipService.unsubscribe(streamNames);
  }

  // ===========================================================================
  // Users
  // ===========================================================================

  @Get('users')
  @ApiOperation({ summary: 'Get list of users' })
  @ApiResponse({
    status: 200,
    description: 'List of users',
    type: [UserResponseDto],
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getUsers(@Query() query: GetUsersQueryDto): Promise<UserResponseDto[]> {
    return this.zulipService.getUsers(query);
  }

  @Get('users/me')
  @ApiOperation({ summary: 'Get current authenticated user' })
  @ApiResponse({
    status: 200,
    description: 'Current user profile',
    type: UserResponseDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getCurrentUser(): Promise<UserResponseDto> {
    return this.zulipService.getCurrentUser();
  }
}
