import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  HttpCode,
  HttpStatus,
  Inject,
  NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { v4 as uuidv4 } from 'uuid';
import {
  SYSTEM_MAINTENANCE_REPOSITORY,
  ISystemMaintenanceRepository,
} from '../../domain/repositories/system-maintenance.repository';
import { SystemMaintenanceEntity } from '../../domain/entities/system-maintenance.entity';
import {
  CreateMaintenanceDto,
  UpdateMaintenanceDto,
  ToggleMaintenanceDto,
} from '../dto/request/system-maintenance.dto';
import {
  MaintenanceResponseDto,
  MaintenanceListResponseDto,
  MaintenanceStatusResponseDto,
} from '../dto/response/system-maintenance.dto';

/**
 * 管理端系统维护控制器
 */
@ApiTags('系统维护管理')
@Controller('admin/maintenance')
export class AdminMaintenanceController {
  constructor(
    @Inject(SYSTEM_MAINTENANCE_REPOSITORY)
    private readonly maintenanceRepo: ISystemMaintenanceRepository,
  ) {}

  /**
   * 创建维护公告
   */
  @Post()
  @ApiOperation({ summary: '创建维护公告' })
  @ApiResponse({ status: 201, type: MaintenanceResponseDto })
  async create(@Body() dto: CreateMaintenanceDto): Promise<MaintenanceResponseDto> {
    const entity = SystemMaintenanceEntity.create({
      id: uuidv4(),
      title: dto.title,
      message: dto.message,
      startTime: new Date(dto.startTime),
      endTime: new Date(dto.endTime),
      createdBy: 'admin', // TODO: 从认证信息获取
    });

    const saved = await this.maintenanceRepo.create(entity);
    return MaintenanceResponseDto.fromEntity(saved);
  }

  /**
   * 获取维护公告列表
   */
  @Get()
  @ApiOperation({ summary: '获取维护公告列表' })
  @ApiResponse({ status: 200, type: MaintenanceListResponseDto })
  async list(
    @Query('limit') limit = 20,
    @Query('offset') offset = 0,
  ): Promise<MaintenanceListResponseDto> {
    const result = await this.maintenanceRepo.findAll({
      limit: Number(limit),
      offset: Number(offset),
    });

    return {
      items: result.items.map((item) => MaintenanceResponseDto.fromEntity(item)),
      total: result.total,
    };
  }

  /**
   * 获取维护公告详情
   */
  @Get(':id')
  @ApiOperation({ summary: '获取维护公告详情' })
  @ApiResponse({ status: 200, type: MaintenanceResponseDto })
  async findById(@Param('id') id: string): Promise<MaintenanceResponseDto> {
    const entity = await this.maintenanceRepo.findById(id);
    if (!entity) {
      throw new NotFoundException('维护公告不存在');
    }
    return MaintenanceResponseDto.fromEntity(entity);
  }

  /**
   * 更新维护公告
   */
  @Put(':id')
  @ApiOperation({ summary: '更新维护公告' })
  @ApiResponse({ status: 200, type: MaintenanceResponseDto })
  async update(
    @Param('id') id: string,
    @Body() dto: UpdateMaintenanceDto,
  ): Promise<MaintenanceResponseDto> {
    const entity = await this.maintenanceRepo.findById(id);
    if (!entity) {
      throw new NotFoundException('维护公告不存在');
    }

    const updated = entity.update({
      title: dto.title,
      message: dto.message,
      startTime: dto.startTime ? new Date(dto.startTime) : undefined,
      endTime: dto.endTime ? new Date(dto.endTime) : undefined,
      updatedBy: 'admin', // TODO: 从认证信息获取
    });

    const saved = await this.maintenanceRepo.update(updated);
    return MaintenanceResponseDto.fromEntity(saved);
  }

  /**
   * 激活/停用维护公告
   */
  @Put(':id/toggle')
  @ApiOperation({ summary: '激活/停用维护公告' })
  @ApiResponse({ status: 200, type: MaintenanceResponseDto })
  async toggle(
    @Param('id') id: string,
    @Body() dto: ToggleMaintenanceDto,
  ): Promise<MaintenanceResponseDto> {
    const entity = await this.maintenanceRepo.findById(id);
    if (!entity) {
      throw new NotFoundException('维护公告不存在');
    }

    // 如果是激活操作，先停用其他所有激活的公告
    if (dto.isActive) {
      await this.maintenanceRepo.deactivateAll(id);
    }

    const updated = dto.isActive
      ? entity.activate('admin') // TODO: 从认证信息获取
      : entity.deactivate('admin');

    const saved = await this.maintenanceRepo.update(updated);
    return MaintenanceResponseDto.fromEntity(saved);
  }

  /**
   * 删除维护公告
   */
  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: '删除维护公告' })
  @ApiResponse({ status: 204 })
  async delete(@Param('id') id: string): Promise<void> {
    const entity = await this.maintenanceRepo.findById(id);
    if (!entity) {
      throw new NotFoundException('维护公告不存在');
    }
    await this.maintenanceRepo.delete(id);
  }

  /**
   * 获取当前维护状态（供内部使用）
   */
  @Get('status/current')
  @ApiOperation({ summary: '获取当前维护状态' })
  @ApiResponse({ status: 200, type: MaintenanceStatusResponseDto })
  async getCurrentStatus(): Promise<MaintenanceStatusResponseDto> {
    const active = await this.maintenanceRepo.findActiveMaintenance();

    if (!active) {
      return { isUnderMaintenance: false, maintenance: null };
    }

    // 计算剩余分钟数
    const now = new Date();
    const endTime = new Date(active.endTime);
    const remainingMs = endTime.getTime() - now.getTime();
    const remainingMinutes = Math.max(0, Math.ceil(remainingMs / 60000));

    return {
      isUnderMaintenance: true,
      maintenance: {
        title: active.title,
        message: active.message,
        startTime: active.startTime,
        endTime: active.endTime,
        remainingMinutes,
      },
    };
  }
}

/**
 * 移动端系统维护控制器（无需认证）
 */
@ApiTags('移动端-系统维护')
@Controller('mobile/system')
export class MobileMaintenanceController {
  constructor(
    @Inject(SYSTEM_MAINTENANCE_REPOSITORY)
    private readonly maintenanceRepo: ISystemMaintenanceRepository,
  ) {}

  /**
   * 检查系统维护状态
   * 注意：此接口无需认证，任何客户端都可以调用
   */
  @Get('maintenance-status')
  @ApiOperation({ summary: '检查系统维护状态' })
  @ApiResponse({ status: 200, type: MaintenanceStatusResponseDto })
  async checkMaintenanceStatus(): Promise<MaintenanceStatusResponseDto> {
    const active = await this.maintenanceRepo.findActiveMaintenance();

    if (!active) {
      return { isUnderMaintenance: false, maintenance: null };
    }

    // 计算剩余分钟数
    const now = new Date();
    const endTime = new Date(active.endTime);
    const remainingMs = endTime.getTime() - now.getTime();
    const remainingMinutes = Math.max(0, Math.ceil(remainingMs / 60000));

    return {
      isUnderMaintenance: true,
      maintenance: {
        title: active.title,
        message: active.message,
        startTime: active.startTime,
        endTime: active.endTime,
        remainingMinutes,
      },
    };
  }
}
