import { Controller, Request, Post, Body, Get, Res, UseGuards, UseInterceptors, UploadedFile, Patch, Query, Put, Delete, Param } from "@nestjs/common"
import { ApiParam, ApiQuery, ApiTags, ApiBody, ApiConsumes, ApiBearerAuth } from "@nestjs/swagger"
import { InfluencerRegisterService } from "./influencer-register.services"
import { toJsonResponse } from "../../common/response"
import { AdminInfluencerGuard } from "../auth/guards/admin-influencer.guard"

// DTO Files
import { SocialMediasDto } from "./dtos/social-media.dto"
import { SecondStepDto } from "./dtos/second-step.dto"
import { ThirdStepDto } from "./dtos/third-step.dto"
import { InfluencerGuard } from "../auth/guards/influencer.guard"
import { UnlinkAccountQueryDto } from "./dtos/unlink-account-query.dto"
import { UnlinkAccountBodyDto } from "./dtos/unlink-account-body.dto"
import { InfluencerSlugParamDto } from "./dtos/influencer-slug-param.dto"
import { InfluencerUpdateDto } from "./dtos/influencer-update.dto"
import { InfluencerKeywords } from "./dtos/influencer-keywords.dto"
import { SocialMediasEditDto } from "./dtos/social-media-edit.dto"
import { SocialMediasParamDto } from "./dtos/social-media-param.dto"
import { SocialMediasLivePostDto } from "./dtos/social-media-live-posts.dto"
import { BankAccountDto } from "./dtos/bank-account.dto"
import { BankIdDto } from "./dtos/bank-id-param.dto"
import { CommonGuard } from "../auth/guards/common.guard"

@ApiTags("influencer-register")
@Controller("influencer-register")
export class InfluencerRegisterController {
    constructor(private influencerRegisterService: InfluencerRegisterService) { }

    @ApiBearerAuth("access-token")
    @ApiBody({ type: SocialMediasDto })
    @UseGuards(InfluencerGuard)
    @Post("social-media")
    /**
     * This API is used to link social media accounts to user.
     * @summary Link social media accounts to user
     */
    async socialMedia(@Body() request: SocialMediasDto, @Request() req, @Res() response: any) {
        const data = await this.influencerRegisterService.socialMedia(request, req.user)
        response.status(200).json(data)
    }

    @ApiBearerAuth("access-token")
    @UseGuards(InfluencerGuard)
    @Get("social-media/live-post/:social_id")
    /**
     * This API is used to link social media accounts to user.
     * @summary Link social media accounts to user
     */
    async socialMediaLivePost(@Query() query: any, @Param() params: SocialMediasLivePostDto, @Request() req, @Res() response: any) {
        const data = await this.influencerRegisterService.socialMediaLivePost(params, query)
        response.status(200).json(data)
    }

    @ApiBearerAuth("access-token")
    @UseGuards(InfluencerGuard)
    @Get("social-media/link")
    /**
     * This API is used to link social media accounts to user.
     * @summary Link social media accounts to user
     */
    async socialMediaLink(@Query() query: any, @Request() req, @Res() response: any) {
        const data = await this.influencerRegisterService.socialMediaLink(query, req.user)
        response.status(200).json(data)
    }


    @ApiBearerAuth("access-token")
    @ApiBody({ type: SocialMediasEditDto })
    @UseGuards(AdminInfluencerGuard)
    @Put("social-media/:id")
    /**
     * This API is used to link social media accounts to user.
     * @summary Link social media accounts to user
     */
    async socialMediaEdit(@Param() param: SocialMediasParamDto, @Body() request: SocialMediasEditDto, @Request() req, @Res() response: any) {

        const data = await this.influencerRegisterService.socialMediaEdit(param, request, req.user)
        response.status(201).json(data)

    }

    @ApiBearerAuth("access-token")
    @UseGuards(CommonGuard)
    @Put("first-step")
    /**
     * This API is used to complete the first step of the influencer registration process.
     * @summary Complete the first step of the influencer registration process
     */
    async firstStep(@Body() body: any, @Request() req, @Res() response: any) {

        const data = await this.influencerRegisterService.firstStep(body, req.user)
        response.status(201).json(data)

    }

