import 'react-sweet-progress/lib/style.css'
import '../styles/project-dashboard.scss'
import { List, Map } from 'immutable'
import React, { useContext, useEffect, useState } from 'react'
import { ExperimentDetail } from './project/ExperimentDetail'
import { FETCH_EXPERIMENTS_INTERVAL } from '../constants'
import { GlobalContext } from '../context'
import { MetricsGraph } from './project/MetricsGraph'
import { ParamsList } from './project/ParamsList'
import { ProjectDetail } from './project/ProjectDetail'
import { ProjectHeader } from './project/ProjectHeader'
import { useParams } from 'react-router-dom'

const ExperimentList = (props) => (
  <div className='experiment-list'>
    <ProjectDetail project={props.project} dataset={props.dataset} />
    {props.experiments.size === 0 &&
      <div className='empty'>
        <span>NO EXPERIMENTS</span>
      </div>}
    {props.experiments.size > 0 &&
      <ul className='experiments'>
        {props.experiments.map((experiment) => (
          <li key={experiment.id}>
            <ExperimentDetail experiment={experiment} />
          </li>
        ))}
      </ul>}
  </div>
)

const ProjectMetrics = (props) => {
  const { experiments, project } = props

  const metrics = {}
  const labels = {}
  experiments.forEach((experiment) => {
    Object.entries(experiment.metrics).forEach(([key, values]) => {
      if (!(key in metrics)) {
        metrics[key] = []
        labels[key] = []
      }
      metrics[key].push(values)
      labels[key].push(experiment.name)
    })
  })

  return (
    <div className='project-metrics'>
      {Object.keys(metrics).length === 0 &&
        <div className='empty'>
          <span>NO METRICS</span>
        </div>}
      {Object.keys(metrics).length > 0 &&
        <MetricsGraph metrics={metrics} labels={labels} project={project} />}
      <ParamsList experiments={experiments} />
    </div>
  )
}

export const ProjectDashboard = (props) => {
  const { id } = useParams()
  const { fetchExperiments } = useContext(GlobalContext)
  const [time, setTime] = useState(Date.now())

  const { datasets, projects } = props
  const experiments = props.experiments.get(Number(id)) ?? List([])
  const project = projects.find((p) => p.id === Number(id)) ?? Map({})
  const { datasetId } = project
  const dataset = datasets.find((d) => d.id === Number(datasetId)) ?? Map({})

  // Fetch experiments
  useEffect(() => {
    fetchExperiments(Number(id))
  }, [id])

  // Fetch experiments periodically
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setTime(Date.now())
      fetchExperiments(Number(id))
    }, FETCH_EXPERIMENTS_INTERVAL)
    return () => {
      clearTimeout(timeoutId)
    }
  }, [time])

  return (
    <div className='dashboard'>
      <ProjectHeader project={project} dataset={dataset} />
      <div className='dashboard-body-wrapper'>
        <div className='dashboard-body'>
          <ExperimentList
            project={project}
            dataset={dataset}
            experiments={experiments}
          />
          <ProjectMetrics experiments={experiments} project={project} />
        </div>
      </div>
    </div>
  )
}