import {useState, useEffect} from 'react'
import {Select} from 'antd'

import {Column} from './Column'
import {CustomColumn} from './CustomColumn'
import ActiveMessagesOnline from './ActiveMessagesOnline'
import {ModeDisplay} from "./ModeDisplay"
import {UserOfWell} from './UserOfWells'

import LoaderPortal from '../../components/LoaderPortal'
import {Grid, GridItem, Flex} from '../../components/Grid'
import {Subscribe} from '../../services/signalr'
import {TelemetryDataSaubService, TelemetryDataSpinService} from '../../services/api'
import {invokeWebApiWrapperAsync} from '../../components/factory'

import MomentStabPicEnabled from "../../images/DempherOn.png"
import MomentStabPicDisabled from "../../images/DempherOff.png"
import SpinPicEnabled from "../../images/SpinEnabled.png"
import SpinPicDisabled from "../../images/SpinDisabled.png"

import '../../styles/message.css'

const {Option} = Select

const dash = [7, 3]

const blockHeightGroup = {
  label: "Высота блока",
  yDisplay: false,
  linePv: {label: "blockPosition", units: 'м', xAccessorName: "blockPosition", yAccessorName: "date", color: '#333'},
  lineOther: {
    label: "wellDepth",
    units: 'м',
    xAccessorName: "wellDepth",
    yAccessorName: "date",
    color: '#333',
    showLine: false,
    xConstValue: 30
  },
}

const blockSpeedGroup = {
  label: "Скорость блока",
  yDisplay: false,
  linePv: {label: "blockSpeed", units: 'м/ч', xAccessorName: "blockSpeed", yAccessorName: "date", color: '#0a0'},
  lineSp: {label: "blockSpeedSp", units: 'м/ч', xAccessorName: "blockSpeedSp", yAccessorName: "date", color: '#0a0'},
}

const pressureGroup = {
  label: "Давление",
  yDisplay: false,
  linePv: {label: "pressure", units: 'атм', xAccessorName: "pressure", yAccessorName: "date", color: '#c00'},
  lineSp: {label: "pressureSp", units: 'атм', xAccessorName: "pressureSp", yAccessorName: "date", color: '#c00'},
  lineIdle: {label: "pressureIdle", units: 'атм', xAccessorName: "pressureIdle", yAccessorName: "date", color: '#c00'},
  linesOther: [
    {
      label: "мекс. перепад",
      units: 'атм',
      xAccessorName: "pressureDeltaLimitMax",
      yAccessorName: "date",
      color: '#c00'
    },
  ],
}

const axialLoadGroup = {
  label: "Осевая нагрузка",
  yDisplay: false,
  linePv: {label: "axialLoad", units: 'т', xAccessorName: "axialLoad", yAccessorName: "date", color: '#00a'},
  lineSp: {label: "axialLoadSp", units: 'т', xAccessorName: "axialLoadSp", yAccessorName: "date", color: '#00a', dash},
  linesOther: [
    {label: "axialLoadLimitMax", units: 'т', xAccessorName: "axialLoadLimitMax", yAccessorName: "date", color: '#00a'},
  ],
}

const hookWeightGroup = {
  label: "Вес на крюке",
  yDisplay: false,
  linePv: {label: "hookWeight", units: 'т', xAccessorName: "hookWeight", yAccessorName: "date", color: '#0aa'},
  lineIdle: {
    label: "hookWeightIdle",
    units: 'т',
    xAccessorName: "hookWeightIdle",
    yAccessorName: "date",
    color: '#0aa',
    dash
  },
  linesOther: [
    {
      label: "hookWeightLimitMin",
      units: 'т',
      xAccessorName: "hookWeightLimitMin",
      yAccessorName: "date",
      color: '#0aa'
    },
    {
      label: "hookWeightLimitMax",
      units: 'т',
      xAccessorName: "hookWeightLimitMax",
      yAccessorName: "date",
      color: '#0aa'
    },
  ],
}

const rotorTorqueGroup = {
  label: "Момент на роторе",
  yDisplay: false,
  linePv: {label: "rotorTorque", units: 'кН·м', xAccessorName: "rotorTorque", yAccessorName: "date", color: '#a0a'},
  lineSp: {label: "rotorTorqueSp", units: 'кН·м', xAccessorName: "rotorTorqueSp", yAccessorName: "date", color: '#a0a'},
  lineIdle: {
    label: "rotorTorqueIdle",
    units: 'кН·м',
    xAccessorName: "rotorTorqueIdle",
    yAccessorName: "date",
    color: '#a0a'
  },
  linesOther: [
    {
      label: "rotorTorqueLimitMax",
      units: 'кН·м',
      xAccessorName: "rotorTorqueLimitMax",
      yAccessorName: "date",
      color: '#a0a'
    },
  ],
}

const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup]

