import { Injectable, Inject, Module } from '@nestjs/common'

@Injectable()
class FakeQueue {
  getWaitingCount = () => 0
  getActiveCount = () => 0
  getCompletedCount = () => 0
  getFailedCount = () => Promise.resolve([])
  getDelayedCount = () => 0
  getFailed = () => Promise.resolve([])
  getJob = () => Promise.resolve(null)
  add = () => Promise.resolve({ id: 'fake-job' })
  close = () => Promise.resolve()
}

@Injectable()
class FakeFlowProducer {
  add = () => Promise.resolve({ jobId: 'fake-flow' })
  close = () => Promise.resolve()
}

@Module({})
export class BullModule {
  static forRootAsync(_opts?: any): any {
    return { module: BullModule }
  }

  static registerQueue(...names: { name: string }[]): any {
    const providers = names.map((n) => ({
      provide: `BullQueue_${n.name}`,
      useClass: FakeQueue,
    }))
    return { module: BullModule, providers, exports: providers }
  }

  static registerFlowProducer(opts: { name: string }): any {
    const providers = [
      { provide: `BullFlowProducer_${opts.name}`, useClass: FakeFlowProducer },
    ]
    return { module: BullModule, providers, exports: providers }
  }
}

export const InjectQueue = (name: string): ParameterDecorator =>
  Inject(`BullQueue_${name}`)

export const InjectFlowProducer = (name: string): ParameterDecorator =>
  Inject(`BullFlowProducer_${name}`)

export function Processor(_name: string): ClassDecorator {
  return (target: any) => {
    Injectable()(target)
  }
}

export class WorkerHost {
  worker: any = { on: () => {}, close: () => Promise.resolve() }
}

export const OnWorkerEvent = (_event: string): MethodDecorator => {
  return () => {}
}
