import * as d3 from "d3"
import React, {FC, LegacyRef, useEffect, useRef} from "react"
import {rainfall} from "../../types";

const RainfallGraph: FC<RainfallGraphProps> = ({width, height, data, start_date, end_date}) => {

    const svgRef = useRef<SVGSVGElement|null>(null)

    useEffect(() => {
        renderSVG()
    }, [width, height, data])

    const renderSVG = () => {
        const margin = {top: 10, right: 30, bottom: 30, left: 20}
        const gWidth = width - margin.left - margin.right
        const gHeight = height - margin.top - margin.bottom

        d3.select(svgRef.current).selectAll("*").remove()
        const svg = d3.select(svgRef.current)
            .attr('width', gWidth + margin.left + margin.right)
            .attr('height', gHeight + margin.top + margin.bottom)
            .attr('class', 'relative')
            .append('g')
            .attr('transform', "translate(" + margin.left + "," + margin.top + ")")

        const yMax = data.reduce((result, item) => item.value > result ? item.value : result, 0)
        const y = d3.scaleLinear()
            .domain([0, yMax + 10])
            .range([gHeight, 0])

        const x = d3.scaleUtc()
            .domain([(new Date(start_date)), (new Date(end_date))])
            .range([margin.left, width - margin.right])

        const yAxis = svg.append('g')
            .attr('transform', `translate(${margin.left},0)`)
            .call(d3.axisLeft(y).ticks(height / 80))
            .call(g => g.select('.domain').remove())

            .call(g => g.append('text')
                .attr('x', -margin.left)
                .attr('y', 10)
                .attr('fill', 'currentColor')
                .attr('text-anchor', 'start')
            )

        svg.append("g")
            .attr("transform", "translate(0," + gHeight + ")")
            .call(d3.axisBottom(x)
                .tickFormat(
                    // @ts-ignore
                    d3.timeFormat("%d/%m/%Y")
                )
            , 0)

        if (data.length === 0) {
            // no values text
            const titleBox = svg.append("g")
                .attr("x", (width))
                .attr("y", height)

            titleBox.append("text")
                .attr("x", (width / 2))
                .attr("y", height / 2)
                .attr("text-anchor", "middle")
                .style("font-size", "20px")
                .text('Aucune Donnée')
        } else {
            yAxis.call(g => g.selectAll(".tick line").clone()
                .attr("x2", width - margin.left - margin.right)
                .attr("stroke-opacity", 0.1))
        }

        svg.selectAll(".bar")
            .data(data)
            .enter()
            .append("rect")
            .attr("class", "bar")
            .attr("fill", "steelblue")
            .attr("x", d => x(new Date(d.date)) * (1 - (100 / data.length)/100))
            .attr("y", d =>  y(d.value))
            .attr("width", (width - 44 + ((width - 44) / (data.length + 1))) / (data.length + 1) - 2)
            .attr("height", d => height - margin.bottom - 10 - y(d.value))
            .append('title')
            .text(d => `${(new Date(d.date)).toLocaleDateString()} : ${d.value}`)
    }

    return <svg ref={svgRef} />
}

export default RainfallGraph

interface RainfallGraphProps {
    width: number,
    height: number,
    data: rainfall[],
    start_date: string,
    end_date: string,
}
