import {
  CertificateEnvelope,
  CertificateFile,
  CertificateHistoryResponseEntryInterface,
  MaterialMassBalanceCertification,
  EntityDTO,
} from "@minespider/core-sdk";
import { MinespiderModel } from "./Model/MinespiderModel";
import { AllowanceEntry } from "@minespider/core-sdk/dist/types/domain/queries/getMaterialAllowancesQuery";
import { BaseMetadataInterface } from "@minespider/core-sdk/dist/types/service/metadata-service";

export interface Options {
  backendHost?: string;
  blockchainNode?: string;
  coreContractAddress?: string;
  balancesContractAddress?: string;
  certificatesContractAddress?: string;
  privateKey?: string;
}

export class MinespiderFacade {
  constructor(private minespiderModel: MinespiderModel) {}

  public async downloadCertificateEnvelope(
    address: any
  ): Promise<CertificateEnvelope> {
    return this.minespiderModel.downloadCertificateEnvelope(address);
  }

  public async createCertificate(certificate: any): Promise<string> {
    return this.minespiderModel.createCertificate(certificate);
  }

  public async getCertificates(): Promise<any> {
    return this.minespiderModel.getCertificates();
  }

  public async getCertificateById(certificateId: string): Promise<any> {
    return this.minespiderModel.getCertificateById(certificateId);
  }

  public async sellCertificate(
    certificateUuid: string,
    amount: number,
    newOwnerAddress: string,
    publicFilesList: CertificateFile[],
    privateFilesList: CertificateFile[],
    newCertificateType?: number,
    meta?: BaseMetadataInterface
  ): Promise<any> {
    return this.minespiderModel.sellCertificate(
      certificateUuid,
      amount,
      newOwnerAddress,
      publicFilesList,
      privateFilesList,
      newCertificateType,
      meta
    );
  }

  public async readCertificateFileList(
    fileList: FileList
  ): Promise<CertificateFile[]> {
    return this.minespiderModel.readCertificateFileList(fileList);
  }

  public async getCertificatePublicFiles(certificateId: string): Promise<any> {
    return this.minespiderModel.getCertificatePublicFiles(certificateId);
  }

  public async getCertificatePrivateFiles(certificateId: string): Promise<any> {
    return this.minespiderModel.getCertificatePrivateFiles(certificateId);
  }

  async getCertificateHistoryByCertificate(
    certificateUuid: string,
    depth: number = 1
  ): Promise<CertificateHistoryResponseEntryInterface[]> {
    return this.minespiderModel.getCertificateHistoryByCertificate(
      certificateUuid,
      depth
    );
  }

  async getCertificateHistoryByOwner(
    entityId: string
  ): Promise<CertificateHistoryResponseEntryInterface[]> {
    return this.minespiderModel.getCertificateHistoryByOwner(entityId);
  }

  public async getEntities(): Promise<EntityDTO[]> {
    return this.minespiderModel.getEntities();
  }

  public async getEntityById(entityId: string): Promise<any> {
    return this.minespiderModel.getEntityDetails(entityId);
  }
  
  public async getEntitiesByName(entityName: string): Promise<EntityDTO[]> {
    return this.minespiderModel.getEntitiesByName(entityName);
  }

  public async createEntity(
    name: string,
    latitude: string,
    longitude: string,
    location: string,
    meta = {},
    entityType: number,
    materialMassBalanceCertifications?: MaterialMassBalanceCertification[]
  ) {
    return this.minespiderModel.createEntity(
      name,
      latitude,
      longitude,
      location,
      meta,
      entityType,
      materialMassBalanceCertifications
    );
  }

  public async createCertifier(
    name: string,
    latitude: string,
    longitude: string,
    location: string,
    meta = {}
  ) {
    return this.minespiderModel.createCertifier(
      name,
      latitude,
      longitude,
      location,
      meta
    );
  }

  public async createProducer(
    name: string,
    latitude: string,
    longitude: string,
    location: string,
    meta = {}
  ) {
    return this.minespiderModel.createProducer(
      name,
      latitude,
      longitude,
      location,
      meta
    );
  }

  public async setMassBalanceCertification(
    producerId: string,
    materialTaxonomyUuid: string,
    measurementUnitUuid: string,
    amount: number
  ): Promise<any> {
    return this.minespiderModel.modifyMassBalanceCertification(
      producerId,
      materialTaxonomyUuid,
      measurementUnitUuid,
      amount
    );
  }

  public async setMassBalanceCertificationForMultipleMaterials(
    producerId: string,
    materialMassBalanceCertifications: MaterialMassBalanceCertification[]
  ): Promise<any> {
    return this.minespiderModel.modifyMassBalanceCertificationForMultipleMaterials(
      producerId,
      materialMassBalanceCertifications
    );
  }

  public async getMassBalanceCertification(
    producerId: string,
    materialTaxonomyUuid: string,
    measurementUnitUuid: string
  ): Promise<any> {
    return this.minespiderModel.getProducerMBCertification(
      producerId,
      materialTaxonomyUuid,
      measurementUnitUuid
    );
  }

  public async getCurrentAccountAddress() {
    return this.minespiderModel.getCurrentAccountAddress();
  }

  public async downloadCertificatePublicFile(
    certificateId: string,
    fileAddress: string
  ) {
    return this.minespiderModel.downloadCertificatePublicFile(
      certificateId,
      fileAddress
    );
  }

  public async downloadCertificatePrivateFile(
    certificateId: string,
    fileAddress: string
  ) {
    return this.minespiderModel.downloadCertificatePrivateFile(
      certificateId,
      fileAddress
    );
  }

  public async getCertificateManifest(certificateId: string) {
    return this.minespiderModel.getCertificateManifest(certificateId);
  }

  public async getMaterialAllowances(
    balanceHolderUuid: string,
    materialTypeUuid: string,
    measurementUnitUuid: string
  ): Promise<AllowanceEntry[]> {
    return this.minespiderModel.getMaterialAllowances(
      balanceHolderUuid,
      materialTypeUuid,
      measurementUnitUuid
    );
  }

  public async getMaterialTaxonomies() {
    return this.minespiderModel.getMaterialTaxonomies();
  }

  public async getMaterialTypes() {
    return this.minespiderModel.getMaterialTypes();
  }

  public async getMeasurementUnits() {
    return this.minespiderModel.getMeasurementUnits();
  }

  public async getMeasurementUnitTypes() {
    return this.minespiderModel.getMeasurementUnitTypes();
  }

  public getPrivateMetadata(
    certificateUuid: string,
    path?: string
  ): Promise<unknown> {
    return this.minespiderModel.getPrivateMetadata(certificateUuid, path);
  }

  public getPublicMetadata(
    certificateUuid: string,
    path?: string
  ): Promise<unknown> {
    return this.minespiderModel.getPublicMetadata(certificateUuid, path);
  }

  public async getCertificateOwner(certificateId: string): Promise<EntityDTO> {
    return this.minespiderModel.getCertificateOwner(certificateId);
  }

  public async getCertificateParentOwner(
    certificateId: string
  ): Promise<EntityDTO> {
    return this.minespiderModel.getCertificateParentOwner(certificateId);
  }

  public async getBalanceHolderUuid() {
    return this.minespiderModel.getBalanceHolderUuid();
  }

  public async acceptCertificate(certificateUuid: string): Promise<void> {
    return this.minespiderModel.acceptCertificate(certificateUuid);
  }

  public async getCertificatesFromCertificateEnvelopes(): Promise<any> {
    return this.minespiderModel.getCertificatesFromCertificateEnvelopes();
  }
}
