import { ApiValidationError } from "../../Models/Server.Error.model";
import { Body, Controller, Middlewares, Post, Response, Route, SuccessResponse } from "tsoa";
import { authenticateMiddleware } from "../../middleware/authentication";
import { ApiVoidResult } from "../../Models/Api.VoidResult.type";
import {
    DeleteMessageParams,
    ISendMessageResult,
    PaginateMessageParams,
    PaginateMessageResults,
    SendMessageParams,
} from "../../Models/Messages/Messages.Interface";
import { MessagesService } from "./Messages.Service";

import { io } from "../../index";
import {
    FindConversationsResults,
    MarkConversationAsReadParams,
    PaginateFindContactsParams,
    PaginateFindContactsResults,
} from "../../Models/MessageConversations/MessagesConversations.Interface";

@Route("messages/find-conversations")
@Middlewares(authenticateMiddleware)
export class FindConversationsController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async findConversations(
        @Body() requestBody: PaginateFindContactsParams
    ): Promise<FindConversationsResults | ApiValidationError> {
        try {
            const messages = await new MessagesService().paginateFindConversations(requestBody);
            this.setStatus(200);
            return messages;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("messages/find-contacts")
@Middlewares(authenticateMiddleware)
export class FindContactsController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async findContacts(
        @Body() requestBody: PaginateFindContactsParams
    ): Promise<PaginateFindContactsResults | ApiValidationError> {
        try {
            const messages = await new MessagesService().paginateFindContacts(requestBody);
            this.setStatus(200);
            return messages;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("messages/paginate")
@Middlewares(authenticateMiddleware)
export class PaginateMessagesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async paginateMessages(
        @Body() requestBody: PaginateMessageParams
    ): Promise<PaginateMessageResults | ApiValidationError> {
        try {
            const messages = await new MessagesService().paginateMessages(requestBody);
            this.setStatus(200);
            return messages;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("messages/send")
@Middlewares(authenticateMiddleware)
export class SendMessagesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async sendMessage(
        @Body() requestBody: SendMessageParams
    ): Promise<ISendMessageResult | ApiValidationError> {
        try {
            const messageResult = await new MessagesService().sendMessage(requestBody);
            this.setStatus(200);
            const emitTo =
                requestBody.sessionUser == messageResult.conversation.userIdTo
                    ? messageResult.conversation.userIdFrom
                    : messageResult.conversation.userIdTo;

            io.to(`user:${emitTo}`).emit("new_message", messageResult);

            return messageResult;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("messages/delete")
@Middlewares(authenticateMiddleware)
export class DeleteMessagesController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async deleteNotifications(
        @Body() requestBody: DeleteMessageParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new MessagesService().deleteMessage(requestBody);
            this.setStatus(200);
            return {
                success: true,
                message: "Mensaje eliminado correctamente",
            };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("messages/conversation-read")
@Middlewares(authenticateMiddleware)
export class MarkConversationReadController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse(200, "Done")
    @Post()
    public async markConversationAsRead(
        @Body() requestBody: MarkConversationAsReadParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new MessagesService().markConversationAsRead(requestBody);
            this.setStatus(200);
            return {
                success: true,
                message: "Conversación marcada como leida",
            };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}