    @ApiBearerAuth("access-token")
    @ApiBody({ type: SecondStepDto })
    @UseGuards(InfluencerGuard)
    @Put("second-step")
    /**
     * This API is used to complete the second step of the influencer registration process.
     * @summary Complete the second step of the influencer registration process
     */
    async secondStep(@Body() request: SecondStepDto, @Request() req, @Res() response: any) {

        const data = await this.influencerRegisterService.secondStep(request, req.user)
        response.status(201).json(data)

    }

    @ApiBearerAuth("access-token")
    @ApiBody({ type: ThirdStepDto })
    @UseGuards(InfluencerGuard)
    @Put("third-step")
    /**
     * This API is used to complete the third and final step of the influencer registration process.
     * @summary Complete the third and final step of the influencer registration process
     */
    async thirdStep(@Body() request: ThirdStepDto, @Request() req, @Res() response: any) {

        const data = await this.influencerRegisterService.thirdStep(request, req.user)
        response.status(201).json(data)

    }

    @ApiBearerAuth("access-token")
    @UseGuards(InfluencerGuard)
    @Patch("back-step")
    async backStep(@Request() req, @Res() response: any) {

        const data = await this.influencerRegisterService.backStep(req.user)
        response.status(201).json(data)

    }

    @ApiBearerAuth("access-token")
    @UseGuards(AdminInfluencerGuard)
    @Delete("social-media/:id")
    /**
     * This API is used to unlink a social media account from the user's profile.
     * @summary Unlink a social media account from the user's profile
     */
    async unlinkAccount(@Param() query: UnlinkAccountQueryDto, @Body() request: UnlinkAccountBodyDto, @Request() req, @Res() response: any) {

        await this.influencerRegisterService.unlinkAccount(query, request, req.user)
        response.status(200).json()

    }

    @ApiBearerAuth("access-token")
    @ApiParam({ name: "influencer_slug", required: true })
    @ApiBody({ type: InfluencerUpdateDto })
    @UseGuards(AdminInfluencerGuard)
    @Put("edit/:influencer_slug")
    /**
     * Updates the influencer data based on the provided request data.
     *
     * @param params - An instance of InfluencerSlugParamDto containing the brand id to be updated.
     * @param request - An instance of InfluencerUpdateDto containing the brand information to be updated.
     * @param response - The response object for sending the HTTP response.
     * @param req - The request object, containing the authenticated user information.
     * Responds with a 201 status if the update is successful.
     * In case of an error, logs the error and responds with the respective error status and message.
     */
    async influencerUpdate(@Param() params: InfluencerSlugParamDto, @Body() request: InfluencerUpdateDto, @Request() req, @Res() response: any) {
        const data = await this.influencerRegisterService.influencerUpdate(params, request, req.user)
        response.status(200).json(data)
    }

    @ApiBearerAuth("access-token")
    @ApiParam({ name: "influencer_slug", required: true })
    @ApiBody({ type: InfluencerKeywords })
    @UseGuards(AdminInfluencerGuard)
    @Put("keyword/:influencer_slug")

    /**
     * Updates the influencer's keywords based on the provided request data.
     */
    async influencerKeyword(@Param() params: InfluencerSlugParamDto, @Body() request: InfluencerKeywords, @Request() req, @Res() response: any) {
        await this.influencerRegisterService.influencerKeywords(params, request, req.user)
        response.status(201).json()
    }

    @ApiBearerAuth("access-token")
    @ApiBody({ type: BankAccountDto })
    @UseGuards(InfluencerGuard)
    @Post("bank-account")
    /**
     * This API is used to link social media accounts to user.
     * @summary Link social media accounts to user
     */
    async saveBank(@Body() request: BankAccountDto, @Request() req, @Res() response: any) {

        const data = await this.influencerRegisterService.saveBank(request, req.user)
        response.status(201).json(data)

    }


    @ApiBearerAuth("access-token")
    @ApiBody({ type: BankAccountDto })
    @UseGuards(InfluencerGuard)
    @Put("bank-account/:id")
    /**
     * This API is used to link social media accounts to user.
     * @summary Link social media accounts to user
     */
    async updateBank(@Param() param: BankIdDto, @Body() request: BankAccountDto, @Request() req, @Res() response: any) {

        const data = await this.influencerRegisterService.updateBank(param, request, req.user)
        response.status(201).json(data)

    }
}
