// @ts-nocheck /* OR @ ts-expect-error */

export interface Config {
  // activeType: string
  // activeFocus: string
  sizePreset: string
  bedType: string
  otherPreset: string
  label: string
  botSizeX: number
  botSizeY: number
  botSizeZ: number
  bedWallThickness: number
  bedHeight: number
  ccSupportSize: number
  x: number
  y: number
  z: number
  beamLength: number
  columnLength: number
  zAxisLength: number
  bedXOffset: number
  bedYOffset: number
  bedZOffset: number
  zGantryOffset: number
  bedWidthOuter: number
  bedLengthOuter: number
  legSize: number
  legsFlush: boolean
  extraLegsX: number
  extraLegsY: number
  bedBrightness: number
  soilBrightness: number
  soilHeight: number
  plants: string
  labels: boolean
  labelsOnHover: boolean
  ground: boolean
  grid: boolean
  axes: boolean
  trail: boolean
  tracks: boolean
  clouds: boolean
  sunInclination: number
  sunAzimuth: number
  perspective: boolean
  bot: boolean
  laser: boolean
  tool: string
  cableCarriers: boolean
  viewCube: boolean
  stats: boolean
  config: boolean
  zoom: boolean
  pan: boolean
  bounds: boolean
  threeAxes: boolean
  xyDimensions: boolean
  zDimension: boolean
  promoInfo: boolean
  solar: boolean
  utilitiesPost: boolean
  packaging: boolean
  lab: boolean
  people: boolean
  scene: string
  lowDetail: boolean
}

export const INITIAL: Config = {
  sizePreset: "Genesis XL",
  bedType: "Mobile",
  otherPreset: "Initial",
  label: "ThreeD Garden FarmBot Genesis XL v1.6",
  botSizeX: 2720,
  botSizeY: 1230,
  botSizeZ: 500,
  bedWallThickness: 40,
  bedHeight: 300,
  ccSupportSize: 50,
  x: 300,
  y: 700,
  z: 200,
  beamLength: 1500,
  columnLength: 500,
  zAxisLength: 1000,
  bedXOffset: 140,
  bedYOffset: 60,
  bedZOffset: 0,
  zGantryOffset: 140,
  bedWidthOuter: 1360,
  bedLengthOuter: 3000,
  legSize: 100,
  legsFlush: true,
  extraLegsX: 1,
  extraLegsY: 0,
  bedBrightness: 8,
  soilBrightness: 6,
  soilHeight: 500,
  plants: "Spring",
  labels: false,
  labelsOnHover: true,
  ground: true,
  grid: false,
  axes: false,
  trail: false,
  tracks: true,
  clouds: true,
  sunInclination: 140,
  sunAzimuth: 230,
  perspective: true,
  bot: true,
  laser: false,
  tool: "rotaryTool",
  cableCarriers: true,
  viewCube: false,
  stats: false,
  config: false,
  zoom: false,
  pan: false,
  bounds: false,
  threeAxes: false,
  xyDimensions: false,
  zDimension: false,
  promoInfo: true,
  solar: false,
  utilitiesPost: true,
  packaging: false,
  lab: false,
  people: false,
  scene: "Outdoor",
  lowDetail: false,
}

export const STRING_KEYS = [
  "sizePreset", "bedType", "otherPreset", "label", "plants", "tool", "scene",
]

export const NUMBER_KEYS = [
  "botSizeX", "botSizeY", "botSizeZ", "bedWallThickness", "bedHeight",
  "ccSupportSize", "x", "y", "z", "beamLength", "columnLength", "zAxisLength",
  "bedXOffset", "bedYOffset", "bedZOffset", "zGantryOffset", "bedWidthOuter",
  "bedLengthOuter", "legSize", "extraLegsX", "extraLegsY", "bedBrightness",
  "soilBrightness", "soilHeight", "sunInclination", "sunAzimuth",
]

export const BOOLEAN_KEYS = [
  "legsFlush", "labels", "labelsOnHover", "ground", "grid", "axes", "trail",
  "tracks", "clouds", "perspective", "bot", "laser", "cableCarriers",
  "viewCube", "stats", "config", "zoom", "pan", "bounds", "threeAxes",
  "xyDimensions", "zDimension", "promoInfo", "solar", "utilitiesPost",
  "packaging", "lab", "people", "lowDetail",
]

