import { Model, RelationMappings, RelationMappingsThunk, QueryContext } from 'objection';
import { v4 as uuidv4 } from 'uuid';
import { WebhookDeliveryStatus } from '../../common/enums';
import { BaseModel } from './base.model';

export const WebhookLogStatus = WebhookDeliveryStatus;
export type WebhookLogStatus = WebhookDeliveryStatus;

export class WebhookLog extends BaseModel {
  static tableName = 'webhook_logs';

  id!: string;
  webhookId!: string;
  eventType!: string;
  payload!: Record<string, unknown>;
  responseStatus?: number;
  responseBody?: string;
  responseTime?: number;
  retryCount!: number;
  status!: WebhookDeliveryStatus;
  createdAt!: Date;

  // Relations
  webhook?: Model;

  async $beforeInsert(queryContext: QueryContext): Promise<void> {
    await super.$beforeInsert(queryContext);
    if (!this.id) {
      this.id = uuidv4();
    }
    this.createdAt = new Date();
  }

  static get jsonSchema() {
    return {
      type: 'object',
      required: ['webhookId', 'eventType', 'payload'],
      properties: {
        id: { type: 'string', format: 'uuid' },
        webhookId: { type: 'string', format: 'uuid' },
        eventType: { type: 'string', maxLength: 100 },
        payload: { type: 'object' },
        responseStatus: { type: ['integer', 'null'] },
        responseBody: { type: ['string', 'null'] },
        responseTime: { type: ['integer', 'null'] },
        retryCount: { type: 'integer', default: 0 },
        status: { type: 'string', maxLength: 20, default: 'PENDING' },
        createdAt: { type: 'string', format: 'date-time' },
      },
    };
  }

  static get relationMappings(): RelationMappingsThunk {
    return (): RelationMappings => {
      const { Webhook } = require('./webhook.model');
      return {
        webhook: {
          relation: Model.BelongsToOneRelation,
          modelClass: Webhook,
          join: {
            from: 'webhook_logs.webhook_id',
            to: 'webhooks.id',
          },
        },
      };
    };
  }
}
