import { Controller, Post, Body, HttpStatus, HttpException, UseGuards, Res, Logger, Get, Query, Param, Delete, ParseBoolPipe } from '@nestjs/common';
import { NewsletterService } from './news-letter.service';
import { SubscribeDto, SendNewsletterDto, UnsubscribeDto } from './dto/subscribe.dto';
import { ApiTags, ApiOperation, ApiResponse, ApiBody, ApiQuery, ApiParam } from '@nestjs/swagger';
import { JwtAuthGuard } from 'common/guards/jwt-auth.guard';
import { Roles } from 'common/decorators/role.decorator';
import { UserRole } from 'common/enum/UserRole.enum';
import { RolesGuard } from 'common/guards/roles.guard';
import { HostType, SendTo } from 'common/enum/HostType.enum';

@ApiTags('Newsletter')
@Controller({ path: 'newsletter', version: '1' })
export class NewsletterController {
  private readonly logger = new Logger(NewsletterController.name);
  constructor(private readonly newsletterService: NewsletterService) {}

  @Post('subscribe')
  @ApiOperation({ summary: 'Subscribe to newsletter' })
  @ApiBody({ type: SubscribeDto })
  @ApiResponse({ status: HttpStatus.CREATED, description: 'Successfully subscribed' })
  @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Invalid email or host type' })
  async subscribe(@Body() subscribeDto: SubscribeDto) {
    try {
      return { message: await this.newsletterService.subscribe(subscribeDto.email, subscribeDto.host) };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
    }
  }

  @Post('unsubscribe')
  @ApiOperation({ summary: 'Unsubscribe from newsletter' })
  @ApiBody({ type: UnsubscribeDto })
  @ApiResponse({ status: HttpStatus.OK, description: 'Successfully unsubscribed' })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Email not found' })
  async unsubscribe(@Body() unsubscribeDto: UnsubscribeDto) {
    try {
      return { message: await this.newsletterService.unsubscribe(unsubscribeDto.email, unsubscribeDto.host) };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.NOT_FOUND);
    }
  }

  @Post('send')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Send newsletter' })
  @ApiBody({ type: SendNewsletterDto })
  @ApiResponse({ status: HttpStatus.CREATED, description: 'Newsletter sent successfully' })
  @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Invalid request parameters' })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'No recipients found' })
  async sendNewsletter(@Body() sendNewsletterDto: SendNewsletterDto, @Res() res: any) {
    this.logger.debug('Sending newsletter:', sendNewsletterDto);
    try {
      return res.json({ message: await this.newsletterService.sendNewsletter(sendNewsletterDto) });
    } catch (error) {
      this.logger.error('Error sending newsletter:', error);
      return res.redirect('/admin/newsletters?error=Sending failed');
    }
  }

  @Get('subscribers/count')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get count of active subscribers' })
  @ApiQuery({ name: 'host', enum: HostType, required: true })
  @ApiResponse({ status: HttpStatus.OK, description: 'Subscriber count retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getSubscriberCount(@Query('host') host: HostType) {
    try {
      const count = await this.newsletterService.countActiveSubscribers(host);
      return { count, host };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
    }
  }

  @Get('sent/count')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get count of newsletters sent' })
  @ApiQuery({ name: 'host', enum: SendTo, required: true })
  @ApiResponse({ status: HttpStatus.OK, description: 'Newsletter count retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getNewslettersSentCount(@Query('host') host: SendTo) {
    try {
      const count = await this.newsletterService.countNewslettersSent(host);
      return { count, host };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
    }
  }

  @Get('subscribers')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get all subscribers' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Subscribers retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getAllSubscribers() {
    try {
      const subscribers = await this.newsletterService.getAllSubscribers();
      return { subscribers };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('subscribers/host/:host')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get subscribers by host' })
  @ApiParam({ name: 'host', enum: HostType, description: 'Host type' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Subscribers retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getSubscribersByHost(@Param('host') host: HostType) {
    try {
      const subscribers = await this.newsletterService.getSubscribersByHost(host);
      return { subscribers, host };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('subscribers/email/:email')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get subscribers by email' })
  @ApiParam({ name: 'email', type: 'string', description: 'Subscriber email' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Subscribers retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getSubscribersByEmail(@Param('email') email: string) {
    try {
      const subscribers = await this.newsletterService.getSubscribersByEmail(email);
      return { subscribers, email };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('subscribers/status/:isActive')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get subscribers by active status' })
  @ApiParam({ name: 'isActive', type: 'boolean', description: 'Active status (true/false)' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Subscribers retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getSubscribersByStatus(@Param('isActive', ParseBoolPipe) isActive: boolean) {
    try {
      const subscribers = await this.newsletterService.getSubscribersByStatus(isActive);
      return { subscribers, isActive };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('subscribers/filter')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get subscribers by host and active status' })
  @ApiQuery({ name: 'host', enum: HostType, required: true, description: 'Host type' })
  @ApiQuery({ name: 'isActive', required: true, type: Boolean, description: 'Active status (true/false)' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Subscribers retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getSubscribersByHostAndStatus(@Query('host') host: HostType, @Query('isActive', ParseBoolPipe) isActive: boolean) {
    try {
      const subscribers = await this.newsletterService.getSubscribersByHostAndStatus(host, isActive);
      return { subscribers, host, isActive };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('logs')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get all newsletter logs' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Newsletter logs retrieved successfully' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getAllNewsletterLogs() {
    try {
      const logs = await this.newsletterService.findAllNewsletterLogs();
      return { logs };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('logs/:id')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get newsletter log by ID' })
  @ApiParam({ name: 'id', type: 'number', description: 'Newsletter log ID' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Newsletter log retrieved successfully' })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Newsletter log not found' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async getNewsletterLogById(@Param('id') id: number) {
    try {
      const log = await this.newsletterService.findNewsletterLogById(id);
      if (!log) {
        throw new HttpException('Newsletter log not found', HttpStatus.NOT_FOUND);
      }
      return { log };
    } catch (error) {
      if (error instanceof HttpException) {
        throw error;
      }
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Delete('logs/:id')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Delete newsletter log by ID' })
  @ApiParam({ name: 'id', type: 'number', description: 'Newsletter log ID' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Newsletter log deleted successfully' })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Newsletter log not found' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
  async deleteNewsletterLog(@Param('id') id: number) {
    try {
      const message = await this.newsletterService.deleteNewsletterLog(id);
      return { message };
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
