import {useState, useEffect} from 'react'
import {useParams} from 'react-router-dom'
import {Row, Col, Select, Table} from 'antd'
import {ChartTimeOnline} from '../components/charts/ChartTimeOnline'
import LoaderPortal from '../components/LoaderPortal'
import {ChartTimeOnlineFooter} from '../components/ChartTimeOnlineFooter'
import {CustomColumn} from '../components/CustomColumn'
import {UserOfWells} from '../components/UserOfWells'
import {ModeDisplay} from '../components/ModeDisplay'
import {Display} from '../components/Display'
import moment from 'moment'
import {Subscribe} from '../services/signalr'
import {DataService, MessageService} from '../services/api'
import '../styles/message.css'
import notify from "../components/notify";

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]

export const Column = ({lineGroup, data, interval}) => {
  let lines = [lineGroup.linePv]

  if (lineGroup.lineSp)
    lines.push(lineGroup.lineSp)

  if (lineGroup.lineOther)
    lines.push(lineGroup.lineOther)

  let dataLast = null
  let pv = null
  if (data?.length > 0) {
    dataLast = data[data.length - 1];
    if (lineGroup.linePv)
      pv = dataLast[lineGroup.linePv?.xAccessorName]
  }

  return (
    <>
      <Display
        label={lineGroup.label}
        value={pv}
        suffix={lineGroup.linePv?.units} isArrowVisible={true}/>
      <ChartTimeOnline
        data={data}
        yDisplay={lineGroup.yDisplay}
        lines={lines}
        interval={interval}/>
      <ChartTimeOnlineFooter
        data={dataLast}
        {...lineGroup} />
    </>)
}

// Словарь категорий для строк таблицы
const categoryDictionary = {
  1: {title: 'Важное'},
  2: {title: 'Предупреждение'},
  3: {title: 'Информация'},
}

// Конфигурация таблицы
const columns = [
  {
    title: 'Дата',
    dataIndex: 'date',
    render: (item) => moment(item).format('DD MMM YYYY, HH:MM:ss'),
    sorter: (a, b) => new Date(b.date) - new Date(a.date),
    sortDirections: ['descend', 'ascend'],
  },
  {
    title: 'Категория',
    dataIndex: 'categoryId',
    render: (_, item) => categoryDictionary[item.categoryId].title,
    style: (_, item) => categoryDictionary[item.categoryId].style,
    sorter: (a, b) => a.categoryId - b.categoryId,
    sortDirections: ['descend', 'ascend'],
  },
  {
    title: 'Сообщение',
    dataIndex: 'message',
    onFilter: (value, record) => record.name.indexOf(value) === 0,
  },
  {
    title: 'Пользователь',
    dataIndex: 'user',
  },
];

export default function TelemetryView(props) {
  let {id} = useParams()
  const [saubData, setSaubData] = useState([])
  const [chartInterval, setChartInterval] = useState(600)
  const [messages, setMessages] = useState([])

  const [loader, setLoader] = useState(false)  // , setLoader

  const handleReceiveDataSaub = (data) => {
    if (data) {
      setSaubData(data)
    }
  }

  const handleReceiveMessages = (messages) => {
    if (messages) {
      setMessages(messages.items.splice(0, 4))
    }
  }

  useEffect(() => {
    setLoader(true)
    let promiseData = DataService.getData(id)
      .then(handleReceiveDataSaub)
      .catch((ex) => {
        notify(`Не удалось загрузить данные по скважине "${id}"`, 'error')
        console.log(ex)
      })

    let promiseMessages = MessageService.getMessage(id)
      .then(handleReceiveMessages)
      .catch((ex) => {
        notify(`Не удалось загрузить сообщения по скважине "${id}"`, 'error')
        console.log(ex)
      })

    Promise.all([promiseData, promiseMessages]).then(()=>setLoader(false))

    let unSubscribeDataSaubHub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub)
    let unSubscribeMessagesHub = Subscribe('hubs/telemetry','ReceiveMessages', `well_${id}`, handleReceiveMessages)
    return () => {
      unSubscribeDataSaubHub()
      unSubscribeMessagesHub()
    }
  }, [id]);

  useEffect(() => {
    setLoader(true)
    DataService.getData(id, null, chartInterval)
      .then(handleReceiveDataSaub)
      .catch(error => console.error(error))
      .finally(()=>setLoader(false))
  }, [id, chartInterval]);

  const colSpan = 24 / (paramsGroups.length)

  return (<LoaderPortal show={loader}>
    <Row style={{marginBottom: '1rem'}}>
      <Col>
        <ModeDisplay data={saubData}/>
      </Col>
      <span style={{flexGrow: 0.1}}>&nbsp;</span>
      <Col>
        Интервал:&nbsp;
        <Select defaultValue="600" onChange={setChartInterval}>
          <Option value='60'>1 минута</Option>
          <Option value='300'>5 минут</Option>
          <Option value='600'>10 минут</Option>
          <Option value='1800'>30 минут</Option>
          <Option value='3600'>1 час</Option>
          <Option value='21600'>6 час</Option>
          <Option value='43200'>12 часов</Option>
          <Option value='86400'>1 день</Option>
        </Select>
      </Col>
      <span style={{flexGrow: 1}}>&nbsp;</span>
      <Col>
        <UserOfWells data={saubData}/>
      </Col>
    </Row>
    <Row>
      <Col span={2}>
        <CustomColumn data={saubData}/>
      </Col>
      <Col span={24 - 2}>
        <Row>
          {paramsGroups.map(group =>
            <Col span={colSpan} className='border_small' key={group.label}>
              <Column data={saubData} lineGroup={group} interval={chartInterval}/>
            </Col>)}
        </Row>
      </Col>
    </Row>
    <Table
      showHeader={false}
      columns={columns}
      dataSource={messages}
      rowClassName={(record) => `event_message_${record.categoryId} event_message`}
      className={'message_table'}
      size={'small'}
      pagination={false}
      rowKey={(record) => record.id}
    />
  </LoaderPortal>)
}