import { FetchContext } from '@agiliza/api/domain'
import { Configuration, DominioApi } from '@microcredito/client'

import { ErrorMappers, ProposalDataMappers } from '../../mappers'
import { DadosPropostaContexto } from '../../mappers/domain/proposalData/context'
import { API_URL, mapUserAgentToString, SESSION_KEY, UserAgent } from '../shared'

export interface ProposalDataContextRepository {
  fetchContext(): Promise<FetchContext['Output']>
}

export class ProposalDataContextRepositoryImpl implements ProposalDataContextRepository {
  private api: DominioApi
  private errorAdapter: ErrorMappers.ResponseErrorAdapter
  private contextMapper: ProposalDataMappers.ContextMapper

  constructor(userAgent: string, accessToken: string) {
    this.errorAdapter = new ErrorMappers.ResponseErrorAdapter()
    this.contextMapper = new ProposalDataMappers.ContextMapper()

    this.api = new DominioApi(
      new Configuration({
        basePath: API_URL,
        accessToken,
        headers: {
          'User-Agent': userAgent,
        },
      })
    )
  }

  public fetchContext = async (): Promise<FetchContext['Output']> => {
    try {
      const contexto: DadosPropostaContexto = {
        enquadramentos: await this.api.obterEnquadramentos(),
        generos: await this.api.obterGeneros(),
        escolaridades: await this.api.obterEscolaridades(),
        estadosCivis: await this.api.obterEstadosCivis(),
        tiposReferencia: await this.api.obterTiposReferencia(),
        tiposMoradia: await this.api.obterTiposMoradia(),
        registrosEscritura: await this.api.obterRegistrosEscritura(),
        setoresAtividade: await this.api.obterSetoresAtividade(),
        opsLiquidadas: await this.api.obterOpsLiquidadas(),
        locais: await this.api.obterLocais(),
        tiposDocumento: await this.api.obterTiposDocumento(),
        classificacoesMes: await this.api.obterClassificacoesMes(),
      }
      return this.contextMapper.mapApiModelToDomain(contexto)
    } catch (e) {
      const result = await this.errorAdapter.mapApiModelToDomain(e)
      throw result
    }
  }
}

export class ProposalDataContextRepositoryImplFactory {
  static create(userAgent: UserAgent) {
    const accessToken = localStorage.getItem(SESSION_KEY) || ''
    const repository = new ProposalDataContextRepositoryImpl(mapUserAgentToString(userAgent), accessToken)
    return repository
  }
}
