import { Body, Controller, Delete, Get, Param, Patch, Post, Query, Req, UseGuards } from '@nestjs/common';
import { ChatService } from './chat.service';
import { AuthGuard } from 'src/auth/auth.guard';
import { ApiBearerAuth, ApiConsumes, ApiQuery } from '@nestjs/swagger';
import { BlockUserDto, chatHistory, ConnectionDto, CreateConnection, CreateGroupDto, GroupOperationsDto, MuteNotificationType, paginationDto, RequestDto, SendMessageFromPushDto } from './dto/chat.dto';
import { ChatGateway } from './chat.gateway';
import { Public } from 'src/auth/public.decorator';

@Controller()
export class ChatController {
    constructor(
        private readonly chatService: ChatService,
        private readonly chatGateway: ChatGateway,
    ) { }

    //create-connections for one to one chat
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Post("/create-connection")
    async createConnectionFromProfile(@Req() req: RequestDto, @Body() body: CreateConnection) {
        let { _id: user_id } = req["user_data"];
        return await this.chatService.createConnections(
            user_id,
            body
        );
    }

    //Group-connections for group chat
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Post("/create-group")
    async createGroup(@Req() req: RequestDto, @Body() body: CreateGroupDto) {
        return await this.chatService.createGroup(
            req,
            body
        );
    }

    //Group-connections-Details
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Get("/group-details/:_id")
    async groupDetails(@Req() req: RequestDto, @Param('_id') _id: string) {
        return await this.chatService.groupDetails(req, _id);
    }

    //connection-Details
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Get("/connection-details/:_id")
    async connectionDetails(@Req() req: RequestDto, @Param('_id') _id: string) {
        return await this.chatService.connectionDetails(req, _id);
    }

    //list-connections
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Get("/list-connection")
    async chatHis(
        @Req() req: RequestDto,
        @Query() queryData: ConnectionDto
    ) {
        let { _id: user_id } = req["user_data"];
        let { search, pagination, limit, type, conn_type } = queryData;
        return await this.chatService.listChatUsers(
            user_id,
            search ?? "",
            type,
            conn_type,
            pagination ?? 0,
            limit ?? 10,
        );
    }

    //chat or message history
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @ApiQuery({ name: "connection_id", required: false })
    @ApiConsumes("application/x-www-form-urlencoded")
    @Get("history")
    async getHistory(
        @Req() req: RequestDto,
        @Query() req_query: chatHistory
    ) {
        let { _id: user_id } = req["user_data"];
        return await this.chatService.message_history(user_id, req_query);
    }

    //particular message history
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @ApiConsumes("application/x-www-form-urlencoded")
    @Get("message/:_id")
    async messageDetails(req: RequestDto,
        @Param("_id") _id: string
    ) {
        return await this.chatService.messageDetails(_id);
    }

    //mute unmute connctions
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Patch("/mute/unmute/")
    async connectionMuteUnmute(
        @Req() req: RequestDto,
        @Body() dto: MuteNotificationType,
    ) {
        const { _id: user_id } = req["user_data"];
        return await this.chatService.muteOrUnmuteConnection(user_id, dto);
    }

    //list-connections
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Patch("/delivered/:message_id/user_id/:user_id")
    async markDelivered(
        @Req() req: RequestDto,
        @Param("message_id") message_id: string,
        @Param("user_id") user_id: string,
    ) {
        return await this.chatGateway.deliveredMessage(message_id, user_id);
    }

    //list-connections
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Patch("/read/:connection_id/user_id/:user_id")
    async markRead(
        @Req() req: RequestDto,
        @Param("connection_id") connection_id: string,
        @Param("user_id") user_id: string,
    ) {
        return await this.chatGateway.readAllMessages(connection_id, user_id);
    }

    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Patch("/operations")
    async groupOperations(
        @Req() req: RequestDto,
        @Body() body: GroupOperationsDto,
    ) {
        return await this.chatService.
            groupOperations(req, body);
    }

    /**
     * Get all pinned messages for a specific conversation
     * @param req - Request with user data
     * @param connection_id - Connection/Conversation ID
     * @returns List of pinned messages with metadata
     */
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Get("/pinned-messages/:connection_id")
    async getPinnedMessages(
        @Req() req: RequestDto,
        @Param("connection_id") connection_id: string,
    ) {
        const { _id: user_id } = req["user_data"];
        return await this.chatService.getPinnedMessages(user_id, connection_id);
    }

    /**
     * Get all starred messages of a connection for the current user
     * @param req - Request with user data
     * @param connection_id - Connection ID to get starred messages from
     * @returns List of starred messages in the connection
     */
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Get("/starred-messages/:connection_id")
    async getStarredMessages(
        @Req() req: RequestDto,
        @Param("connection_id") connection_id: string,
    ) {
        const { _id: user_id } = req["user_data"];
        return await this.chatService.getStarredMessages(connection_id, user_id);
    }

    /**
     * Get media list by connection ID for the current user
     * @param req - Request with user data
     * @param connection_id - Connection ID to get media from
     * @param media_type - Optional media type filter (IMAGE, VIDEO, AUDIO, DOCUMENT, etc.)
     * @param pagination - Page number for pagination
     * @param limit - Number of items per page
     * @returns List of media in the connection
     */
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @ApiQuery({ name: "media_type", required: false })
    @ApiQuery({ name: "pagination", required: false })
    @ApiQuery({ name: "limit", required: false })
    @Get("/media/:connection_id")
    async getMediaByConnection(
        @Req() req: RequestDto,
        @Param("connection_id") connection_id: string,
        @Query("media_type") media_type?: string,
        @Query("pagination") pagination?: string,
        @Query("limit") limit?: string,
    ) {
        const { _id: user_id } = req["user_data"];
        return await this.chatService.getMediaByConnection(
            connection_id,
            user_id,
            media_type,
            pagination ? parseInt(pagination) : undefined,
            limit ? parseInt(limit) : undefined
        );
    }

    /**
    *
    * @param req
    * @param body
    * @returns send message through push notifications
    */
    @UseGuards(AuthGuard)
    @ApiBearerAuth("access_token")
    @Public()
    @Post("/send-message")
    async sendMessageWithPush(@Req() req: RequestDto, @Body() body: SendMessageFromPushDto) {
        let { _id: user_id } = req["user_data"];
        console.log("_______send message api hit successfully++++++++++++");
        return this.chatService.sendMessageWithPush(
            user_id,
            body,
        );
    }
}
