import GrainDescriber from "grain/GrainDescriber";
import { cloneDeep } from "lodash";
import { pond } from "protobuf-ts/pond";
import { or } from "utils/types";

export class GrainBag {
  public settings: pond.GrainBagSettings = pond.GrainBagSettings.create();
  public title: string = "Bag";
  private objKey: string = "";

  public static create(pb?: pond.GrainBag): GrainBag {
    let my = new GrainBag();
    if (pb) {
      my.settings = pond.GrainBagSettings.fromObject(cloneDeep(or(pb.settings, {})));
      my.title = pb.name;
      my.objKey = pb.key;
    }
    return my;
  }

  public static clone(other?: GrainBag): GrainBag {
    if (other) {
      return GrainBag.create(
        pond.GrainBag.fromObject({
          title: other.title,
          key: other.objKey,
          settings: cloneDeep(other.settings)
        })
      );
    }
    return GrainBag.create();
  }

  public static any(data: any): GrainBag {
    return GrainBag.create(pond.GrainBag.fromObject(cloneDeep(data)));
  }

  public key(): string {
    if (this) {
      return this.objKey;
    } else {
      return "";
    }
  }

  public startLocation(): pond.Location {
    let start = pond.Location.create();
    start.latitude = this.settings.startLocation?.latitude ?? 0;
    start.longitude = this.settings.startLocation?.longitude ?? 0;
    return start;
  }

  public endLocation(): pond.Location {
    let end = pond.Location.create();
    end.latitude = this.settings.endLocation?.latitude ?? 0;
    end.longitude = this.settings.endLocation?.longitude ?? 0;
    return end;
  }

  public bushels(): number {
    return this.settings.currentBushels;
  }

  public capacity(): number {
    return this.settings.bushelCapacity;
  }

  public isCustom(): boolean {
    return this.settings.storageType !== pond.BinStorage.BIN_STORAGE_SUPPORTED_GRAIN;
  }

  public name(): string {
    if (this) {
      return this.title;
    } else {
      return "";
    }
  }

  public fillPercent(): number {
    let fill = 0;
    if (this.settings.bushelCapacity > 0) {
      fill = Math.round((this.settings.currentBushels / this.settings.bushelCapacity) * 100);
    }
    return fill;
  }

  public objectType(): pond.ObjectType {
    return pond.ObjectType.OBJECT_TYPE_GRAIN_BAG;
  }

  public objectTypeString(): string {
    return "Grain Bag";
  }

  public storage(): pond.BinStorage {
    return this.settings.storageType;
  }

  public grain(): pond.Grain {
    return this.settings.supportedGrain;
  }

  public customType(): string {
    return this.settings.customGrain;
  }

  public subtype(): string {
    return this.settings.grainSubtype;
  }

  public centerLocation(): pond.Location {
    let center = pond.Location.create();
    if (this.startLocation() && this.endLocation()) {
      center.longitude = (this.startLocation().longitude + this.endLocation().longitude) / 2;
      center.latitude = (this.startLocation().latitude + this.endLocation().latitude) / 2;
    }
    return center;
  }

  /**
   * returns the bushels per tonne set in the bins settings, if not set will return 1
   * @returns 1 or bushels per tonne
   */
  public bushelsPerTonne(): number {
    //trying to avoid a divide by 0 error by only returning a value greater than 0
    //since to get the weight you divide the current bushels by the bushels per tonne
    let bpt = 1;
    if (this.settings.currentBushels) {
      if (this.settings.bushelsPerTonne > 0) {
        bpt = this.settings.bushelsPerTonne;
      }
    }
    return bpt;
  }

  public grainName(): string {
    if (this.grain() !== pond.Grain.GRAIN_INVALID) {
      if (this.grain() === pond.Grain.GRAIN_CUSTOM) {
        return this.customType();
      } else {
        return GrainDescriber(this.grain()).name;
      }
    } else {
      return "None";
    }
  }
}
