import { Controller, Patch, Get, Body, Query, Res, UseGuards, Request } from '@nestjs/common';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { CountryRecommendedCategoriesService } from './country-recommended-categories.service';
import { toJsonResponse } from '../../common/response';
import { AdminGuard } from '../auth/guards/admin.guard';
import { CommonGuard } from '../auth/guards/common.guard';
import { ToggleCountryRecommendedDto } from './dtos/toggle-country-recommended.dto';
import { CountryRecommendedListQueryDto } from './dtos/country-recommended-list-query.dto';
import { UpdateCountryRecommendedOrderDto } from './dtos/update-country-recommended-order.dto';
import { UpdateCountryRecommendedMinApplicationDto } from './dtos/update-country-recommended-min-application.dto';
import { CategoryCampaignListQueryDto } from './dtos/category-campaign-list-query.dto';
import { ToggleCategoryCampaignDto } from './dtos/toggle-category-campaign.dto';
import { ToggleCategoryCampaignHideDto } from './dtos/toggle-category-campaign-hide.dto';
import { UpdateCategoryCampaignOrderDto } from './dtos/update-category-campaign-order.dto';

@ApiTags('categories')
@Controller('categories/country-recommended')
export class CountryRecommendedCategoriesController {
  constructor(private readonly countryRecommendedCategoriesService: CountryRecommendedCategoriesService) { }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Toggle campaign in category for a country (add country order if missing, remove if exists)' })
  @ApiBody({ type: ToggleCategoryCampaignDto })
  @UseGuards(AdminGuard)
  @Patch('campaigns/toggle')
  async toggleCampaign(@Body() request: ToggleCategoryCampaignDto, @Request() req, @Res() response: any) {
    try {
      const data = await this.countryRecommendedCategoriesService.toggleCampaign(request);
      response.status(201).json(data);
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Toggle hidden state for a campaign in a category for a country' })
  @ApiBody({ type: ToggleCategoryCampaignHideDto })
  @UseGuards(AdminGuard)
  @Patch('campaigns/hide-toggle')
  async toggleCampaignHide(@Body() request: ToggleCategoryCampaignHideDto, @Request() req, @Res() response: any) {
    try {
      const data = await this.countryRecommendedCategoriesService.toggleCampaignHide(request);
      response.status(201).json(data);
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Move a campaign category to a new position' })
  @ApiBody({ type: UpdateCategoryCampaignOrderDto })
  @UseGuards(AdminGuard)
  @Patch('campaigns/order')
  async updateCampaignOrder(@Body() request: UpdateCategoryCampaignOrderDto, @Request() req, @Res() response: any) {
    try {
      await this.countryRecommendedCategoriesService.updateCampaignOrder(request);
      response.status(201).json();
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Get paginated campaigns by category id' })
  @ApiQuery({ name: 'country_id', required: true, type: 'string' })
  @ApiQuery({ name: 'category_id', required: true, type: 'string' })
  @ApiQuery({ name: 'page', required: true, example: 1 })
  @ApiQuery({ name: 'per_page', required: false, example: 10 })
  @ApiQuery({ name: 'search', required: false, type: 'string' })
  @UseGuards(AdminGuard)
  @Get('campaigns')
  async campaignList(@Query() queryParam: CategoryCampaignListQueryDto, @Request() req, @Res() response: any) {
    try {
      console.log(queryParam);
      const data = await this.countryRecommendedCategoriesService.campaignList(queryParam);
      response.status(200).json(data);
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Get categories by country with recommended filter' })
  @ApiQuery({ name: 'country_id', required: true, type: 'string' })
  @ApiQuery({ name: 'recommended', required: true, enum: ['true', 'false'], description: 'true = country recommended only, false = other categories' })
  @UseGuards(CommonGuard)
  @Get('list')
  async list(@Query() queryParam: CountryRecommendedListQueryDto, @Request() req, @Res() response: any) {
    try {
      const data = await this.countryRecommendedCategoriesService.list(queryParam, req.user);
      response.status(200).json(data);
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Update minimum application limit for a country recommended category' })
  @ApiBody({ type: UpdateCountryRecommendedMinApplicationDto })
  @UseGuards(AdminGuard)
  @Patch('min-application')
  async updateMinApplication(@Body() request: UpdateCountryRecommendedMinApplicationDto, @Request() req, @Res() response: any) {
    try {
      const data = await this.countryRecommendedCategoriesService.updateMinApplication(request);
      response.status(201).json(data);
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Move a country recommended category to a new position' })
  @ApiBody({ type: UpdateCountryRecommendedOrderDto })
  @UseGuards(AdminGuard)
  @Patch('order')
  async updateOrder(@Body() request: UpdateCountryRecommendedOrderDto, @Request() req, @Res() response: any) {
    try {
      await this.countryRecommendedCategoriesService.updateOrder(request);
      response.status(201).json();
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }

  @ApiBearerAuth('access-token')
  @ApiOperation({ summary: 'Toggle category as recommended for a country (add if missing, remove if exists)' })
  @ApiBody({ type: ToggleCountryRecommendedDto })
  @UseGuards(AdminGuard)
  @Patch('toggle')
  async toggle(@Body() request: ToggleCountryRecommendedDto, @Request() req, @Res() response: any) {
    try {
      const data = await this.countryRecommendedCategoriesService.toggle(request);
      response.status(201).json(data);
    } catch (error: any) {
      console.log(error);
      response.status(error.status || 500).json(toJsonResponse(error.status || 500, error.message));
    }
  }
}
