import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Param,
  Body,
  Query,
  Headers,
  UnauthorizedException,
  NotFoundException,
  ParseIntPipe,
  DefaultValuePipe,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { NotificationRepository, CreateNotificationDto } from '../../../infrastructure/repositories/notification.repository';
import * as jwt from 'jsonwebtoken';

/**
 * Platform-admin endpoints for managing notifications.
 * Requires JWT with platform_admin or platform_super_admin role.
 */
@Controller('api/v1/notifications/admin')
export class NotificationAdminController {
  constructor(private readonly repo: NotificationRepository) {}

  /** POST /api/v1/notifications/admin — create notification */
  @Post()
  async create(
    @Headers('authorization') auth: string,
    @Body() body: any,
  ) {
    const admin = this.requireAdmin(auth);
    return this.repo.create({
      title: body.title,
      content: body.content,
      type: body.type ?? 'ANNOUNCEMENT',
      priority: body.priority ?? 'NORMAL',
      targetType: body.targetType ?? 'ALL',
      tenantIds: body.tenantIds,
      userIds: body.userIds,
      targetTagIds: body.targetTagIds,
      targetTagLogic: body.targetTagLogic ?? 'ANY',
      targetPlans: body.targetPlans,
      targetStatuses: body.targetStatuses,
      targetSegment: body.targetSegment ?? null,
      channelKey: body.channelKey ?? null,
      imageUrl: body.imageUrl ?? null,
      linkUrl: body.linkUrl ?? null,
      requiresForceRead: body.requiresForceRead ?? false,
      isEnabled: body.isEnabled ?? true,
      publishedAt: body.publishedAt ? new Date(body.publishedAt) : null,
      expiresAt: body.expiresAt ? new Date(body.expiresAt) : null,
      createdBy: admin.userId,
    } as CreateNotificationDto);
  }

  /** GET /api/v1/notifications/admin — list all notifications */
  @Get()
  async list(
    @Headers('authorization') auth: string,
    @Query('type') type: string | undefined,
    @Query('targetType') targetType: string | undefined,
    @Query('limit', new DefaultValuePipe(50), ParseIntPipe) limit: number,
    @Query('offset', new DefaultValuePipe(0), ParseIntPipe) offset: number,
  ) {
    this.requireAdmin(auth);
    return this.repo.findAllAdmin({ type, targetType, limit: Math.min(limit, 200), offset });
  }

  /** GET /api/v1/notifications/admin/:id — get detail */
  @Get(':id')
  async getOne(
    @Headers('authorization') auth: string,
    @Param('id') id: string,
  ) {
    this.requireAdmin(auth);
    const item = await this.repo.findById(id);
    if (!item) throw new NotFoundException('Notification not found');
    return item;
  }

  /** PUT /api/v1/notifications/admin/:id — update */
  @Put(':id')
  async update(
    @Headers('authorization') auth: string,
    @Param('id') id: string,
    @Body() body: any,
  ) {
    this.requireAdmin(auth);
    const dto: Partial<CreateNotificationDto> = {};
    if (body.title !== undefined) dto.title = body.title;
    if (body.content !== undefined) dto.content = body.content;
    if (body.type !== undefined) dto.type = body.type;
    if (body.priority !== undefined) dto.priority = body.priority;
    if (body.targetType !== undefined) dto.targetType = body.targetType;
    if (body.tenantIds !== undefined) dto.tenantIds = body.tenantIds;
    if (body.userIds !== undefined) dto.userIds = body.userIds;
    if (body.targetTagIds !== undefined) dto.targetTagIds = body.targetTagIds;
    if (body.targetTagLogic !== undefined) dto.targetTagLogic = body.targetTagLogic;
    if (body.targetPlans !== undefined) dto.targetPlans = body.targetPlans;
    if (body.targetStatuses !== undefined) dto.targetStatuses = body.targetStatuses;
    if (body.targetSegment !== undefined) dto.targetSegment = body.targetSegment;
    if (body.channelKey !== undefined) dto.channelKey = body.channelKey;
    if (body.imageUrl !== undefined) dto.imageUrl = body.imageUrl;
    if (body.linkUrl !== undefined) dto.linkUrl = body.linkUrl;
    if (body.requiresForceRead !== undefined) dto.requiresForceRead = body.requiresForceRead;
    if (body.isEnabled !== undefined) dto.isEnabled = body.isEnabled;
    if (body.publishedAt !== undefined) dto.publishedAt = body.publishedAt ? new Date(body.publishedAt) : null;
    if (body.expiresAt !== undefined) dto.expiresAt = body.expiresAt ? new Date(body.expiresAt) : null;

    const updated = await this.repo.update(id, dto);
    if (!updated) throw new NotFoundException('Notification not found');
    return updated;
  }

  /** DELETE /api/v1/notifications/admin/:id */
  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  async remove(
    @Headers('authorization') auth: string,
    @Param('id') id: string,
  ) {
    this.requireAdmin(auth);
    const item = await this.repo.findById(id);
    if (!item) throw new NotFoundException('Notification not found');
    await this.repo.delete(id);
  }

  private requireAdmin(auth: string): { userId: string } {
    if (!auth?.startsWith('Bearer ')) {
      throw new UnauthorizedException('Missing authorization header');
    }
    const token = auth.slice(7);
    const secret = process.env.JWT_SECRET || 'dev-secret';
    try {
      const payload = jwt.verify(token, secret) as any;
      const roles: string[] = Array.isArray(payload.roles) ? payload.roles : [];
      if (!roles.includes('platform_admin') && !roles.includes('platform_super_admin')) {
        throw new UnauthorizedException('Admin role required');
      }
      return { userId: payload.sub };
    } catch (err) {
      if (err instanceof UnauthorizedException) throw err;
      throw new UnauthorizedException('Invalid JWT');
    }
  }
}
