import { Feature } from 'maplibre-gl'

import length from '@turf/length'

export class FeatureTarget {
  constructor(
    public feature: Feature,
    public distance: number,
    public direction?: number,
  ) {}
}

export interface TreeBucket {
  [id: string]: number
}

export class Trail {
  constructor(
    public id: number,
    public name: string,
    public description: string,
    public feature: GeoJSON.Feature,
    public trees: Trees,
    public photo?: string,
  ) {}

  get length(): number {
    return length(<any>this.feature, {units: 'meters'})
  }

  get mapRouteArgs(): Object {
    return { queryParams: { 'show': `trail:id:${this.id}`}}
  }

  get treeList(): Tree[] {
    return Object.values(this.trees)
  }

  getTreeBucket(): TreeBucket {
    const counts = {};
    let plantekeys = this.treeList.map(t => t.plantekeyId)
    plantekeys.forEach((x) => {
      counts[x] = (counts[x] || 0) + 1;
    })
    return counts
  }

  getPhotoUrl(): string {
    return `/attachment/trail/${this.id}/${this.photo}`
  }
}

export class Trails {
  [id: string]: Trail
}

export class PlantsTrails {
  [plantId: string]: Trails
}

export class Tree {
  constructor(
    public id: string, // UUID
    public feature: GeoJSON.Feature,
    public plantekeyId?: string,
    public photo?: string,
    public data?: Object,
    public height?: string,
    public comments?: string,
    public plant?: Plant,
    public trails: Trail[] = [],
  ) {}

  getPhotoUrl(): (string | void) {
    if (this.photo) {
      if (this.photo.startsWith('data:image')) {
        return this.photo
      }
      else {
        return `/attachment/tree/${this.id}/${this.photo}`
      }
    }
    else {
      return this.plant.get_thumbnail_url()
    }
  }
}

export interface Trees {
  [id: string]: Tree
}

export class TreeTrails {
  [treeId: string]: Trails
}

export class TreeTrail {
  constructor(
    public tree_id: string,
    public trail_id: number,
  ) {}
}

export class Poi {
  constructor(
    public id: number,
    public feature: GeoJSON.Feature,
    public name?: string,
    public type?: string,
    public description?: string,
    public photo?: string,
    public data?: Object,
  ) {}

  getPhotoUrl(): string {
    return `/attachment/poi/${this.id}/${this.photo}`
  }
}

export class Pois {
  [id: string]: Poi
}

export class Zone {
  constructor(
    public id: number,
    public geojson: GeoJSON.Feature,
    public name?: string,
    public type?: string,
    public description?: string,
    public photo?: string,
    public data?: Object,
  ) {}

  getPhotoUrl(): string {
    return `/attachment/zone/${this.id}/${this.photo}`
  }
}

export class Zones {
  [id: string]: Zone
}

export class Style {
  constructor(
    public layer: string,
    public paint?: Object,
    public layout?: Object,
  ) {}
}

export class Styles {
  [layer: string]: Style
}

export class Plant {
  constructor(
    public ID: string,
    public id: string,
    public english: string,
    public family: string,
    public hindi: string,
    public img: string,
    public name: string,
    public spiritual: string,
    public tamil: string,
    public type: string,
    public description: string,
    public habit: string,
    public landscape: string,
    public uses: string,
    public planting: string,
    public propagation: string,
    public element: string,
    public woody: string,
    public latex: string,
    public leaf_style: string,
    public leaf_type: string,
    public leaf_arrangement: string,
    public leaf_aroma: string,
    public leaf_length: string,
    public leaf_width: string,
    public flower_color: string,
    public flower_aroma: string,
    public flower_size: string,
    public fruit_color: string,
    public fruit_size: string,
    public fruit_type: string,
    public thorny: string,
    public images: string[],
    public symbol: string,
  ) {}

  get_thumbnail_url() {
    return '/attachment/plantekey/thumb/' + this.img
  }

  isMatch(searchText: string) {
    searchText = searchText.toLowerCase()
    return (
      this.id.indexOf(searchText) != -1 ||
      this.name.indexOf(searchText) != -1 ||
      (this.english && this.english.toLowerCase().indexOf(searchText) != -1)
    )
  }

  getFriendlyName(): string {
    if (this.english) {
      return `${this.name} (${this.english})`
    }
    else if (this.spiritual) {
      return `${this.name} (${this.spiritual})`
    }
    else {
      return this.name
    }
  }
}

export class Plants {
  [id: string]: Plant
}

export class All {
  constructor(
    public trees: Trees = {},
    public trails: Trails = {},
    public tree_trails: TreeTrail[] = [],
    public plants: Plants = {},
    public pois: Pois = {},
    public zones: Zones = {},
    public styles: Styles = {},
  ) {}
}

export class Role {
  constructor(
    public name: String,
  ) {}
}

export class User {
  constructor(
    public username: String,
    public roles: Role[],
    public full_name?: String,
    public email?: String,
  ) {}
}
/*
let layer: LayerSpecification = <LayerSpecification>{
  id: layerDef.store,
  type: layerDef.type,
  source: <GeoJSONSourceSpecification>{
      type: "geojson",
      data: data
  },
  attribution: resp.style.attribution
}
*/
