import {
  UiService
} from "./chunk-WUILV27O.js";
import {
  Address,
  ContentBinary,
  ContentService,
  Filesystem,
  Http,
  PromotionType,
  Share
} from "./chunk-JNQRPNRP.js";
import {
  Directory
} from "./chunk-BN54ET2Y.js";
import {
  AuthRefService,
  StorageService
} from "./chunk-M3LFBN7N.js";
import {
  Appointment,
  AppointmentDocument,
  AppointmentEventSubType,
  AppointmentEventType,
  AppointmentFixture,
  AppointmentPrice,
  AppointmentPropertyEntity,
  EntityAttribute,
  Property,
  PropertyEntityType,
  deepClone,
  generateId,
  hashString,
  safePrice
} from "./chunk-N36JE2BE.js";
import {
  environment
} from "./chunk-DNHSR4U6.js";
import {
  HttpClient,
  HttpEventType,
  Injectable,
  Observable,
  Subject,
  filter,
  map,
  setClassMetadata,
  tap,
  ɵɵdefineInjectable,
  ɵɵinject
} from "./chunk-VAMMRICA.js";
import {
  Capacitor
} from "./chunk-IT26RCSL.js";
import {
  __async
} from "./chunk-RVA4KI76.js";

// src/app/shared/appointments/models/events.ts
var AppointmentEvent = class {
  constructor(id, appointmentId, userId, newData, type, subType) {
    this.id = "";
    this.appointmentId = "";
    this.type = AppointmentEventType.Generic;
    this.subType = AppointmentEventSubType.Changed;
    this.id = id;
    this.appointmentId = appointmentId, this.userId = userId;
    this.newData = newData;
    this.type = type;
    this.subType = subType;
    this.timeStamp_Utc = /* @__PURE__ */ new Date();
  }
};

