import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Logger } from 'nestjs-pino';

export type TeamsWebhookPayload = {
  service?: string;
  risk?: string;
  message?: string;
  host?: string;
  src_ip?: string;
  event_time?: string;
  received?: string;
  text?: string;
};

@Injectable()
export class WebhooksService {
  constructor(private readonly logger: Logger) {}

  async handleTeamsWebhook(
    body: TeamsWebhookPayload | TeamsWebhookPayload[],
    token?: string
  ): Promise<{ ok: true }> {
    const expectedToken = process.env.WEBHOOK_TOKEN;
    if (!expectedToken) {
      throw new HttpException('WEBHOOK_TOKEN not configured', HttpStatus.SERVICE_UNAVAILABLE);
    }
    if (token !== expectedToken) {
      throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);
    }

    const webhookUrl = process.env.TEAMS_WEBHOOK_URL;
    if (!webhookUrl) {
      throw new HttpException('TEAMS_WEBHOOK_URL not configured', HttpStatus.SERVICE_UNAVAILABLE);
    }

    const payloads = Array.isArray(body) ? body : [body];
    this.logger.log({ count: payloads.length, body }, 'Teams webhook payload received');

    for (const payload of payloads) {
      const cardPayload = this.buildAdaptiveCard(payload);

      const response = await fetch(webhookUrl, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(cardPayload),
      });

      if (!response.ok) {
        const respText = await response.text();
        this.logger.error(
          {
            status: response.status,
            statusText: response.statusText,
            body: respText.slice(0, 500),
          },
          'Failed to send Teams webhook'
        );
        throw new HttpException('Failed to send Teams webhook', HttpStatus.BAD_GATEWAY);
      }
    }

    return { ok: true };
  }

  private buildAdaptiveCard(body: TeamsWebhookPayload): Record<string, unknown> {
    const service = body.service ?? 'unknown';
    const risk = body.risk ?? 'unknown';
    const title = `[${risk}] ${service} risk event`;

    const facts: Array<{ title: string; value: string }> = [];
    if (body.message) facts.push({ title: 'message', value: body.message });
    if (body.host) facts.push({ title: 'host', value: body.host });
    if (body.src_ip) facts.push({ title: 'src_ip', value: body.src_ip });
    if (body.event_time) facts.push({ title: 'event_time', value: body.event_time });
    if (body.received) facts.push({ title: 'received', value: body.received });

    const bodyBlocks: Array<Record<string, unknown>> = [
      {
        type: 'TextBlock',
        text: title,
        size: 'Large',
        weight: 'Bolder',
        wrap: true,
      },
    ];

    if (body.text && facts.length === 0) {
      bodyBlocks.push({
        type: 'TextBlock',
        text: body.text,
        wrap: true,
      });
    }

    if (facts.length > 0) {
      bodyBlocks.push({
        type: 'FactSet',
        facts,
      });
    }

    return {
      type: 'message',
      attachments: [
        {
          contentType: 'application/vnd.microsoft.card.adaptive',
          contentUrl: null,
          content: {
            $schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
            type: 'AdaptiveCard',
            version: '1.2',
            body: bodyBlocks,
          },
        },
      ],
    };
  }
}
