import '@material/web/icon/icon.js'
import '@operato/property-editor/ox-properties-dynamic-view.js'
import '@operato/markdown'
import '@operato/board/ox-board-viewer.js'

import { css, html, LitElement } from 'lit'
import { customElement, property } from 'lit/decorators.js'

import { ScrollbarStyles } from '@operato/styles'
import { i18next } from '@operato/i18n'

import { SMALLVALUE, formatValueWithPrecision } from './utils'

const STED_COMPOSITION_LIST = ['H2O', 'N2', 'O2', 'N2O', 'CO2', 'CH4', 'C2H6', 'C3H8']

@customElement('equipment-info')
export class EquipmentInfo extends LitElement {
  static styles = [
    ScrollbarStyles,
    css`
      :host {
        display: block;
        background-color: var(--main-section-background-color);
      }

      [center] {
        text-align: center;
      }
      div {
        margin: var(--margin-wide) var(--margin-default) var(--margin-default) var(--margin-default);
        padding: var(--padding-default);
        background-color: var(--theme-white-color);
        border-radius: 10px;
        box-shadow: var(--box-shadow);
      }
      h2 {
        margin: 0;
        padding: var(--padding-narrow) 4px;
        font: var(--subtitle-font);
        color: var(--subtitle-text-color);
      }
      table {
        border-collapse: collapse;
        background-color: #fff;
        width: 100%;
        margin: auto;
      }
      tr {
        border-bottom: var(--border-dark-color);
      }
      th {
        border-top: 2px solid var(--focus-background-color);
        border-right: 1px solid var(--primary-color);
        background-color: var(--secondary-text-color);
        padding: var(--padding-narrow);
        color: var(--theme-white-color);
      }

      tr td:first-child {
        background-color: rgba(0, 0, 0, 0.05);
        text-align: right;
      }
      td {
        padding: var(--padding-narrow);
        border-right: var(--border-dark-color);
        text-align: right;
        font-size: 0.8em;
      }
      td:last-child {
        border-right: 0;
      }

      tr[doubleline] {
        border-bottom: 2px double rgba(0, 0, 0, 0.2);
      }

      [subTh] {
        text-align: center !important;
        font-weight: bold;
      }

      [subTh2] {
        background-color: rgba(var(--primary-color-rgb), 0.5) !important;
        color: #fff;
        text-align: center !important;
        font-weight: bold;
        font-size: 1em;
      }
      [formation] td:first-child {
        background-color: rgba(var(--primary-color-rgb), 0.05) !important;
        font-weight: bold;
        color: var(--primary-color);
      }
      [formation]:nth-child(odd) {
        background-color: rgba(var(--primary-color-rgb), 0.02);
      }

      tr:hover,
      [formation]:hover {
        background-color: var(--focus-background-color) !important;
      }

      @media screen and (max-width: 460px) {
        :host {
          width: 100vw;
        }
        div {
          margin: 0;
          padding: var(--padding-default);
          background-color: transparent;
          border-radius: 0;
          box-shadow: none;
        }
        th {
          font-size: 0.9em;
        }
      }
    `
  ]

  @property({ type: Object }) equipment?: any //StreamLine