const timePeriodCollection = [
  {value: '60', label: '1 минута'},
  {value: '300', label: '5 минут'},
  {value: '600', label: '10 минут'},
  {value: '1800', label: '30 минут'},
  {value: '3600', label: '1 час'},
  {value: '21600', label: '6 часов'},
  {value: '43200', label: '12 часов'},
  {value: '86400', label: '24 часа'}
]

const defaultChartInterval = '600'

const getLast = (data) =>
  Array.isArray(data) ? data.slice(-1)[0] : data

const isMseEnabled = (dataSaub) => {
  const lastData = getLast(dataSaub)
  return (lastData?.mseState && 2) > 0
}

const isTorqueStabEnabled = (dataSpin) => {
  const lastData = getLast(dataSpin)
  return lastData?.state === 7
}

const isSpinEnabled = (dataSpin) => {
  const lastData = getLast(dataSpin)
  return lastData?.state > 0 && lastData?.state !== 6
}

const getIndexOfDrillingBy = (dataSaub)=>{
  const order = {
    0: -1,
    1: 1, // скорость
    2: 2, // давление
    3: 3, // нагрузка
    4: 5, // момент
  }
  const idFeedRegulator = getLast(dataSaub)?.idFeedRegulator??0
  return order[idFeedRegulator]??-1
}

export default function TelemetryView({idWell}) {
  const [dataSaub, setDataSaub] = useState([])
  const [dataSpin, setDataSpin] = useState([])
  const [chartInterval, setChartInterval] = useState(defaultChartInterval)
  const [showLoader, setShowLoader] = useState(false)

  const options = timePeriodCollection.map((line) => <Option key={line.value}>{line.label}</Option>)

  const handleDataSaub = (data) => {
    if (data) {
      data.forEach((_, idx) => {
        if (data[idx].rotorSpeed < 1)
          data[idx].rotorSpeed = 0;
        if (data[idx].rotorTorque < 1)
          data[idx].rotorTorque = 0;
        data[idx].blockSpeed = Math.abs(data[idx].blockSpeed)
      })
      setDataSaub(data)
    }
  }

  const handleDataSpin = (data) => {
    if (data) {
      setDataSpin(data)
    }
  }

  useEffect(() => {
    invokeWebApiWrapperAsync(
      async () => {
        const dataSaub = await TelemetryDataSaubService.getData(idWell, null, chartInterval)
        const dataSpin = await TelemetryDataSpinService.getData(idWell, null, chartInterval)
        handleDataSaub(dataSaub)
        handleDataSpin(dataSpin)
      },
      setShowLoader,
      `Не удалось получить данные по скважине "${idWell}"`,
    )    
    const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub)
    const unsubscribeSpin = Subscribe('hubs/telemetry', 'ReceiveDataSpin', `well_${idWell}`, handleDataSpin)
    return () => {
      unsubscribeSaub()
      unsubscribeSpin()
    }
  }, [idWell, chartInterval])

  return (<LoaderPortal show={showLoader}>
    <Grid style={{gridTemplateColumns: 'auto repeat(6, 1fr)'}}>
      <GridItem col='1' row='1' colSpan='8' style={{marginBottom: '0.5rem'}}>
        <Flex>
          <ModeDisplay data={dataSaub}/>
          <div style={{marginLeft: '1rem'}}>
            Интервал:&nbsp;
            <Select defaultValue={defaultChartInterval} onChange={setChartInterval}>
              {options}
            </Select>
          </div>
          <span style={{flexGrow: 20}}>&nbsp;</span>
          <img src={isTorqueStabEnabled(dataSpin) ? MomentStabPicEnabled : MomentStabPicDisabled} style={{marginRight: "15px"}} alt="TorqueMaster"/>
          <img src={isSpinEnabled(dataSpin) ? SpinPicEnabled : SpinPicDisabled} style={{marginRight: "15px"}} alt="SpinMaster"/>
          <h2 style={{marginBottom: 0, marginRight: "15px",fontWeight: "bold", color: isMseEnabled(dataSaub) ? "green" : "lightgrey"}}>MSE</h2>
          <UserOfWell data={dataSaub}/>
        </Flex>
      </GridItem>
      <GridItem col='1' row='2' rowSpan='3' style={{minWidth:'260px', width:'0.142fr'}}>
        <CustomColumn data={dataSaub}/>
      </GridItem>
      {paramsGroups.map((group, index) =>
        <GridItem col={2 + index} row='2' className='border_small' key={group.label}>          
          <Column 
            style={{width:'13vw'}}
            data={dataSaub}
            lineGroup={group}
            interval={chartInterval}
            showBorder={getIndexOfDrillingBy(dataSaub) === index}/>
        </GridItem>
      )}

      <GridItem col='2' row='3' colSpan='7'>
        <ActiveMessagesOnline idWell={idWell}/>
      </GridItem>
    </Grid>
  </LoaderPortal>)
}