import { WinstonLoggerOptions } from '@jig-software/logger-winston';
import {
  Config,
  Inject,
  KoaAppOptions,
  MongoDIOptions,
} from '@jig-software/sdk';
import { z } from 'zod';
import { AppSettingsInit } from './shared';

// Note: AppConfig is for Static props.

const LogLevel = z.enum([
  'error',
  'warn',
  'info',
  'http',
  'verbose',
  'debug',
  'silly',
]);

const _AppConfig = z.object({
  port: z.number().optional(),
  apiPrefix: z.string().optional(),
  databaseURL: z.string(),
  databaseName: z.string(),
  logDirectory: z.string().optional(),
  printLogLevel: LogLevel.optional(),
  persistLogLevel: LogLevel.optional(),
  defaultSettings: AppSettingsInit,
});

export const AppConfig = Config.extend('AppConfig', _AppConfig);
export type AppConfig = Config.infer<typeof AppConfig>;

export class KoaAppOptionsFactory {
  @Inject()
  private appConfig!: AppConfig;
  create(): KoaAppOptions {
    return {
      port: this.appConfig.port ?? 3000,
      prefix: this.appConfig.apiPrefix,
    };
  }
}

export class MongoDIOptionsFactory {
  @Inject()
  private appConfig!: AppConfig;

  create(): MongoDIOptions {
    return {
      uri: this.appConfig.databaseURL,
      database: this.appConfig.databaseName,
      clientOptions: { ignoreUndefined: true },
    };
  }
}

export class WinstonLoggerParamsFactory {
  @Inject()
  private appConfig!: AppConfig;

  create(): [WinstonLoggerOptions] {
    return [
      {
        logDirname: this.appConfig.logDirectory,
        printLogLevel: this.appConfig.printLogLevel,
        persistLogLevel: this.appConfig.persistLogLevel,
      },
    ];
  }
}
