import { Schedule, ScheduleStatus } from '@agiliza/api/domain/schedule'
import {
  AgendamentoVisitaClienteApiModel,
  AgendamentoVisitaClienteCompletoApiModel,
  AgendamentoVisitaSituacaoApiModel,
  AgendamentoVisitaSituacaoCompletoApiModel
} from '@microcredito/client'

import { DomainAdapter } from '../domain'
import { ProjectDocumentMapper } from './project/projects'

export class ScheduleMapper implements DomainAdapter<AgendamentoVisitaClienteApiModel, Schedule> {
  private statusAdapter: ScheduleStatusMapper
  private documentAdapter: ProjectDocumentMapper
  constructor() {
    this.statusAdapter = new ScheduleStatusMapper()
    this.documentAdapter = new ProjectDocumentMapper()
  }

  private mapSolicitacaoReagendamentoToDomain = (
    sR: AgendamentoVisitaClienteCompletoApiModel['solicitacaoReagendamento']
  ): Schedule['requestReschedule'] => ({
    date: sR?.dataReagendamento || null,
    idReason: sR?.codigoMotivo || '',
    justification: sR?.justificativa || '',
  })

  private mapSolicitacaoCancelamentoToDomain = (
    sC: AgendamentoVisitaClienteCompletoApiModel['solicitacaoCancelamento']
  ): Schedule['requestCancel'] => ({ idReason: sC?.codigoMotivo || '', justification: sC?.justificativa || '' })

  public mapApiModelToDomain = (apimodel: AgendamentoVisitaClienteCompletoApiModel) => {
    const result: Schedule = {
      date: new Date(apimodel.data),
      events: apimodel.eventos ?? [],
      id: apimodel.id,
      number: apimodel.numero,
      status: this.statusAdapter.mapApiModelToDomain(apimodel.situacao),
      documents: apimodel.documentos?.map(this.documentAdapter.mapApiModelToDomain),
      requestReschedule: apimodel.solicitacaoReagendamento && this.mapSolicitacaoReagendamentoToDomain(apimodel.solicitacaoReagendamento),
      requestCancel: apimodel.solicitacaoCancelamento && this.mapSolicitacaoCancelamentoToDomain(apimodel.solicitacaoCancelamento),
    }
    return result
  }
}

export class ScheduleStatusMapper implements DomainAdapter<AgendamentoVisitaSituacaoApiModel, ScheduleStatus> {
  public mapOperacaoToDomain = (operacao: AgendamentoVisitaSituacaoCompletoApiModel['operacoes'][0]): Schedule['status']['operations'][0] => ({
    id: operacao.codigo,
    description: operacao.descricao,
    descriptionTransition: operacao.descricaoTransicao,
    permission: operacao.permissao === 'cliente' ? 'customer' : 'broker',
  })
  public mapSituacaoToDomain = (situacao: AgendamentoVisitaSituacaoCompletoApiModel): Schedule['status'] => ({
    id: situacao.codigo,
    description: situacao.descricao,
    operations: situacao.operacoes.map(this.mapOperacaoToDomain),
  })
  public mapApiModelToDomain = (apimodel: AgendamentoVisitaSituacaoCompletoApiModel) => {
    const result: ScheduleStatus = {
      id: apimodel.codigo,
      description: apimodel.descricao,
      operations: apimodel.operacoes.filter((op) => op.permissao === 'cliente').map(this.mapOperacaoToDomain),
    }
    return result
  }
}
