import {Alert, Button, Checkbox, Modal, Progress, Spin, Tooltip, Upload} from "antd";
import {UploadOutlined, LoadingOutlined} from "@ant-design/icons";
import {api, downloadImportTemplate, startAnalysis, uploadPointsFile} from "../api.js";
import {download} from "../utils.js";
import {useState} from "react";
import {useQuery} from "@tanstack/react-query";
import {Title} from "../components/Title.jsx";

const antIcon = <LoadingOutlined style={{ fontSize: 14 }} spin />
const Loader = (props) => <Spin indicator={antIcon} size={'small'} {...props}/>

const useStatusInfo = ({taskId, onSuccess}) => {
  return useQuery(['tasks', taskId], async () => {
    const {data} = await api.get(`/api/task/${taskId}/`)
    return data;
  }, {enabled: taskId !== null, refetchInterval: 1000, onSuccess });
}

const Uploader = ({text, dataType, onSuccess, onError}) => {
  const [shouldRefill, setShouldRefill] = useState(false);
  const [taskId, setTaskId] = useState(null);
  const [isFinished, setIsFinished] = useState(false)
  const [isInitialUploading, setIsInitialUploading] = useState(false);

  const {data: uploadData, isInitialLoading, isFetching} = useStatusInfo({
    taskId,
    onSuccess: (data) => {
      if (data.description === 'Импорт данных завершен') {
        setTaskId(null)
        setIsFinished(true)
        onSuccess(dataType)
      }
    }})

  const isLoading = isInitialLoading || isFetching

  const onTemplateDownload = async () => {
    const data = await downloadImportTemplate(dataType);
    await download(`${dataType}_template.xlsx`, data);
  }

  const handleFileUpload = async (options) => {
    const { file } = options;
    try {
      setIsInitialUploading(true)
      const response = await uploadPointsFile(file, dataType, shouldRefill);
      if (response.task_id) {
        setTaskId(response.task_id)
      }
    } catch (err) {
      onError(dataType)
      console.error(err)
    } finally {
      setIsInitialUploading(false)
    }
  };

  const getStatusInfo = () => {
    const isIdle = !isInitialUploading && !uploadData && !isFinished
    if (isIdle) return null

    const getPercent = () => {
      if (isInitialUploading) return 0
      if (isFinished) return 100

      return uploadData.progress
    }

    const getMessage = () => {
      if (isInitialUploading) return 'Data import'
      if (isFinished) return 'Data import completed'

      return uploadData.description
    }

    return <div>
      {!isFinished && <Loader className={'mr-2'}/>}
      <Progress
        percent={getPercent()}
        status={isLoading ? 'active' : null}
        size={'small'}
        className={'w-[300px]'}
      />
      <Title text={getMessage()} className='text-xs'/>
    </div>
  }

  return <div>
    <div className='space-x-3'>
      <Tooltip title={'Overwrite data'}>
        <Checkbox checked={shouldRefill} onChange={e => setShouldRefill(e.target.checked)}/>
      </Tooltip>
      <Upload
        name='file'
        accept='application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'
        customRequest={handleFileUpload}
        itemRender={() => null}
      >
        <Button icon={<UploadOutlined />}>{text}</Button>
      </Upload>
      <Button
        className="p-0 text-xs text-grey underline h-auto"
        type="text"
        onClick={onTemplateDownload}
      >
        Download template
      </Button>
    </div>
    {getStatusInfo()}
  </div>
}

export const ImportDataModal = ({onClose}) => {
  const [isInitialAnalysisStarting, setIsInitialAnalysisStarting] = useState(false);
  const [isError, setIsError] = useState(false);
  const [uploadResult, setUploadResult] = useState({
    odpu: null,
    asupr: null,
    moek_scheme: null,
    events: null,
    houses: null
  });
  const [taskId, setTaskId] = useState(null);
  const [isFinished, setIsFinished] = useState(false)
  const {data: uploadData, isInitialLoading, isFetching} = useStatusInfo({
    taskId,
    onSuccess: (data) => {
      if (data.description === 'ПРОЦЕССИНГ данных завершен') {
        setTaskId(null)
        setIsFinished(true)
        onClose()
      }
    }})

  const isLoading = isInitialLoading || isFetching

  const handleUploadSuccess = (dataType) => setUploadResult((prev) => ({...prev, [dataType]: true }) )
  const handleUploadError = (dataType) => setUploadResult((prev) => ({...prev, [dataType]: false }) )

  const hasUploadError = Object.values(uploadResult).some(result => result === null || result === false)

  const handleButtonClick = async () => {
    setIsInitialAnalysisStarting(true);
    try {
      const response = await startAnalysis()
      if (response.task_id) {
        setTaskId(response.task_id)
      }
    } catch (err) {
      console.error(err)
      setIsError(true);
    } finally {
      setIsInitialAnalysisStarting(false);
    }
  }

  const getStatusInfo = () => {
    const isIdle = !isInitialAnalysisStarting && !uploadData && !isFinished
    if (isIdle) return null

    const getPercent = () => {
      if (isInitialAnalysisStarting) return 0
      if (isFinished) return 100

      return uploadData.progress
    }

    const getMessage = () => {
      if (isInitialAnalysisStarting) return 'Начало анализа'
      if (isFinished) return 'Data analysis completed'

      return uploadData.description
    }

    return <div>
      {!isFinished && <Loader className={'mr-2'}/>}
      <Progress
        percent={getPercent()}
        status={isLoading ? 'active' : null}
        size={'small'}
        className={'w-[300px]'}
      />
      <Title text={getMessage()} className='text-xs'/>
    </div>
  }

  return (
    <Modal
      open={true}
      title="Data import"
      width={400}
      footer={null}
      onCancel={onClose}
    >
      <div className='text-center space-y-3'>
        <Alert
          message="Please note that import time can be significant (up to 10 minutes) depending on the size of the input data."
          type="warning"
          className={'mb-5'}
          showIcon
          closable
        />
        <Uploader dataType={'odpu'} text={'Select ODPU file'} onSuccess={handleUploadSuccess} onError={handleUploadError}/>
        <Uploader dataType={'asupr'} text={'Select ASUPR file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
        <Uploader dataType={'moek_scheme'} text={'Select MOEK file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
        <Uploader dataType={'events'} text={'Select events file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
        <Uploader dataType={'houses'} text={'Select houses file'} onSuccess={handleUploadSuccess} onError={handleUploadError} />
        <Button
          key="start-upload"
          className='mt-5'
          type="primary"
          onClick={handleButtonClick}
          loading={isInitialAnalysisStarting}
          disabled={hasUploadError || isLoading}
        >
          Start data analysis
        </Button>
        {getStatusInfo()}
        {isError && <p className='text-red-600'>An error occurred</p>}
      </div>
    </Modal>
  );
}