export const PRESETS: Record<string, Config> = {
  "Jr": {
    ...INITIAL,
    sizePreset: "Jr",
    bedType: "Standard",
    label: "FarmBot Jr",
    botSizeX: 620,
    botSizeY: 220,
    botSizeZ: 250,
    beamLength: 550,
    columnLength: 300,
    zAxisLength: 750,
    bedXOffset: 140,
    bedYOffset: 80,
    zGantryOffset: 140,
    bedWidthOuter: 400,
    bedLengthOuter: 900,
    extraLegsX: 0,
    extraLegsY: 0,
    soilHeight: 280,
    tracks: true,
  },
  "Genesis": {
    ...INITIAL,
    sizePreset: "Genesis",
    bedType: "Standard",
    label: "FarmBot Genesis v1.7",
    botSizeX: 2720,
    botSizeY: 1230,
    botSizeZ: 500,
    beamLength: 1500,
    columnLength: 500,
    zAxisLength: 1000,
    bedXOffset: 140,
    bedYOffset: 60,
    zGantryOffset: 140,
    bedWidthOuter: 1360,
    bedLengthOuter: 3000,
    extraLegsX: 1,
    extraLegsY: 0,
    soilHeight: 500,
    tracks: true,
  },
  "Genesis XL": {
    ...INITIAL,
    sizePreset: "Genesis XL",
    bedType: "Mobile",
    label: "ThreeD FarmBot Genesis XL v1.6",
    botSizeX: 5720,
    botSizeY: 2730,
    botSizeZ: 500,
    beamLength: 3000,
    columnLength: 500,
    zAxisLength: 1000,
    bedXOffset: 140,
    bedYOffset: 60,
    zGantryOffset: 140,
    bedWidthOuter: 2860,
    bedLengthOuter: 6000,
    extraLegsX: 3,
    extraLegsY: 1,
    soilHeight: 500,
    tracks: true,
  },
  "Initial": INITIAL,
  "Minimal": {
    ...INITIAL,
    bedWallThickness: 40,
    bedHeight: 300,
    x: 300,
    y: 200,
    z: 200,
    ccSupportSize: 50,
    legSize: 100,
    legsFlush: false,
    bedBrightness: 8,
    soilBrightness: 6,
    plants: "",
    labels: false,
    labelsOnHover: false,
    ground: true,
    grid: false,
    axes: false,
    trail: false,
    clouds: false,
    sunInclination: 90,
    sunAzimuth: 0,
    perspective: true,
    bot: true,
    laser: false,
    tool: "",
    cableCarriers: true,
    viewCube: false,
    stats: false,
    config: false,
    zoom: true,
    pan: true,
    bounds: false,
    threeAxes: false,
    xyDimensions: false,
    zDimension: false,
    promoInfo: false,
    solar: false,
    utilitiesPost: false,
    packaging: false,
    lab: false,
    people: false,
    scene: "Outdoor",
    lowDetail: false,
  },
  "Maximal": {
    ...INITIAL,
    bedWallThickness: 40,
    bedHeight: 300,
    x: 300,
    y: 200,
    z: 200,
    ccSupportSize: 50,
    legSize: 100,
    legsFlush: true,
    bedBrightness: 8,
    soilBrightness: 6,
    plants: "Spring",
    labels: true,
    labelsOnHover: false,
    ground: true,
    grid: true,
    axes: true,
    trail: true,
    clouds: true,
    sunInclination: 30,
    sunAzimuth: 45,
    perspective: true,
    bot: true,
    laser: true,
    tool: "",
    cableCarriers: true,
    viewCube: true,
    stats: true,
    config: true,
    zoom: true,
    pan: true,
    bounds: true,
    threeAxes: true,
    xyDimensions: true,
    zDimension: true,
    promoInfo: true,
    solar: true,
    utilitiesPost: true,
    packaging: true,
    lab: true,
    people: true,
    scene: "outdoor",
    lowDetail: false,
  },
}

const SIZE_CONFIG_KEYS: (keyof Config)[] = [
  "sizePreset", "label", "bedType",
  "botSizeX", "botSizeY", "botSizeZ", "beamLength", "columnLength", "zAxisLength",
  "bedXOffset", "bedYOffset", "zGantryOffset", "bedWidthOuter", "bedLengthOuter",
  "extraLegsX", "extraLegsY", "soilHeight", "tracks",
]

