import { useState, useEffect } from "react";
import { useParams } from 'react-router-dom';
import {
  Form,
  DatePicker,
  Radio,
  Button,
  Select,
  Table,
  Progress, 
  notification
} from 'antd';
import 'moment/locale/ru';
import locale from 'antd/lib/locale/ru_RU';
import moment from "moment";
import {Subscribe} from '../services/signalr';
import notify from '../components/notify';
import LoaderPortal from '../components/LoaderPortal';
import { ReportService } from '../services/api';

const { RangePicker } = DatePicker;
const { Option } = Select;

let reportDatesRange = {
  from: moment("0001-01-01T00:00:00"),
  to: moment("9999-12-31T23:59:59.9999999")
}

const timePeriodNames = [
  {label: '1 секунда', value: 1},
  {label: '10 секунд', value: 10},
  {label: '1 минута', value: 60},
  {label: '5 минут', value: 300},
  {label: '30 минут', value: 1800},
  {label: '1 час', value: 3600},
  {label: '6 часов', value: 21600},
  {label: '12 часов', value: 43200},
  {label: '1 день', value: 86400},
  {label: '1 неделя', value: 604800}
]

const  firstStep = timePeriodNames[2]["value"]

const imgPaths = {
  '.pdf': '/images/pdf.png',
  '.las': '/images/las.png'
}


