import { Controller, Request, Post, Body, Get, Res, UseGuards, Param, Put, Query, Delete, Patch, Req } from '@nestjs/common';
import { ApiParam, ApiQuery, ApiTags, ApiBody, ApiConsumes } from '@nestjs/swagger';

import { CommonGuard } from 'src/modules/auth/guards/common.guard';
import { BrandGuard } from 'src/modules/auth/guards/brand.guard';
import { toJsonResponse } from 'src/common/response';
import { CampaignListQueryDto } from 'src/modules/campaign/dtos/campaign-list-query.dto';
import { CampaignServiceForAdmin } from './campaign.services';
import { AdminGuard } from 'src/modules/auth/guards/admin.guard';
import { CampaignSlugParamDto } from 'src/modules/campaign/dtos/campaign-slug-param.dto';
import { CampaignIdParamDto } from 'src/modules/campaign/dtos/campaign-id-param.dto';
import { PaymentBodyDto } from './dto/payment.dto';
import { PaymentIdParamDto } from './dto/payment-id-param.dto';
import { PaymentExportDto } from './dto/export-payment.dto';
import { QueryCommonGuard } from 'src/modules/auth/guards/common-query.guard';

// DTO Files

@ApiTags('admin/campaign')
@Controller('admin/campaign')
export class CampaignControllerForAdmin {
    constructor(private campaignService: CampaignServiceForAdmin) { }

    @ApiQuery({ name: 'page', required: false, example: 1 })
    @ApiQuery({ name: 'sort_by', required: false, type: 'string' })
    @ApiQuery({ name: 'sort', required: false, type: 'string' })
    @ApiQuery({ name: 'search', required: false, type: 'string' })
    @UseGuards(AdminGuard)
    @Get('list')
    async list(@Query() queryParam: any, @Request() req, @Res() response: any) {
        try {
            const data = await this.campaignService.list(queryParam);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @ApiQuery({ name: 'page', required: false, example: 1 })
    @ApiQuery({ name: 'sort_by', required: false, type: 'string' })
    @ApiQuery({ name: 'sort', required: false, type: 'string' })
    @ApiQuery({ name: 'search', required: false, type: 'string' })
    @UseGuards(AdminGuard)
    @Get('recommended')
    async recommended(@Query() queryParam: any, @Request() req, @Res() response: any) {
        try {
            const data = await this.campaignService.recommended(queryParam);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @UseGuards(AdminGuard)
    @Post('recommended')
    async addRecommended(@Body() body: any, @Request() req, @Res() response: any) {
        try {
            const data = await this.campaignService.addRecommended(body, req.user);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @ApiQuery({ name: 'page', required: false, example: 1 })
    @ApiQuery({ name: 'sort_by', required: false, type: 'string' })
    @ApiQuery({ name: 'sort', required: false, type: 'string' })
    @ApiQuery({ name: 'search', required: false, type: 'string' })
    @UseGuards(AdminGuard)
    @Get('payment-list')
    async paymentList(@Query() queryParam: any, @Request() req, @Res() response: any) {
        try {
            const data = await this.campaignService.paymentList(queryParam);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @UseGuards(AdminGuard)
    @Patch('payment/change-status/:payment_id')
    async changePaymentStatus(@Param() params: PaymentIdParamDto, @Body() body: any, @Request() req, @Res() response: any) {
        try {
            await this.campaignService.changePaymentStatus(params, body, req.user);
            response.status(201).json();
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @ApiQuery({ name: 'page', required: false, example: 1 })
    @ApiQuery({ name: 'sort_by', required: false, type: 'string' })
    @ApiQuery({ name: 'sort', required: false, type: 'string' })
    @ApiQuery({ name: 'search', required: false, type: 'string' })
    @UseGuards(AdminGuard)
    @Get('payment-history')
    async paymentHistory(@Query() queryParam: any, @Request() req, @Res() response: any) {
        try {
            const data = await this.campaignService.paymentHistory(queryParam);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @ApiParam({ name: 'payment_id', required: true })
    @UseGuards(AdminGuard)
    @Patch('paid/:payment_id')
    async paid(@Param() params: PaymentIdParamDto, @Body() body: PaymentBodyDto, @Request() req, @Res() response: any) {
        try {
            await this.campaignService.paidToInfluencer(params, body, req.user);
            response.status(200).json();
        } catch (error) {
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @UseGuards(QueryCommonGuard)
    @Get('export')
    async export(@Query() param: PaymentExportDto, @Res() response: any) {
        try {
            const data = await this.campaignService.export(param, response);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @UseGuards(QueryCommonGuard)
    @Get('export/analysis')
    async postsExport(@Query() param: PaymentExportDto, @Res() response: any) {
        try {
            const data = await this.campaignService.postsExport(param, response);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }

    @ApiParam({ name: 'slug', required: true })
    @UseGuards(AdminGuard)
    @Get(':slug')
    async campaignDetail(@Param() param: CampaignSlugParamDto, @Res() response: any) {
        try {
            const data = await this.campaignService.campaignDetail(param);
            response.status(200).json(data);
        } catch (error) {
            console.log(error);
            response.status(error.status).json(toJsonResponse(error.status, error.message));
        }
    }
}