  render() {
    const equipment = this.equipment
    var { smartGuides } = equipment.data || {}

    const { inlets = [], outlets = [], anchors } = equipment

    const streams = [
      ...inlets.map(stream => {
        const { refid, streamType: type } = stream?.state || {}
        const { data = {}, to } = stream

        return {
          refid,
          type,
          anchor: to.anchor,
          inout: 'in',
          ...data
        }
      }),
      ...outlets.map(stream => {
        const { refid, streamType: type } = stream?.state || {}
        const { data = {}, from } = stream

        return {
          refid,
          type,
          anchor: from.anchor,
          inout: 'out',
          ...data
        }
      })
    ]

    anchors.forEach(anchor => {
      if (!streams.find(stream => stream.anchor == anchor.name)) {
        streams.push({ anchor: anchor.name, type: anchor.type, inout: anchor.inout })
      }
    })

    var massFractions: any[] = []
    var moleFractions: any[] = []

    STED_COMPOSITION_LIST.forEach(material => {
      massFractions.push(
        streams.map(stream => (stream.type === 'fluid' && stream.Y && material in stream.Y ? stream.Y[material] : null))
      )
      moleFractions.push(
        streams.map(stream => (stream.type === 'fluid' && stream.X && material in stream.X ? stream.X[material] : null))
      )
    })

    const properties = equipment.nature?.properties || []
    const smartGuide = (smartGuides || []).join('</br>')

    return html`
      <div>
        <h2><md-icon>auto_stories</md-icon> smart guide</h2>
        <p>${smartGuide}</p>

        <h2>${i18next.t('label.equipment-property')}</h2>
        <table>
          <tr>
            <th>${i18next.t('label.equipment-property')}</th>
            <th>${i18next.t('label.value')}</th>
          </tr>
          ${properties.length == 0
            ? html`
                <tr>
                  <td subTh colspan="2" center>${i18next.t('text.no property to be shown')}</td>
                </tr>
              `
            : properties.map(property => {
                const { name, type, label, property: prop } = property
                const value = this.equipment.state[name]
                const valueContent =
                  type === 'unit-number'
                    ? `${String(value === undefined ? '-' : value)} ${prop?.unit}`
                    : type === 'mass-fraction'
                    ? !value
                      ? i18next.t('text.no fractions set')
                      : html`
                          <table>
                            ${Object.entries(value).map(
                              ([key, val]) => html`
                                <tr>
                                  <td subTh>${key}</td>
                                  <td>${val}</td>
                                </tr>
                              `
                            )}
                          </table>
                        `
                    : String(value === undefined ? '-' : value)

                return html`
                  <tr>
                    <td subTh>${i18next.t(`label.${label}`)}</td>
                    <td>${valueContent}</td>
                  </tr>
                `
              })}
        </table>
      </div>

      <div>
        <h2>${i18next.t('label.stream-status')}</h2>
        <table>
          <tr>
            <th colspan="2">${i18next.t('label.stream-node')}</th>
            ${streams.length == 0
              ? html` <td rowspan=${massFractions.length + 12} center>${i18next.t('text.no streams connected')}</td> `
              : streams.map(stream => html` <th>${stream.anchor}</th> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.type')}</td>
            ${streams.map(stream => html` <td>${stream.type}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.id')}</td>
            ${streams.map(stream => html` <td>${stream.refid}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.inout')}</td>
            ${streams.map(stream => html` <td>${stream.inout}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.mass')} (kg)</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.m)}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.temperature')} (K)</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.T)}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.pressure')} (Pa)</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.p)}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">비엔탈피 (J/kg)</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.h)}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.moisture-content')} (%)</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.MC)}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">비열 (J/(kg·K))</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.spheat, 4)}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.electric-power')} (W)</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.pwr)}</td> `)}
          </tr>
          <tr>
            <td subTh colspan="2">${i18next.t('label.out-heat')} (W)</td>
            ${streams.map(stream => html` <td>${formatValueWithPrecision(stream.htr)}</td> `)}
          </tr>

          ${massFractions.map((subs, idx) => {
            return html`
              <tr formation>
                ${idx == 0
                  ? html` <td subTh2 rowspan=${massFractions.length}>${i18next.t('label.mass-fraction')}</td> `
                  : html``}
                ${(subs && subs.reduce((acc, cur) => acc + parseFloat(cur || 0.0), 0.0)) > SMALLVALUE
                  ? html`
                      <td>${STED_COMPOSITION_LIST[idx]}</td>
                      ${subs.map(sub => html` <td>${formatValueWithPrecision(sub || 0.0)}</td>`)}
                    `
                  : html``}
              </tr>
            `
          })}
          ${moleFractions.map((subs, idx) => {
            return html`
              <tr formation>
                ${idx == 0
                  ? html` <td subTh2 rowspan="${moleFractions.length}">${i18next.t('label.mole-fraction')}</td> `
                  : html``}
                ${(subs && subs.reduce((acc, cur) => acc + parseFloat(cur || 0.0), 0.0)) > SMALLVALUE
                  ? html`
                      <td>${STED_COMPOSITION_LIST[idx]}</td>
                      ${subs.map(sub => html` <td>${formatValueWithPrecision(sub || 0.0)}</td>`)}
                    `
                  : html``}
              </tr>
            `
          })}
        </table>
      </div>
    `
  }
}
