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

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

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

  create(req: CreateChainServiceRequest) {
    return this.post<ChainServiceEvent, CreateChainServiceRequest>(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<ChainServiceEvent>(`${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/service/${eventId}/event`);
  }

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

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

  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({ serviceId: req.id, serviceName: req.name, ...req });
    return this.get<PagedResponse<WitnessAsset>>(`${this.apiUrl}/assets/v1/witness/witnesses-service?${query}`);
  }

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

  updateMetadata(eventId: string, req: UpdateMetadataRequest) {
    return this.post<ChainServiceEventData, 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(attachmentId: string) {
    return this.delete(`${this.chainApiUrl}/${attachmentId}/attachments`);
  }

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

  updateAttachments(eventId: string, req: UpdateAttachmentRequest) {
    return this.put<UpdateAttachmentResponse, UpdateAttachmentRequest>(
      `${this.chainApiUrl}/${eventId}/attachments`,
      req
    );
  }

  updateConfirmStatus(eventId: string) {
    return this.post<void, object>(`${this.apiUrl}/assets/v1/service/${eventId}/confirm`, {});
  }

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

  getS2CEventByQrId(qrId: string, vdtType: ChainTypeEnum, orgId?: string) {
    const query = createQueryParams({ vdtType, orgId });
    return this.get<S2CCustomerAsset[]>(`${this.apiUrl}/assets/v1/service/s2c/qr/${qrId}?${query}`);
  }

  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/service/${eventId}/share`, data);
  }
}