// Экспорт рендера
export default function Report(props) { 
  
  const [rangeDate, setRangeDate] = useState([moment().subtract(1,'days'), moment()])
  const [step, setStep] = useState(firstStep)
  const [format, setFormat] = useState(0)
  const [approxPages, setPagesCount] = useState(0)
  const [suitableReports, setSuitableReports] = useState([])
  const [loader, setLoader] = useState(false)


  let wellId = useParams().id;

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

  const columns = [
    {
      title: '',
      dataIndex: 'reportFormat',
      key: 'reportFormat',
      render: format => <img src={imgPaths[format]} width="50" alt={format}></img>
    },
    {
      title: 'Параметры отчета',
      dataIndex: 'reportParams',
      key: 'reportParams',
    },
    {
      title: 'Название отчета',
      dataIndex: 'reportName',
      key: 'reportName',
      render: name => <button onClick={event => getReportFile(event, name)} download={name}>{name}</button>
    },
  ];
  
  const ReportCreationNotify = ({progressData}) => {
    progressData = progressData ?? {progress: 0.0, operation: 'Создание отчета', reportName: ''} 

    return (
    <>
        <Progress percent={ progressData.progress } />
        <br />
        <span> { progressData.operation } </span>
        <br />
        <button onClick={event => {getReportFile(event, progressData.reportName)}}
          download={progressData.reportName}>
          { progressData.reportName } 
        </button>
    </>
    )
  }

  const getReportFile = async (event, reportFileName) => {
    const element = event.target

    if(!element.href.length) {
      try {
        await fetch(`/api/report/${wellId}/${reportFileName}`, {
          headers: {
            Authorization: 'Bearer ' + localStorage['token']
          }
        })
        .then(async (response) => {
          const blob = await response.blob();
  
          let reader = new FileReader();
          reader.readAsDataURL(blob);
          reader.onload = function (e) {
            element.href = e.target.result
            element.click()
          };
        });
      } catch (error) {
        notify(`Не удалось скачать отчет по скважине (${wellId}) c 
        ${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по 
        ${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
        console.log(error)
      }
    }
  }

  const handleReportCreation = async (values) => {
    let begin = rangeDate[0].toISOString()
    let end = rangeDate[1].toISOString()

    try {
      const taskId = await ReportService.createReport(wellId, values.step, values.format, begin, end)
      if(!taskId)
        return 

      const handleReportProgress = (progressData) => {
        if(progressData) {
          notification.open({
            key: taskId,
            message: 'Создание отчета:',
            description: <ReportCreationNotify progressData={progressData}></ReportCreationNotify>,
            duration: 0
          });

          if (progressData.reportName?.length)
            unSubscribeReportHub()
        }
      }

      const unSubscribeReportHub = Subscribe('hubs/reports', 'GetReportProgress', `Report_${taskId}`, handleReportProgress)
    }
    catch(error) {
      notify(`Не удалось создать отчет по скважине (${wellId}) c 
      ${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по 
      ${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
      console.log(error)
    }
  }

  function disabledDate(current) {
    return reportDatesRange.From  >= current || reportDatesRange.To  <= current;
  }

  useEffect(()=>{
    async function getRepostSizeAsync() {
      let begin = rangeDate[0].toISOString()
      let end = rangeDate[1].toISOString()
      try {
        let approxPagesResponse = await ReportService.getReportSize(wellId, step, format, begin, end)
        setPagesCount(approxPagesResponse)
      } catch(error) {
        notify(`Не удалось получить предварительный размер отчета c 
                ${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по 
                ${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
        console.log(error)
      } finally {
        setLoader(false)
      }
    }

    getRepostSizeAsync()
  },[rangeDate, step, format, wellId])

  useEffect(()=>{
    async function getSuitableReportsAsync() {
      let begin = rangeDate[0].toISOString()
      let end = rangeDate[1].toISOString()
      try {
        setLoader(true)
        let suitableReportsResponse = await ReportService.getSuitableReportsNames(wellId, step, format, begin, end)
        let suitableReports = suitableReportsResponse.map(value => {
          return { 
            key: value.id,
            reportFormat: value.format,
            reportParams: `Дата создания: ${new Date(value.date).toLocaleDateString()}, 
                          Данные от ${new Date(value.begin).toLocaleString()} 
                          до ${new Date(value.end).toLocaleString()}, 
                          Шаг: ${timePeriodNames[value.step]}`,
            reportName: value.name
          }
        })
        setSuitableReports(suitableReports)
      } catch(error) {
        notify(`Не удалось получить подходящие по параметрам отчеты c 
                ${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по 
                ${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
        console.log(error)
      } finally {
        setLoader(false)
      }
    }

    getSuitableReportsAsync()
  },[rangeDate, step, format, wellId])

  useEffect(()=>{
    async function getDatesRange() {
      let response = await ReportService.getReportsDateRange(wellId)
      reportDatesRange.from = moment(response.from)
      reportDatesRange.to = moment(response.to)
    }

    getDatesRange()
  },[wellId])

  return (<>
    <div className="w-100 mt-20px">
      <Form
        layout="vertical"
        name="reportForm"
        initialValues={{ remember: true }}
        onFinish={handleReportCreation}
      >
        <div className={'d-flex'}>
          <Form.Item
            label="Диапазон дат отчета"
            name="period"
            initialValue = { [rangeDate[0], rangeDate[1]] }
          >
            <RangePicker
              disabledDate={disabledDate}
              allowClear={false}
              onCalendarChange = { (dates, dateStrings, info) => {
                  setRangeDate([moment(dateStrings[0]), moment(dateStrings[1])])
                }
              } 
              locale={locale} 
              showTime 
            />
          </Form.Item>
          <Form.Item
            label="Шаг графиков"
            name="step"
            initialValue={step}
            className="ml-30px"
          >
            <Select onChange={setStep}
            >
              {periods}
            </Select>
          </Form.Item>
          <Form.Item
              label="Формат отчета"
              name="format"
              initialValue = {format}
              onChange={(e) => setFormat(e.target.value)}
              className="ml-30px"
          >
              <Radio.Group>
                <Radio.Button value={0}>PDF</Radio.Button>
                <Radio.Button value={1}>LAS</Radio.Button>
              </Radio.Group>
          </Form.Item>
          <Button 
            type="primary" 
            htmlType="submit"
            className="mt-30px ml-30px">
            <span>Получить рапорт</span>
            <span className={'ml-5px'}>
              ({approxPages} стр.)
            </span> 
            <span style={{display: approxPages > 100 ? 'inline' : 'none'}} className={'ml-5px'}>
              !!!
            </span> 
          </Button>
        </div>
      </Form>
    </div>
    <br/>
    <h3>
      Отчеты с аналогичными параметрами, доступные для скачивания:
    </h3> <br/>
    
    <LoaderPortal show={loader}>
      <Table dataSource={suitableReports} columns={columns} />
    </LoaderPortal>
  </>
  )
}
