import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Param,
  Body,
  Query,
  Req,
  UseGuards,
  HttpCode,
  HttpStatus,
  ParseUUIDPipe,
} from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { Request } from 'express';
import { randomBytes } from 'crypto';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../../auth/guards/roles.guard';
import { Roles, UserRole } from '../../../common/decorators/roles.decorator';
import { CurrentUser } from '../../../common/decorators/current-user.decorator';
import { PrismaService } from '../../../prisma/prisma.service';
import { WebhookProcessorService } from '../services/webhook-processor.service';
import { FormSubmissionDto } from '../dto/form-submission.dto';
import { CreateWebhookEndpointDto } from '../dto/create-webhook-endpoint.dto';
import { UpdateWebhookEndpointDto } from '../dto/update-webhook-endpoint.dto';

// --- Public endpoints (no JWT) ---

@ApiTags('CRM Webhooks (Public)')
@Controller('crm/deals')
export class WebhooksPublicController {
  constructor(private readonly webhookProcessor: WebhookProcessorService) {}

  @Post('from-form')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Submit form from landing page' })
  @ApiResponse({ status: 200 })
  async submitForm(@Body() dto: FormSubmissionDto, @Req() req: Request) {
    const ip =
      (req.headers['x-forwarded-for'] as string)?.split(',')[0]?.trim() ||
      (req.headers['cf-connecting-ip'] as string) ||
      req.ip;

    return this.webhookProcessor.processFormSubmission(
      dto as any,
      ip,
      req.headers['user-agent'],
      req.headers['referer'],
    );
  }

  @Post('webhook/:token')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Receive webhook from external system' })
  @ApiResponse({ status: 200 })
  async receiveWebhook(
    @Param('token') token: string,
    @Body() body: Record<string, any>,
    @Query() query: Record<string, string>,
    @Req() req: Request,
  ) {
    const ip =
      (req.headers['x-forwarded-for'] as string)?.split(',')[0]?.trim() ||
      (req.headers['cf-connecting-ip'] as string) ||
      req.ip;

    return this.webhookProcessor.processWebhook({
      token,
      body,
      headers: req.headers as Record<string, string>,
      query,
      ip,
    });
  }
}

// --- Protected endpoints (JWT) ---

@ApiTags('CRM Webhook Endpoints')
@ApiBearerAuth()
@Controller('crm/webhooks')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN)
export class WebhooksAdminController {
  constructor(private readonly prisma: PrismaService) {}

  @Get()
  @ApiOperation({ summary: 'List webhook endpoints' })
  @ApiResponse({ status: 200 })
  async findAll(@CurrentUser() user: any) {
    const clubId = user.role === UserRole.SUPER_ADMIN ? null : user.clubId;
    return this.prisma.crmWebhookEndpoint.findMany({
      where: { clubId },
      orderBy: { createdAt: 'desc' },
    });
  }

  @Post()
  @ApiOperation({ summary: 'Create webhook endpoint' })
  @ApiResponse({ status: 201 })
  async create(@CurrentUser() user: any, @Body() dto: CreateWebhookEndpointDto) {
    const clubId = user.role === UserRole.SUPER_ADMIN ? null : user.clubId;
    const token = randomBytes(24).toString('hex');

    return this.prisma.crmWebhookEndpoint.create({
      data: {
        clubId,
        token,
        name: dto.name,
        pipelineId: dto.pipelineId,
        stageId: dto.stageId,
        defaultAssigneeId: dto.defaultAssigneeId,
        fieldMappings: dto.fieldMappings ?? undefined,
        listMappings: dto.listMappings ?? undefined,
        antifraudEnabled: dto.antifraudEnabled ?? true,
      },
    });
  }

  @Patch(':id')
  @ApiOperation({ summary: 'Update webhook endpoint' })
  async update(@Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdateWebhookEndpointDto) {
    return this.prisma.crmWebhookEndpoint.update({
      where: { id },
      data: {
        ...(dto.name !== undefined ? { name: dto.name } : {}),
        ...(dto.pipelineId !== undefined ? { pipelineId: dto.pipelineId } : {}),
        ...(dto.stageId !== undefined ? { stageId: dto.stageId } : {}),
        ...(dto.defaultAssigneeId !== undefined
          ? { defaultAssigneeId: dto.defaultAssigneeId }
          : {}),
        ...(dto.fieldMappings !== undefined ? { fieldMappings: dto.fieldMappings } : {}),
        ...(dto.listMappings !== undefined ? { listMappings: dto.listMappings } : {}),
        ...(dto.antifraudEnabled !== undefined ? { antifraudEnabled: dto.antifraudEnabled } : {}),
        ...(dto.isActive !== undefined ? { isActive: dto.isActive } : {}),
      },
    });
  }

  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete webhook endpoint' })
  async remove(@Param('id', ParseUUIDPipe) id: string) {
    await this.prisma.crmWebhookEndpoint.delete({ where: { id } });
  }
}
