// 'use strict'
/* global m */

import { byKeyToByLang, makeFmt } from './translate.js'

const urlParams = new URLSearchParams(window.location.search)

const matIsSelected = (mat, name, _nameLong) => {
  // i had to disable the following "smart" logic because in skanska's new dispatch the long name is non-unique and this kept selecting multiple materials (effectively selecting the last one) -> so let's just consider (short) name to be the primary key for now
  if (mat.name === name) {
    return true
  }
  /*
  // try exact match first
  if (mat.name === name && mat.namelong === nameLong) {
    return true;
  }
  // then non-exact
  if (mat.name === name || mat.nameLong === nameLong) {
    return true;
  }
  // TODO: should we try a cross-match (name<=>nameLong) as well?
  */
  return false
}

const saveNewPlacement = (vnode, saver) => {
  const d = vnode.state.data
  // TODO: the following is ugly - just send the entire material structure, not just individual attributes (same for the backend side)
  const x = {
    type: d.material_type,
    name: d._mat_name,
    name_long: d._mat_name_long,
    subtype: d._mat_subtype,
    silo_minor: d.silo_minor,
    substitution: d.substitution
  }
  saver(d.k, x)
}

// TODO: put this inside of the component
const onChangeMaterial = (vnode, e, saver) => {
  console.log('onChangeMaterial', e.target.value, vnode.state.data)
  const idx = e.target.value !== '' ? parseInt(e.target.value) : null
  // TODO: the following is ugly - just save the entire material structure, not just individual attributes (same for the backend side)
  vnode.state.data._mat_name = idx != null ? vnode.state.data._possible_materials[idx].name : null
  vnode.state.data._mat_name_long = idx != null ? vnode.state.data._possible_materials[idx].name_long : null
  vnode.state.data._mat_subtype = idx != null ? vnode.state.data._possible_materials[idx].subtype : null
  console.log(vnode.state.data)
  saveNewPlacement(vnode, saver)
}

// TODO: put this inside of the component
const onChangeSiloMinor = (vnode, e, saver) => {
  console.log('onChangeSiloMinor', e.target.value, vnode.state.data)
  vnode.state.data.silo_minor = e.target.value !== '' ? parseInt(e.target.value) : null
  console.log(vnode.state.data)
  saveNewPlacement(vnode, saver)
}

// TODO: put this inside of the component
const onChangeSubstitution = (vnode, e, saver) => {
  console.log('onChangeSubstitution', e.target.value, vnode.state.data)
  vnode.state.data.substitution = e.target.checked
  console.log(vnode.state.data)
  saveNewPlacement(vnode, saver)
}

// TODO: find a proper name
// TODO: move to component
const theBigSaver = (vnode, k, d) => {
  m.request({
    url: './save_new_placement/' + k,
    method: 'POST',
    body: d
  }).then(data => {
    console.log('saved, new data is', data)
    vnode.state.data = data
  })
}

const PlaceListItem = {
  oninit: vnode => {
    vnode.state.data = vnode.attrs.data
  },
  view: vnode => {
    const d = vnode.attrs.data
    const saver = vnode.attrs.saver
    const fmt = vnode.attrs.fmt
    const title = fmt(d.title)
    const posMats = [{ id: null, text: '', selected: 1 }]
    d._possible_materials.forEach((x, idx) => {
      posMats.push({
        id: idx,
        text: x.name + ' (' + x.name_long + ')',
        selected: matIsSelected(x, d._mat_name, d._mat_name_long)
      })
    })
    const posSilos = [{ id: null, text: '', selected: 1 }]
    d._possible_minor_silos.forEach((x, _idx) => {
      posSilos.push({
        text: x,
        selected: x === d.silo_minor
      })
    })
    return m('tr.' + d.material_type, [
      m('td', { title }, title), // TODO: why the tooltip?
      m('td',
        m('select', {
          style: { width: '200px' },
          onchange: e => onChangeMaterial(vnode, e, saver)
        }, posMats.map(x => m('option', {
          value: x.id,
          selected: x.selected,
          disabled: d._is_minor_silo
        }, x.text)))
      ),
      // m("td", {title: fmt("{silo_minor}")}, fmt("{silo_minor_abbrev}:")),
      m('td',
        m('select', {
          style: { width: '50px' },
          onchange: e => onChangeSiloMinor(vnode, e, saver)
        }, posSilos.map(x => m('option', {
          selected: x.selected,
          disabled: d._is_minor_silo
        }, x.text)))
      ),
      // m("td", {title: fmt("{substitution}")}, fmt("{substitution_abbrev}:")),
      m('td',
        m('input', {
          type: 'checkbox',
          checked: d.substitution,
          disabled: d._is_minor_silo,
          onchange: e => onChangeSubstitution(vnode, e, saver)
        }))
    ])
  }
}

const PlaceList = {
  oninit: vnode => {
    console.log('init')
    vnode.state.data = []
    m.request({ url: './get_fill_data', method: 'GET' }).then(data => {
      console.log('GOT', data)
      vnode.state.data = data
    })
  },
  view: vnode => {
    const fmt = vnode.attrs.fmt
    return m('table', [
      m('tr', [
        m('th'),
        m('th'),
        m('th', { title: fmt('{silo_minor}') }, fmt('{silo_minor_abbrev}')),
        m('th', { title: fmt('{substitution}') }, fmt('{substitution_abbrev}'))
      ]),
      ...vnode.state.data.map(x => m(PlaceListItem, {
        data: x,
        saver: (k, d) => theBigSaver(vnode, k, d),
        fmt
      }))
    ])
  }
}

const Main = {
  view: vnode => {
    return m('', [
      m(PlaceList, { filt: vnode.state.filt, fmt: vnode.attrs.fmt })
    ])
  }
}

// TODO: cut-n-pasted from pymanager (and edited)
const Language = {
  oninit: vnode => {
    vnode.state.lang = vnode.attrs.lang || 'cs'
    console.log('lang is', vnode.state.lang)
    vnode.state.byLangDict = {}
    m.request('./captions').then(data => {
      console.log('got lang data', data)
      vnode.state.byLangDict = byKeyToByLang(data)
      vnode.state.fmt = makeFmt(vnode.state.lang, vnode.state.byLangDict)
    })
  },
  view: vnode => {
    if (!vnode.state.fmt) {
      return m('Loading...')
    }
    return m(vnode.attrs.theChild, { fmt: vnode.state.fmt }) // TODO: find a better way than "theChild"
  }
}

m.mount(document.getElementById('content'), { view: () => m(Language, { lang: urlParams.get('lang'), theChild: Main }) })