const OTHER_CONFIG_KEYS: (keyof Config)[] = [
  "bedWallThickness", "bedHeight", "x", "y", "z",
  "ccSupportSize", "legSize", "legsFlush",
  "bedBrightness", "soilBrightness", "plants", "labels", "ground", "grid", "axes",
  "trail", "clouds", "sunInclination", "sunAzimuth", "perspective", "bot", "laser",
  "tool", "cableCarriers", "viewCube", "stats", "config", "zoom", "bounds",
  "threeAxes", "xyDimensions", "zDimension", "labelsOnHover", "promoInfo", "pan",
  "solar", "utilitiesPost", "packaging", "lab", "people", "scene", "lowDetail",
]

export const modifyConfig = (config: Config, update: Partial<Config>) => {
  const newConfig: Config = { ...config, ...update }
  if (update.sizePreset) {
    const presetConfig = PRESETS[update.sizePreset]
    SIZE_CONFIG_KEYS.map(key => newConfig[key] = presetConfig[key] as never)
    if (update.sizePreset == "Jr") {
      newConfig.x = 100
      newConfig.y = 100
      newConfig.z = 50
    }
  }
  if (update.scene) {
    newConfig.lab = update.scene == "Lab"
    newConfig.clouds = update.scene != "Lab"
    newConfig.people = update.scene == "Lab"
    newConfig.bedType =
      (update.scene == "Lab" && newConfig.sizePreset != "Genesis XL")
        ? "Mobile"
        : "Standard"
  }
  if (update.bedType || (newConfig.bedType != config.bedType)) {
    newConfig.bedZOffset = newConfig.bedType == "Mobile" ? 500 : 0
    newConfig.legsFlush = newConfig.bedType == "Mobile" ? false : true
  }
  if (update.otherPreset) {
    if (update.otherPreset == "Reset all") {
      Object.keys(config).map(key => {
        const configKey = key as keyof Config
        newConfig[configKey] = INITIAL[configKey] as never
      })
    } else {
      const presetConfig = PRESETS[update.otherPreset]
      OTHER_CONFIG_KEYS.map(key => newConfig[key] = presetConfig[key] as never)
    }
  }
  return newConfig
}

export const KIT_LOOKUP: { [x: string]: string } = {
  "genesis": "Genesis",
  "genesis_xl": "Genesis XL",
  "jr": "Jr",
}

export const modifyConfigsFromUrlParams = (config: Config) => {
  let newConfig: Config = { ...config }
  const urlParams = new URLSearchParams(window.location.search)
  const kit = urlParams.get("kit")?.toLowerCase()
  if (kit) {
    const sizePreset = KIT_LOOKUP[kit]
    if (sizePreset && sizePreset != config.sizePreset) {
      newConfig = modifyConfig(newConfig, { sizePreset })
    }
  }
  STRING_KEYS.map(key => {
    const value = urlParams.get(key)
    if (value) {
      newConfig = modifyConfig(newConfig, { [key]: value })
    }
  })
  NUMBER_KEYS.map(key => {
    const value = urlParams.get(key)
    if (value) {
      newConfig = modifyConfig(newConfig, { [key]: parseInt(value) })
    }
  })
  BOOLEAN_KEYS.map(key => {
    const value = urlParams.get(key)
    if (value) {
      newConfig = modifyConfig(newConfig, { [key]: value == "true" })
    }
  })
  return newConfig
}






export const setUrlFocusParam = (value: string) => {
  const url = new URL(window.location.href)
  if (value) {
    url.searchParams.set("focus", value)
  } else {
    url.searchParams.delete("focus")
  }
  window.history.replaceState({}, "", url.toString())
}

export const getFocusFromUrlParams = () => {
  const urlParams = new URLSearchParams(window.location.search)
  return urlParams.get("focus") || ""
}









type SeasonProperties = {
  sunIntensity: number
  sunColor: string
  cloudOpacity: number
}
export const seasonProperties: Record<string, SeasonProperties> = {
  Winter: { sunIntensity: 4 / 4, sunColor: '#A0C4FF', cloudOpacity: 0.85 },
  Spring: { sunIntensity: 7 / 4, sunColor: '#BDE0FE', cloudOpacity: 0.2 },
  Summer: { sunIntensity: 9 / 4, sunColor: '#FFFFFF', cloudOpacity: 0 },
  Fall: { sunIntensity: 5.5 / 4, sunColor: '#FFD6BC', cloudOpacity: 0.3 },
}

export const detailLevels = (config: Config) =>
  config.lowDetail ? [0, 0] : [0, 25000]