export type Annee = Record<string, { t: number[]; y: number[]; i: number }>

export type Sample = {
    hourly: { x: string[]; y: number[] }
    daily: { x: string[]; y: number[] }
    weekly: { x: string[]; y: number[] }
}

export function sample(
    min_t: number,
    max_t: number,
    annee: Annee,
    somme: Sample,
    soleil: Sample
): { auto: number; totalProd: number; totalConso: number }
export function sample(
    min_t: number,
    max_t: number,
    annee: Annee,
    somme: Sample
): undefined
export function sample(
    min_t: number,
    max_t: number,
    annee: Annee,
    somme: Sample,
    soleil?: Sample
): undefined | { auto: number; totalProd: number; totalConso: number } {
    let auto = 0
    let totalProd = 0
    let totalConso = 0

    somme.hourly = { x: [], y: [] }
    somme.daily = { x: [], y: [] }
    somme.weekly = { x: [], y: [] }

    let i = 0
    for (let [_, r] of Object.entries(annee)) {
        r.i = 0
    }
    for (let t = min_t; t < max_t; t += 3600) {
        let tt = new Date(t * 1000)
        let tds = tt.toLocaleDateString()
        let tts = tt.toLocaleString()
        let y = 0
        for (let [_, r] of Object.entries(annee)) {
            // Les profils Enedis sont échantillonnés à la
            // demi-heure, il faut ajouter deux points consécutifs
            while (r.i < r.t.length && r.t[r.i] < t + 3600) {
                if (!isNaN(r.y[r.i])) y += r.y[r.i]
                r.i += 1
            }
        }
        somme.hourly.x.push(tts)
        somme.hourly.y.push(y)
        if ((t - min_t) % (24 * 3600) == 0) {
            if ((t - min_t) % (24 * 7 * 3600) == 0) {
                somme.weekly.x.push(tds)
                somme.weekly.y.push(y)
            } else {
                somme.weekly.y[somme.weekly.y.length - 1] += y
            }
            somme.daily.x.push(tds)
            somme.daily.y.push(y)
        } else {
            somme.daily.y[somme.daily.y.length - 1] += y
            somme.weekly.y[somme.weekly.y.length - 1] += y
        }
        totalConso += y
        if (soleil) {
            totalProd += soleil.hourly.y[i]
            auto += Math.min(y, soleil.hourly.y[i])
        }
        i += 1
    }
    if (soleil) {
        return {
            auto,
            totalProd,
            totalConso,
        }
    }
}

export type PlotSample = {
    x: (number | string)[]
    y: number[]
    bucket: number
}

export function chooseScale(s: Sample & PlotSample, w?: number) {
    console.log('chooseScale', w)
    // ww: nombre d'échantillons bruts à afficher
    let ww = w || s.hourly.x.length
    let bbox = (<SVGGraphicsElement | undefined>(
        document.getElementsByClassName('bglayer')[0]
    ))?.getBBox()
    let width = (bbox?.width || 100) / 3
    console.log(bbox?.width)
    if (ww <= width) {
        s.x = s.hourly.x
        s.y = s.hourly.y
        s.bucket = 1
    } else if (ww / 24 <= width) {
        s.x = s.daily.x
        s.y = s.daily.y
        s.bucket = 24
    } else {
        s.x = s.weekly.x
        s.y = s.weekly.y
        s.bucket = 24 * 7
    }
}

export function relayout(
    event: any,
    plot: HTMLElement,
    Plotly: any,
    layout: any,
    has_plot: { has_plot: boolean },
    soleil: Sample & PlotSample,
    somme: Sample & PlotSample
) {
    console.log('relayout')
    if (event.bucket) {
        return false
    }
    let w = event['xaxis.range[1]'] - Math.max(0, event['xaxis.range[0]'])
    let layout_ = JSON.parse(JSON.stringify(layout))
    if (!plot) {
        return false
    }

    if (isNaN(w)) {
        chooseScale(soleil)
        chooseScale(somme)
        layout_.xaxis.autorange = true
        layout_.yaxis.autorange = true
        event.bucket = soleil.bucket
    } else {
        let sb = soleil.bucket
        if (event.bucket) {
            w *= event.bucket
        } else {
            w *= soleil.bucket
        }
        chooseScale(soleil, w)
        chooseScale(somme, w)
        let sb_ = soleil.bucket
        event['xaxis.range[0]'] *= sb / sb_
        event['xaxis.range[1]'] *= sb / sb_
        event.bucket = soleil.bucket
        layout_.xaxis.range = [event['xaxis.range[0]'], event['xaxis.range[1]']]
        let unite: string
        if (soleil.bucket == 24) {
            unite = 'kWh/jour'
        } else if (soleil.bucket == 24 * 7) {
            unite = 'kWh/semaine'
        } else {
            unite = 'kWh'
        }
        layout_.yaxis.title.text = unite
        layout_.yaxis.autorange = true
        layout_.yaxis.fixedrange = false
    }

    if (has_plot.has_plot) {
        Plotly!.update(plot, [soleil, somme], layout_)
    } else {
        Plotly!.newPlot(plot, [soleil, somme], layout_, {
            responsive: true,
        })
        //@ts-ignore
        plot.on('plotly_relayout', (event: any) =>
            relayout(event, plot, Plotly, layout, has_plot, soleil, somme)
        )
        has_plot.has_plot = true
    }
}