// src/app/shared/appointments/services/appointment-mapping.service.ts
var _AppointmentMappingService = class _AppointmentMappingService {
  constructor() {
  }
  // #region Mapping
  mapAppointment(parsedAppointment) {
    const appointment = Object.assign(new Appointment(), parsedAppointment);
    if (appointment.scheduled_Utc != null) {
      appointment.scheduled_Utc = new Date(appointment.scheduled_Utc);
    }
    if (appointment.property != null) {
      const property = Object.assign(new Property(), appointment.property);
      if (property.photo != null) {
        property.photo = new ContentBinary(property.photo);
      }
      if (property.address != null) {
        const address = Object.assign(new Address(), appointment.property.address);
        property.address = address;
      }
      if (property.entity != null) {
        property.entity = this.mapPropertyEntity(property.entity, appointment);
      }
      appointment.property = property;
      appointment.changed$ = new Subject();
      appointment.priceChanged$ = new Subject();
      appointment.customPriceChanged$ = new Subject();
    }
    if (appointment.job != null) {
      appointment.job = this.mapPropertyEntity(appointment.job, appointment);
    }
    if (appointment.price != null) {
      appointment.price = this.mapAppointmentPrice(appointment.price, appointment);
    }
    if (appointment.customPrice != null) {
      appointment.customPrice = this.mapAppointmentPrice(appointment.customPrice, appointment);
      if (appointment.customPrice.details != null && appointment.price?.details != null) {
        const clonedDetails = deepClone(appointment.price.details);
        if (clonedDetails != null) {
          appointment.customPrice.details = clonedDetails;
        }
      }
    }
    appointment.documents = this.mapAppointmentDocuments(appointment);
    appointment.checkPaymentsValidity();
    appointment.checkDocumentValidity();
    appointment.checkProgression();
    return appointment;
  }
  mapAppointmentDocuments(appointment) {
    const documents = [];
    appointment.documents.forEach((document2) => {
      const existingDoc = documents.find((x) => x.id == document2.id);
      if (existingDoc == null) {
        const mappedDocument = new AppointmentDocument(document2.id, document2.name, document2.customerFacing, document2.shopFacing, document2.standalone, document2.dynamic, document2.alwaysShow, document2.displayInSigning, document2.mapping, document2.displayOrder, document2.content, document2.executed, document2.signers, document2.rules, document2.documents, document2.signatures, document2.userContent, document2.lastUpdated_Utc, document2.created_Utc, document2.generatedContent, document2.originalHash);
        if (mappedDocument.dynamic) {
          mappedDocument.hash = hashString(mappedDocument.content ?? "");
        } else {
          mappedDocument.hash = hashString(JSON.stringify(mappedDocument.mapping));
        }
        if (mappedDocument.name == "Scope of Work Acknowledgments") {
          mappedDocument.hash = hashString(JSON.stringify(mappedDocument.documents));
        }
        documents.push(mappedDocument);
      }
    });
    return documents;
  }
  mapAppointmentPrice(price, appointment) {
    const mappedPrice = new AppointmentPrice(price);
    return mappedPrice;
  }
  mapPropertyEntity(entity, appointment) {
    const mappedEntity = new AppointmentPropertyEntity(entity.id, entity.entityId, entity.type, entity.name, entity.number, entity.attributes, entity.fixtures, entity.renderDimensions, entity.metafields, entity.rules, entity.photos, entity.photos_B64, entity.render, entity.localRender, entity.notes);
    const mappedEntities = [];
    for (var i = 0, len = entity.entities.length; i < len; i++) {
      const childEntity = entity.entities[i];
      const mappedChildEntity = this.mapPropertyEntity(childEntity, appointment);
      mappedEntities.push(mappedChildEntity);
    }
    mappedEntity.entities = mappedEntities;
    const mappedFixtures = this.mapFixtures(entity.fixtures, appointment);
    const mappedAttributes = this.mapAttributes(entity.attributes, appointment);
    mappedEntity.fixtures = mappedFixtures;
    mappedEntity.attributes = mappedAttributes;
    const photos = [];
    mappedEntity.photos.forEach((photo) => {
      photo = new ContentBinary(photo);
      photos.push(photo);
    });
    mappedEntity.photos = photos;
    if (mappedEntity.render != null) {
      mappedEntity.render = new ContentBinary(mappedEntity.render);
    }
    return mappedEntity;
  }
  mapFixture(fixture, appointment) {
    const mappedFixture = new AppointmentFixture(fixture.id, fixture.entityId, fixture.name, fixture.imageSrc_Base64, fixture.number, fixture.attributes, fixture.renderDimensions, fixture.photos, fixture.photos_B64, fixture.notes);
    mappedFixture.attributes = this.mapAttributes(fixture.attributes, appointment);
    const photos = [];
    mappedFixture.photos.forEach((photo) => {
      photo = new ContentBinary(photo);
      photos.push(photo);
    });
    mappedFixture.photos = photos;
    return mappedFixture;
  }
  mapFixtures(fixtures, appointment) {
    const mappedFixtures = [];
    fixtures.forEach((fixture) => {
      const mappedFixture = this.mapFixture(fixture, appointment);
      mappedFixtures.push(mappedFixture);
    });
    return mappedFixtures;
  }
  mapAttributes(attributes, appointment) {
    const mappedAttributes = [];
    if (attributes != null) {
      attributes.forEach((attribute) => {
        const mappedAttribute = new EntityAttribute(attribute.id, attribute.name, attribute.customerFacing, attribute.possibleValues, attribute.type, attribute.displayOrder, attribute.defaultValue, attribute.hidden, attribute.rules, attribute.values, attribute.functionName);
        mappedAttributes.push(mappedAttribute);
      });
    }
    return mappedAttributes;
  }
  // #endregion
  ngOnDestroy() {
  }
};
_AppointmentMappingService.\u0275fac = function AppointmentMappingService_Factory(__ngFactoryType__) {
  return new (__ngFactoryType__ || _AppointmentMappingService)();
};
_AppointmentMappingService.\u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _AppointmentMappingService, factory: _AppointmentMappingService.\u0275fac, providedIn: "root" });
var AppointmentMappingService = _AppointmentMappingService;
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(AppointmentMappingService, [{
    type: Injectable,
    args: [{
      providedIn: "root"
    }]
  }], () => [], null);
})();

