import { BaseService, BaseServiceOptions } from '../../api/services/base-service';
import { FilterParams, PagedResponse, UpdateAttachmentResponse, createQueryParams } from '../../common';
import { Event } from '../../core-events';
import { createAndUploadAttachments } from '../asset-attachment.utils';
import { AddReferenceVdtRequest, ShareAssetRequest } from '../asset.service.interfaces';
import {
  ChainAssetEvent,
  ChainAssetEventData,
  CreateAttachmentsPayload,
  CreateChainAssetRequest,
  CreateQrAttachmentRequest,
  CustomerAsset,
  EventGroupItem,
  GenerateQrRequest,
  GetWitnessAssetsRequest,
  IChainService,
  LinkQrRequest,
  QrPackageCodeResponse,
  UpdateAttachmentRequest,
  UpdateChainAssetDetailsRequest,
  UpdateFavoriteRequest,
  UpdateLocationPrivacyRequest,
  UpdateMetadataRequest,
  WitnessAsset,
} from '../interfaces';

export class ChainAssetService extends BaseService implements IChainService {
  chainApiUrl: string;

  constructor(opts: BaseServiceOptions) {
    super(opts);
    this.chainApiUrl = `${this.apiUrl}/${this.coreApiServicePrefix}/v1/chain-assets`;
  }

  create(req: CreateChainAssetRequest) {
    return this.post<ChainAssetEvent, CreateChainAssetRequest>(this.chainApiUrl, req);
  }

  createAttachments(req: CreateAttachmentsPayload) {
    return createAndUploadAttachments({ service: this, chainApiUrl: this.chainApiUrl, req });
  }

  createQrAttachment(eventId: string, req: CreateQrAttachmentRequest) {
    return this.post<void, CreateQrAttachmentRequest>(`${this.chainApiUrl}/${eventId}/qr`, req);
  }

  getEvent(eventId: string) {
    return this.get<ChainAssetEvent>(`${this.chainApiUrl}/${eventId}`);
  }

  getChildEvents(eventId: string) {
    return this.get<EventGroupItem[]>(`${this.chainApiUrl}/${eventId}/child-events`);
  }

  getDetailsByEvent(eventId: string) {
    return this.get<CustomerAsset>(`${this.apiUrl}/assets/v1/asset/${eventId}/event`);
  }

  getDetails(assetId: string) {
    return this.get<CustomerAsset>(`${this.apiUrl}/assets/v1/asset/${assetId}`);
  }

  assetByQr(qrId: string) {
    return this.get<ChainAssetEvent>(`${this.coreApiUrl}/v1/qrcode/${qrId}/asset-info`);
  }

  eventPublicByQr(qrId: string) {
    return this.get<ChainAssetEvent>(`${this.coreApiUrl}/v1/qrcode/${qrId}/asset-info-public`);
  }

  getAttachmentImageUrl(attachmentId: string, thumb?: boolean) {
    const query = createQueryParams({ thumb: thumb ? 'true' : undefined });
    return `${this.chainApiUrl}/attachments/${attachmentId}/view?${query}`;
  }

  getWitnesses(req: GetWitnessAssetsRequest) {
    const query = createQueryParams({ assetId: req.id, assetName: req.name, ...req });
    return this.get<PagedResponse<WitnessAsset>>(`${this.apiUrl}/assets/v1/witness/witnesses-asset?${query}`);
  }

  update(eventId: string, req: UpdateChainAssetDetailsRequest) {
    return this.put<ChainAssetEvent, UpdateChainAssetDetailsRequest>(`${this.chainApiUrl}/${eventId}/details`, req);
  }

  updateMetadata(eventId: string, req: UpdateMetadataRequest) {
    return this.post<ChainAssetEventData, UpdateMetadataRequest>(`${this.chainApiUrl}/${eventId}/metadata`, req);
  }

  updateLocationPrivacy(eventId: string, req: UpdateLocationPrivacyRequest) {
    return this.patch<void, UpdateLocationPrivacyRequest>(`${this.chainApiUrl}/${eventId}/privacy`, req);
  }

  linkQr(qrId: string, req: LinkQrRequest) {
    return this.put<QrPackageCodeResponse, LinkQrRequest>(`${this.coreApiUrl}/v1/qrcode/${qrId}/link`, req);
  }

  generateQr(req: GenerateQrRequest) {
    return this.post<QrPackageCodeResponse, GenerateQrRequest>(`${this.coreApiUrl}/v1/qrcode/system-generated`, req);
  }

  deleteAttachments(attId: string) {
    return this.delete<any>(`${this.chainApiUrl}/${attId}/attachments`);
  }

  addReferenceVdt(req: AddReferenceVdtRequest) {
    return this.post<AddReferenceVdtRequest, AddReferenceVdtRequest>(
      `${this.apiUrl}/assets/v1/asset/reference-vdt`,
      req
    );
  }

  updateAttachments(eventId: string, req: UpdateAttachmentRequest) {
    return this.put<UpdateAttachmentResponse, UpdateAttachmentRequest>(
      `${this.chainApiUrl}/${eventId}/attachments`,
      req
    );
  }
  updateConfirmStatus(eventId: string) {
    return this.patch<void, object>(`${this.apiUrl}/assets/v1/asset/${eventId}/confirm`, {});
  }

  deleteReferenceVdt(id: string, qrCodeRefId: string) {
    return this.delete<void>(`${this.apiUrl}/assets/v1/asset/${id}/reference-vdt/${qrCodeRefId}`);
  }

  eventByQr(qrId: string) {
    return this.get<Event>(`${this.coreApiUrl}/v1/qrcode/${qrId}/event-info`);
  }

  updateFavorite(req: UpdateFavoriteRequest) {
    return this.patch<void, UpdateFavoriteRequest>(`${this.chainApiUrl}/favorite`, req);
  }

  share(eventId: string, data: ShareAssetRequest): Promise<any> {
    return this.post<void, ShareAssetRequest>(`${this.apiUrl}/assets/v1/asset/${eventId}/share`, data);
  }
}
