import { applyDecorators, Type } from '@nestjs/common';
import {
  ApiCreatedResponse,
  ApiExtraModels,
  ApiOkResponse,
  getSchemaPath,
} from '@nestjs/swagger';

function successEnvelopeSchema(dataSchema: Record<string, unknown>) {
  return {
    type: 'object',
    properties: {
      success: { type: 'boolean', example: true },
      path: { type: 'string', example: '/api/example' },
      timestamp: { type: 'string', format: 'date-time' },
      data: dataSchema,
    },
  };
}

export function ApiEnvelopeOkResponse(model: Type<unknown>, description?: string) {
  return applyDecorators(
    ApiExtraModels(model),
    ApiOkResponse({
      description,
      schema: successEnvelopeSchema({ $ref: getSchemaPath(model) }),
    }),
  );
}

export function ApiEnvelopeCreatedResponse(model: Type<unknown>, description?: string) {
  return applyDecorators(
    ApiExtraModels(model),
    ApiCreatedResponse({
      description,
      schema: successEnvelopeSchema({ $ref: getSchemaPath(model) }),
    }),
  );
}

export function ApiArrayEnvelopeOkResponse(model: Type<unknown>, description?: string) {
  return applyDecorators(
    ApiExtraModels(model),
    ApiOkResponse({
      description,
      schema: successEnvelopeSchema({
        type: 'array',
        items: { $ref: getSchemaPath(model) },
      }),
    }),
  );
}

export function ApiPaginatedEnvelopeOkResponse(model: Type<unknown>, description?: string) {
  return applyDecorators(
    ApiExtraModels(model),
    ApiOkResponse({
      description,
      schema: successEnvelopeSchema({
        type: 'object',
        properties: {
          items: {
            type: 'array',
            items: { $ref: getSchemaPath(model) },
          },
          total: { type: 'number', example: 25 },
          page: { type: 'number', example: 1 },
          limit: { type: 'number', example: 10 },
        },
      }),
    }),
  );
}