// src/app/shared/appointments/services/appointment.service.ts
var _AppointmentService = class _AppointmentService {
  constructor(apptMappingService, http, authRefService, storageService, contentService, uiService) {
    this.apptMappingService = apptMappingService;
    this.http = http;
    this.authRefService = authRefService;
    this.storageService = storageService;
    this.contentService = contentService;
    this.uiService = uiService;
  }
  // #region Floors
  getLevelCount(entities = [], levelCount = 0) {
    entities.forEach((e) => {
      if (e.type == PropertyEntityType.Structure) {
        levelCount = levelCount + e.entities.length;
      } else {
        levelCount = this.getLevelCount(e.entities, levelCount);
      }
    });
    return levelCount;
  }
  // #endregion
  // #region Map
  getCoordinatesForAddress(address) {
    const encodedAddress = btoa(address);
    return new Observable((o) => {
      this.storageService.getAddressCoordinates(encodedAddress).then((coordinates) => {
        if (coordinates != null) {
          o.next(coordinates);
          o.complete();
        } else {
          const url = "https://nominatim.openstreetmap.org/search";
          this.http.get(url, {
            params: {
              q: address,
              format: "json",
              addressdetails: "1",
              limit: "1"
            }
          }).subscribe({
            next: (results) => {
              let coords = results[0];
              if (coords == null) {
                coords = {
                  encodedAddress,
                  lat: 0,
                  lon: 0,
                  place_id: "",
                  licence: "",
                  osm_type: "",
                  osm_id: "",
                  display_name: address,
                  boundingbox: ["", "", "", ""],
                  class: "",
                  type: "",
                  importance: 0
                };
              }
              coords.encodedAddress = encodedAddress;
              this.storageService.storeAddressCoordinates(coords);
              o.next(coords);
              o.complete();
            },
            error: () => {
              o.error();
              o.complete();
            }
          });
        }
      }).catch(() => {
        o.error();
        o.complete();
      });
    });
  }
  // #endregion
  // #region Promotions
  applyPromotion(price, promotion, updatePrice = true) {
    const existingPromotion = price.appliedPromotions.find((x) => x.id == promotion.id);
    if (promotion.discount != null && existingPromotion == null) {
      const appliedDiscount = promotion.appliedDiscount ?? 0;
      promotion.active = true;
      price.appliedPromotions.push(promotion);
      if (updatePrice) {
        price.finalPrice = price.finalPrice - appliedDiscount;
      }
      price.calcTotalDiscount();
    }
  }
  removePromotion(price, promotion) {
    const existingPromotionIndex = price.appliedPromotions.findIndex((x) => x.id == promotion.id);
    if (existingPromotionIndex > -1) {
      const existingPromotion = price.appliedPromotions[existingPromotionIndex];
      if (existingPromotion.appliedDiscount != null) {
        existingPromotion.active = false;
        existingPromotion.locked = false;
        price.appliedPromotions.splice(existingPromotionIndex, 1);
        price.finalPrice = price.finalPrice + existingPromotion.appliedDiscount;
        price.calcTotalDiscount();
      }
    }
  }
  calcPromotionDiscount(promotion, price, invert = false) {
    if (promotion.discount != null) {
      switch (promotion.type) {
        case PromotionType.Percent: {
          let promotionDiscount = promotion.discount / 100;
          if (invert) {
            promotionDiscount = 1 - promotion.discount / 100;
            return safePrice(safePrice(price.finalPrice / promotionDiscount) - price.finalPrice);
          } else {
            return safePrice(price.finalPrice * (promotion.discount / 100));
          }
        }
      }
    }
    return 0;
  }
  resetPromotions(appointment, price, invert = false) {
    price.appliedPromotions = [];
    for (var i = 0, len = appointment.availablePromotions.length; i < len; i++) {
      const promotion = appointment.availablePromotions[i];
      promotion.active = false;
      promotion.locked = false;
      if (promotion.discount != null) {
        const invertCalc = invert && promotion.autoApply;
        switch (promotion.type) {
          case PromotionType.Percent:
            {
              promotion.appliedDiscount = this.calcPromotionDiscount(promotion, price, invertCalc);
            }
            break;
        }
        const appliedDiscount = promotion.appliedDiscount ?? 0;
        promotion.appliedDiscount = appliedDiscount;
      }
      if (promotion.autoApply) {
        this.applyPromotion(price, promotion, false);
      }
    }
  }
  calcSpecialPromotion(price) {
    let delta = price.targetPrice - price.totalDiscount - price.finalPrice;
    delta = safePrice(delta);
    let specialPromotion = price.appliedPromotions.find((x) => x.name == "Special Discount");
    if (delta > 0) {
      if (specialPromotion == null) {
        specialPromotion = {
          id: generateId(),
          name: "Special Discount",
          discount: delta,
          autoApply: true,
          type: PromotionType.Amount,
          manual: false,
          appliedDiscount: delta,
          stackable: true,
          active: true,
          priority: 99,
          locked: true
        };
        price.appliedPromotions.push(specialPromotion);
      } else {
        specialPromotion.discount = delta;
        specialPromotion.appliedDiscount = delta;
      }
    } else if (specialPromotion != null) {
      this.removePromotion(price, specialPromotion);
    }
  }
  // #endregion
  // #region Pricing
  resetCustomPrice(appointment) {
    const customPrice = deepClone(appointment.price);
    if (customPrice != null) {
      const originalFinalPrice = customPrice.finalPrice;
      appointment.customPrice = new AppointmentPrice(customPrice);
      this.resetPromotions(appointment, appointment.customPrice, true);
      appointment.customPrice.targetPrice = originalFinalPrice + appointment.customPrice.totalDiscount;
      this.calcSpecialPromotion(appointment.customPrice);
      appointment.customPriceChanged$.next();
    }
    appointment.changed$.next();
  }
  updateCustomPrice(appointment) {
    if (appointment.customPrice != null) {
      this.calcSpecialPromotion(appointment.customPrice);
      appointment.customPriceChanged$.next();
    }
  }
  // #endregion
  // #region Syncing
  getLastUserAppointmentRetrieval(userId) {
    const lastRetrieval = localStorage.getItem(`u_${userId}_ar`);
    if (lastRetrieval != null) {
      try {
        return parseInt(lastRetrieval);
      } catch {
        return void 0;
      }
    }
    return void 0;
  }
  updateLastUserAppointmentRetrieval(userId) {
    let now = /* @__PURE__ */ new Date();
    now.setDate(now.getDate() - 1);
    localStorage.setItem(`u_${userId}_ar`, `${now.getTime()}`);
  }
  syncAppointmentsForUser(userId, forceAll = false) {
    let url = `{{api}}/appointments/${userId}/latest`;
    if (!forceAll) {
      const lastRetrievalInMs = this.getLastUserAppointmentRetrieval(userId);
      if (lastRetrievalInMs != null) {
        const now = /* @__PURE__ */ new Date();
        const sinceInMs = now.getTime() - lastRetrievalInMs;
        url = url + `/${sinceInMs}`;
      }
    }
    return this.http.get(url).pipe(tap((appointments) => __async(this, null, function* () {
      yield this.storageService.remoteStoreAppointments(appointments);
      this.updateLastUserAppointmentRetrieval(userId);
    })));
  }
  syncTodayAppointmentsForUser(userId) {
    let url = `{{api}}/appointments/${userId}/today`;
    return this.http.get(url).pipe(tap((appointments) => {
      this.storageService.remoteStoreAppointments(appointments);
    }));
  }
  getLastTeamAppointmentsRetrieval(userId) {
    const lastRetrieval = localStorage.getItem(`u_${userId}_tar`);
    if (lastRetrieval != null) {
      try {
        return parseInt(lastRetrieval);
      } catch {
        return void 0;
      }
    }
    return void 0;
  }
  updateLastTeamAppointmentsRetrieval(userId) {
    const now = /* @__PURE__ */ new Date();
    localStorage.setItem(`u_${userId}_tar`, `${now.getTime()}`);
  }
  syncAppointmentsForTeam(userId) {
    let url = `{{api}}/appointments/${userId}/team/latest`;
    const lastRetrievalInMs = this.getLastTeamAppointmentsRetrieval(userId);
    if (lastRetrievalInMs != null) {
      const now = /* @__PURE__ */ new Date();
      const sinceInMs = now.getTime() - lastRetrievalInMs;
      url = url + `/${sinceInMs}`;
    }
    return this.http.get(url).pipe(tap((appointments) => {
      this.storageService.remoteStoreAppointments(appointments);
      this.updateLastTeamAppointmentsRetrieval(userId);
    }));
  }
  // To be used if passing an appointment around and not wanting to touch the original
  cloneAppointment(appointment) {
    const clonedAppointment = deepClone(appointment);
    if (clonedAppointment != null) {
      return this.mapAppointment(clonedAppointment);
    }
    return void 0;
  }
  getAppointment(id) {
    return new Observable((o) => {
      this.storageService.getAppointment(id).then((appointment) => {
        if (appointment != null) {
          const mappedAppointment = this.mapAppointment(appointment);
          o.next(mappedAppointment);
          o.complete();
        } else {
          o.next(null);
          o.complete();
        }
      }).catch(() => {
        o.error();
        o.complete();
      });
    });
  }
  searchAppointments(query, userId, status = void 0) {
    return new Observable((o) => {
      this.storageService.searchAppointments(userId, query, status).then((appointments) => {
        const mappedAppointments = [];
        appointments.forEach((appointment) => {
          const mappedAppointment = this.mapAppointment(appointment);
          mappedAppointments.push(mappedAppointment);
        });
        o.next(mappedAppointments);
        o.complete();
      }).catch(() => {
        o.error();
        o.complete();
      });
    });
  }
  getAppointmentsForDateRange(startDate, endDate, userId = void 0) {
    return new Observable((o) => {
      this.storageService.getAppointmentsForDateRange(startDate, endDate, userId).then((appointments) => {
        const mappedAppointments = [];
        appointments.forEach((appointment) => {
          const mappedAppointment = this.mapAppointment(appointment);
          mappedAppointments.push(mappedAppointment);
        });
        o.next(mappedAppointments);
        o.complete();
      }).catch(() => {
        o.error();
        o.complete();
      });
    });
  }
  getAppointmentsForToday(userId = void 0) {
    return new Observable((o) => {
      const today = /* @__PURE__ */ new Date();
      const year = today.getFullYear();
      const month = today.getMonth() + 1;
      let monthStr = `${month}`;
      if (month < 10) {
        monthStr = `0${month}`;
      }
      const date = today.getDate();
      let dateStr = `${date}`;
      if (date < 10) {
        dateStr = `0${date}`;
      }
      this.storageService.getAppointmentsForDate(`${year}-${monthStr}-${dateStr}`, userId).then((appointments) => {
        const mappedAppointments = [];
        appointments.forEach((appointment) => {
          const mappedAppointment = this.mapAppointment(appointment);
          mappedAppointments.push(mappedAppointment);
        });
        o.next(mappedAppointments);
        o.complete();
      }).catch(() => {
        o.error();
        o.complete();
      });
    });
  }
  getAppointmentsForUser(userId) {
    return new Observable((o) => {
      this.storageService.getAppointmentsForUser(userId).then((appointments) => {
        const mappedAppointments = [];
        appointments.forEach((appointment) => {
          const mappedAppointment = this.mapAppointment(appointment);
          mappedAppointments.push(mappedAppointment);
        });
        o.next(mappedAppointments);
        o.complete();
      }).catch(() => {
        o.error();
        o.complete();
      });
    });
  }
  getAppointmentsByStatus(status, userId) {
    return new Observable((o) => {
      this.storageService.getAppointmentsForStatus(status, userId).then((appointments) => {
        const mappedAppointments = [];
        appointments.forEach((appointment) => {
          const mappedAppointment = this.mapAppointment(appointment);
          mappedAppointments.push(mappedAppointment);
        });
        o.next(mappedAppointments);
        o.complete();
      }).catch(() => {
        o.error();
        o.complete();
      });
    });
  }
  mapAppointment(appointment) {
    return this.apptMappingService.mapAppointment(appointment);
  }
  mapPropertyEntity(entity, appointment) {
    return this.apptMappingService.mapPropertyEntity(entity, appointment);
  }
  mapFixture(fixture, appointment) {
    return this.apptMappingService.mapFixture(fixture, appointment);
  }
  mapFixtures(fixtures, appointment) {
    return this.apptMappingService.mapFixtures(fixtures, appointment);
  }
  mapAttributes(attributes, appointment = void 0) {
    return this.apptMappingService.mapAttributes(attributes, appointment);
  }
  // {{api}}/appointments/store
  storeAppointment(appointment, shouldSync = false, showError = false) {
    window.clearTimeout(this.storeDebounce);
    if (appointment.checkPaymentsValidity == null) {
      appointment = this.apptMappingService.mapAppointment(appointment);
    }
    this.storeDebounce = window.setTimeout(() => {
      appointment.checkPaymentsValidity();
      appointment.checkDocumentValidity();
      appointment.checkProgression();
      appointment.lastUpdated_Utc = /* @__PURE__ */ new Date();
      if (shouldSync) {
        appointment.syncing = true;
        const originalSync = appointment.lastSynced;
        this.syncAppointment(appointment).subscribe({
          next: () => {
            appointment.syncing = false;
            appointment.lastSynced = /* @__PURE__ */ new Date();
            this.storageService.storeAppointment(appointment);
          },
          error: () => {
            appointment.syncing = false;
            appointment.lastSynced = originalSync;
            if (showError) {
              this.uiService.prompt("Failed to Sync Appointment", "There was an issue syncing the appointment. Please try again or contact support.", "Okay").subscribe({
                next: () => {
                }
              });
            }
          }
        });
      } else {
        this.storageService.storeAppointment(appointment);
      }
    }, 500);
  }
  syncAppointment(appointment) {
    const url = `{{api}}/appointments/store`;
    const headers = { "Content-Type": "application/json" };
    const request = {
      data: [appointment]
    };
    return this.http.post(url, JSON.stringify(request), { headers });
  }
  // #endregion
  // #region Acceptance
  acceptAppointment(appointmentId) {
    const url = `{{api}}/appointments/${appointmentId}/accept`;
    return this.http.post(url, null);
  }
  // #endregion
  // #region Events
  storeEvent(appointment, newData, type, subType) {
    const activeUser = this.authRefService.user.getValue();
    const newEvent = new AppointmentEvent(generateId(), appointment.id, activeUser?.id, newData, type, subType);
    return newEvent;
  }
  // #endregion
  // #region Addresses
  getDirections(address) {
    const addressParts = [];
    if (address.streetAddress1)
      addressParts.push(address.streetAddress1);
    if (address.streetAddress2)
      addressParts.push(address.streetAddress2);
    if (address.streetAddress3)
      addressParts.push(address.streetAddress3);
    if (address.city)
      addressParts.push(address.city);
    if (address.regionIso3166)
      addressParts.push(address.regionIso3166);
    if (address.subRegion)
      addressParts.push(address.subRegion);
    if (address.countryIso3166)
      addressParts.push(address.countryIso3166);
    if (address.postalCode)
      addressParts.push(address.postalCode);
    const link = addressParts.join(", ").replace(/ /g, "+");
    return `https://www.google.com/maps/search/?api=1&query=${link}`;
  }
  sendDirections(appointmentId, phoneNumber = void 0, emailAddress = void 0) {
    const url = `{{api}}/appointments/${appointmentId}/directions`;
    const headers = { "Content-Type": "application/json" };
    const request = {
      appointmentId,
      phoneNumber,
      emailAddress
    };
    return this.http.post(url, JSON.stringify(request), { headers });
  }
  // #endregion
  // #region Estimates
  submitEstimate(appointment, documents, metaDocuments, operationsNote, preferredShopId, preferredInstallDate) {
    const price = appointment.customPrice ?? appointment.price;
    let priceToSend = deepClone(price);
    if (priceToSend != null) {
      priceToSend.details.forEach((detail) => {
        detail.lineItems.forEach((lineItem) => {
          lineItem.entity = void 0;
        });
      });
    }
    const submittedDate = (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA");
    if (Capacitor.isNativePlatform()) {
      const url = `${environment.API_URL}/appointments/estimates/submit`;
      return new Observable((o) => {
        const base64 = this.contentService.convertBytesToBase64(documents);
        Filesystem.writeFile({
          path: "Estimate Documents.pdf",
          data: base64,
          directory: Directory.Cache
        }).then((storeResult) => {
          o.next({ progress: 100 });
          return Http.uploadFile({
            url,
            name: "documents",
            filePath: storeResult.uri,
            data: {
              appointmentId: appointment.id,
              operationsNote,
              preferredInstallDate,
              preferredShopId,
              metaDocuments: JSON.stringify(metaDocuments),
              price: JSON.stringify(priceToSend),
              paymentSetting: JSON.stringify(appointment.paymentSetting),
              lenders: JSON.stringify(appointment.lenders ?? []),
              payments: JSON.stringify(appointment.payments),
              submittedDate
            },
            headers: {
              Authorization: `Bearer ${this.authRefService.accessToken ?? ""}`
            }
          }).then((result) => {
            o.next(result.data);
            o.complete();
          }).catch((uploadErr) => {
            o.error(uploadErr);
            o.complete();
          }).finally(() => {
            Filesystem.deleteFile({ path: "Estimate Documents.pdf", directory: Directory.Cache }).then();
          });
        }).catch(() => {
          o.error("Failed to prepare quote for sending.");
          o.complete();
        });
      });
    } else {
      const url = `{{api}}/appointments/estimates/submit`;
      const formData = new FormData();
      formData.append("appointmentId", appointment.id);
      const pdfBlob = this.contentService.convertBytesToBlob(documents, "application/pdf");
      formData.append("documents", pdfBlob);
      if (operationsNote !== void 0) {
        formData.append("operationsNote", operationsNote);
      }
      if (preferredInstallDate !== void 0) {
        formData.append("preferredInstallDate", preferredInstallDate);
      }
      if (preferredShopId !== void 0) {
        formData.append("preferredShopId", preferredShopId);
      }
      formData.append("price", JSON.stringify(priceToSend));
      formData.append("paymentSetting", JSON.stringify(appointment.paymentSetting));
      formData.append("lenders", JSON.stringify(appointment.lenders ?? []));
      formData.append("payments", JSON.stringify(appointment.payments));
      formData.append("metaDocuments", JSON.stringify(metaDocuments));
      formData.append("submittedDate", submittedDate);
      return this.http.post(url, formData, {
        reportProgress: true,
        observe: "events"
      }).pipe(filter((e) => e.type === HttpEventType.UploadProgress || e.type === HttpEventType.Response), map((event) => {
        if (event.type === HttpEventType.UploadProgress) {
          const percent = event.total ? Math.round(100 * event.loaded / event.total) : 0;
          return { progress: percent };
        }
        return event.body;
      }));
    }
  }
  // #endregion
  // #region Documents
  sendDocumentsToCustomer(appointmentId, content, recipientName, email = void 0, phone = void 0) {
    const url = `{{api}}/appointments/${appointmentId}/documents/customer`;
    const headers = { "Content-Type": "application/json" };
    const request = {
      content,
      recipientName,
      emailAddress: email,
      smsNumber: phone
    };
    return this.http.post(url, JSON.stringify(request), { headers });
  }
  sendFinalDocuments(appointmentId, documents, recipientName, recipientEmail) {
    if (Capacitor.isNativePlatform()) {
      const url = `${environment.API_URL}/appointments/${appointmentId}/documents/final/send`;
      return new Observable((o) => {
        const base64 = this.contentService.convertBytesToBase64(documents);
        Filesystem.writeFile({
          path: "Documents.pdf",
          data: base64,
          directory: Directory.Cache
        }).then((storeResult) => {
          o.next({ progress: 100 });
          return Http.uploadFile({
            url,
            name: "documents",
            filePath: storeResult.uri,
            data: {
              recipientName,
              recipientEmail
            },
            headers: {
              Authorization: `Bearer ${this.authRefService.accessToken ?? ""}`
            }
          }).then((result) => {
            o.next(result.data);
            o.complete();
          }).catch((uploadErr) => {
            o.error(uploadErr);
            o.complete();
          }).finally(() => __async(this, null, function* () {
            yield Filesystem.deleteFile({ path: "Documents.pdf", directory: Directory.Cache });
          }));
        }).catch(() => {
          o.error("Failed to prepare documents for sending.");
          o.complete();
        });
      });
    } else {
      const url = `{{api}}/appointments/${appointmentId}/documents/final/send`;
      const pdfBlob = this.contentService.convertBytesToBlob(documents, "application/pdf");
      const formData = new FormData();
      formData.append("documents", pdfBlob);
      formData.append("recipientName", recipientName);
      formData.append("recipientEmail", recipientEmail);
      return this.http.post(url, formData, {
        reportProgress: true,
        observe: "events"
      }).pipe(filter((e) => e.type === HttpEventType.UploadProgress || e.type === HttpEventType.Response), map((event) => {
        if (event.type === HttpEventType.UploadProgress) {
          const percent = event.total ? Math.round(100 * event.loaded / event.total) : 0;
          return { progress: percent };
        }
        return event.body;
      }));
    }
  }
  sendQuote(appointmentId, quote, recipientName, recipientEmail) {
    if (Capacitor.isNativePlatform()) {
      const url = `${environment.API_URL}/appointments/${appointmentId}/documents/quote/send`;
      return new Observable((o) => {
        const base64 = this.contentService.convertBytesToBase64(quote);
        Filesystem.writeFile({
          path: "Quote.pdf",
          data: base64,
          directory: Directory.Cache
        }).then((storeResult) => __async(this, null, function* () {
          o.next({ progress: 100 });
          return Http.uploadFile({
            url,
            name: "quote",
            filePath: storeResult.uri,
            data: {
              recipientName,
              recipientEmail
            },
            headers: {
              Authorization: `Bearer ${this.authRefService.accessToken ?? ""}`
            }
          }).then((result) => {
            o.next(result.data);
            o.complete();
          }).catch((uploadErr) => {
            o.error(uploadErr);
            o.complete();
          }).finally(() => __async(this, null, function* () {
            yield Filesystem.deleteFile({ path: "Quote.pdf", directory: Directory.Cache });
          }));
        })).catch(() => {
          o.error("Failed to prepare quote for sending.");
          o.complete();
        });
      });
    } else {
      const url = `{{api}}/appointments/${appointmentId}/documents/quote/send`;
      const pdfBlob = this.contentService.convertBytesToBlob(quote, "application/pdf");
      const formData = new FormData();
      formData.append("quote", pdfBlob);
      formData.append("recipientName", recipientName);
      formData.append("recipientEmail", recipientEmail);
      return this.http.post(url, formData, {
        reportProgress: true,
        observe: "events"
      }).pipe(filter((e) => e.type === HttpEventType.UploadProgress || e.type === HttpEventType.Response), map((event) => {
        if (event.type === HttpEventType.UploadProgress) {
          const percent = event.total ? Math.round(100 * event.loaded / event.total) : 0;
          return { progress: percent };
        }
        return event.body;
      }));
    }
  }
  // #endregion
  // #region Data Export
  remoteExportAppointment(jobId, compressedAppointment) {
    const fileName = `${jobId}-${(/* @__PURE__ */ new Date()).toISOString()}`;
    if (Capacitor.isNativePlatform()) {
      const url = `${environment.API_URL}/appointments/export`;
      return new Observable((o) => {
        const base64 = this.contentService.convertBytesToBase64(compressedAppointment);
        const filePath = `${fileName}.zip`;
        Filesystem.writeFile({
          path: filePath,
          data: base64,
          directory: Directory.Cache
        }).then((storeResult) => __async(this, null, function* () {
          o.next({ progress: 100 });
          return Http.uploadFile({
            url,
            name: "appointment",
            filePath: storeResult.uri,
            data: {
              fileName: filePath
            },
            headers: {
              Authorization: `Bearer ${this.authRefService.accessToken ?? ""}`
            }
          }).then((result) => {
            o.next(result.data);
            o.complete();
          }).catch((uploadErr) => {
            o.error(uploadErr);
            o.complete();
          }).finally(() => __async(this, null, function* () {
            yield Filesystem.deleteFile({ path: filePath, directory: Directory.Cache });
          }));
        })).catch(() => {
          o.error("Failed to remote export appointment.");
          o.complete();
        });
      });
    } else {
      const url = `{{api}}/appointments/export`;
      const appointmentBlob = new Blob([compressedAppointment], { type: "application/zip" });
      const formData = new FormData();
      formData.append("appointment", appointmentBlob);
      formData.append("fileName", `${fileName}.zip`);
      return this.http.post(url, formData, {
        reportProgress: true,
        observe: "events"
      }).pipe(filter((e) => e.type === HttpEventType.UploadProgress || e.type === HttpEventType.Response), map((event) => {
        if (event.type === HttpEventType.UploadProgress) {
          const percent = event.total ? Math.round(100 * event.loaded / event.total) : 0;
          return { progress: percent };
        }
        return event.body;
      }));
    }
  }
  exportAppointment(appointment) {
    return new Promise((res, rej) => __async(this, null, function* () {
      const fileName = `${appointment.jobId}-${(/* @__PURE__ */ new Date()).toISOString()}`;
      const compressedAppointment = yield this.contentService.compressData(appointment, `${fileName}.json`);
      if (Capacitor.isNativePlatform()) {
        const base64 = this.contentService.convertBytesToBase64(compressedAppointment);
        const filePath = `${fileName}.zip`;
        yield Filesystem.writeFile({
          path: filePath,
          data: base64,
          directory: Directory.Cache
        }).then((writeResult) => __async(this, null, function* () {
          yield Share.share({
            title: "Export Appointment to Device",
            url: writeResult.uri,
            dialogTitle: "Save Appointment to Files"
          });
          res();
        })).catch(() => {
          rej();
        }).finally(() => __async(this, null, function* () {
          yield Filesystem.deleteFile({ path: filePath, directory: Directory.Cache });
        }));
      } else {
        try {
          const appointmentBlob = new Blob([compressedAppointment], { type: "application/zip" });
          const url = URL.createObjectURL(appointmentBlob);
          const link = document.createElement("a");
          link.href = url;
          link.download = `${fileName}.zip`;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          URL.revokeObjectURL(url);
          res();
        } catch {
          rej();
        }
      }
    }));
  }
  // #endregion
  ngOnDestroy() {
  }
};
_AppointmentService.\u0275fac = function AppointmentService_Factory(__ngFactoryType__) {
  return new (__ngFactoryType__ || _AppointmentService)(\u0275\u0275inject(AppointmentMappingService), \u0275\u0275inject(HttpClient), \u0275\u0275inject(AuthRefService), \u0275\u0275inject(StorageService), \u0275\u0275inject(ContentService), \u0275\u0275inject(UiService));
};
_AppointmentService.\u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _AppointmentService, factory: _AppointmentService.\u0275fac, providedIn: "root" });
var AppointmentService = _AppointmentService;
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(AppointmentService, [{
    type: Injectable,
    args: [{
      providedIn: "root"
    }]
  }], () => [{ type: AppointmentMappingService }, { type: HttpClient }, { type: AuthRefService }, { type: StorageService }, { type: ContentService }, { type: UiService }], null);
})();

export {
  AppointmentService
};
//# sourceMappingURL=chunk-WJXFQPCB.js.map
