import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  HttpCode,
  HttpStatus,
  NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiQuery } from '@nestjs/swagger';
import { NotificationService } from '../../application/services/notification.service';
import type { CreateNotificationDto, UpdateNotificationDto } from '../../application/services/notification.service';
import { Public } from '../../shared/guards/admin-auth.guard';

/**
 * 管理端通知控制器
 */
@ApiTags('Notifications')
@Controller('notifications')
export class AdminNotificationController {
  constructor(private readonly notificationService: NotificationService) {}

  @Post()
  @ApiOperation({ summary: '创建通知' })
  async create(@Body() dto: CreateNotificationDto) {
    return this.notificationService.create(dto);
  }

  @Get()
  @ApiOperation({ summary: '获取通知列表' })
  @ApiQuery({ name: 'type', required: false })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'offset', required: false, type: Number })
  async findAll(
    @Query('type') type?: string,
    @Query('limit') limit?: number,
    @Query('offset') offset?: number,
  ) {
    return this.notificationService.findAll({
      type: type as any,
      limit: limit ? Number(limit) : undefined,
      offset: offset ? Number(offset) : undefined,
    });
  }

  @Get(':id')
  @ApiOperation({ summary: '获取通知详情' })
  async findOne(@Param('id') id: string) {
    const notification = await this.notificationService.findById(id);
    if (!notification) {
      throw new NotFoundException('通知不存在');
    }
    return notification;
  }

  @Put(':id')
  @ApiOperation({ summary: '更新通知' })
  async update(@Param('id') id: string, @Body() dto: UpdateNotificationDto) {
    const existing = await this.notificationService.findById(id);
    if (!existing) {
      throw new NotFoundException('通知不存在');
    }
    return this.notificationService.update(id, dto);
  }

  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: '删除通知' })
  async delete(@Param('id') id: string) {
    await this.notificationService.delete(id);
  }
}

/**
 * 移动端通知控制器
 */
@ApiTags('Mobile Notifications')
@Controller('mobile/notifications')
export class MobileNotificationController {
  constructor(private readonly notificationService: NotificationService) {}

  @Get()
  @Public()
  @ApiOperation({ summary: '获取用户通知列表' })
  @ApiQuery({ name: 'userSerialNum', required: true })
  @ApiQuery({ name: 'type', required: false })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'offset', required: false, type: Number })
  async getNotifications(
    @Query('userSerialNum') userSerialNum: string,
    @Query('type') type?: string,
    @Query('limit') limit?: number,
    @Query('offset') offset?: number,
  ) {
    const notifications = await this.notificationService.findNotificationsForUser({
      userSerialNum,
      type: type as any,
      limit: limit ? Number(limit) : undefined,
      offset: offset ? Number(offset) : undefined,
    });

    const unreadCount = await this.notificationService.countUnreadForUser(userSerialNum);

    return {
      notifications,
      total: notifications.length,
      unreadCount,
    };
  }

  @Get('unread-count')
  @Public()
  @ApiOperation({ summary: '获取未读通知数量' })
  @ApiQuery({ name: 'userSerialNum', required: true })
  async getUnreadCount(@Query('userSerialNum') userSerialNum: string) {
    const unreadCount = await this.notificationService.countUnreadForUser(userSerialNum);
    return { unreadCount };
  }

  @Post('mark-read')
  @Public()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '标记通知为已读' })
  async markRead(@Body() dto: { userSerialNum: string; notificationId?: string }) {
    if (dto.notificationId) {
      await this.notificationService.markAsRead(dto.notificationId, dto.userSerialNum);
    } else {
      await this.notificationService.markAllAsRead(dto.userSerialNum);
    }
    return { success: true };
  }
}
