<script>
    import { getContext } from 'svelte'
    import { Button, Table, InputGroup, InputGroupText, Icon } from 'sveltestrap'
    import MetricSelection from './MetricSelection.svelte'
    import StatsTableEntry from './StatsTableEntry.svelte'
    import { maxScope } from './utils.js'

    export let job
    export let jobMetrics

    const allMetrics = [...new Set(jobMetrics.map(m => m.name))].sort(),
          scopesForMetric = (metric) => jobMetrics
            .filter(jm => jm.name == metric)
            .map(jm => jm.metric.scope)

    let hosts = job.resources.map(r => r.hostname).sort(),
        selectedScopes = {},
        sorting = {},
        isMetricSelectionOpen = false,
        selectedMetrics = getContext('cc-config')[`job_view_nodestats_selectedMetrics:${job.cluster}`]
            || getContext('cc-config')['job_view_nodestats_selectedMetrics']

    for (let metric of allMetrics) {
        selectedScopes[metric] = maxScope(scopesForMetric(metric))
        sorting[metric] = {
            min: { dir: 'up', active: false },
            avg: { dir: 'up', active: false },
            max: { dir: 'up', active: false },
        }
    }

    export function sortBy(metric, stat) {
        let s = sorting[metric][stat]
        if (s.active) {
            s.dir = s.dir == 'up' ? 'down' : 'up'
        } else {
            for (let metric in sorting)
                for (let stat in sorting[metric])
                    sorting[metric][stat].active = false
            s.active = true
        }

        let series = jobMetrics.find(jm => jm.name == metric && jm.metric.scope == 'node')?.metric.series
        sorting = {...sorting}
        hosts = hosts.sort((h1, h2) => {
            let s1 = series.find(s => s.hostname == h1)?.statistics
            let s2 = series.find(s => s.hostname == h2)?.statistics
            if (s1 == null || s2 == null)
                return -1

            return s.dir != 'up' ? s1[stat] - s2[stat] : s2[stat] - s1[stat]         
        })
    }

    export function moreLoaded(jobMetric) {
        jobMetrics = [...jobMetrics, jobMetric]
    }
</script>

<Table>
    <thead>
        <tr>
            <th>
                <Button outline on:click={() => (isMetricSelectionOpen = true, console.log(isMetricSelectionOpen))}>
                    Metrics
                </Button>
            </th>
            {#each selectedMetrics as metric}
                <th colspan={selectedScopes[metric] == 'node' ? 3 : 4}>
                    <InputGroup>
                        <InputGroupText>
                            {metric}
                        </InputGroupText>
                        <select class="form-select"
                            bind:value={selectedScopes[metric]}
                            disabled={scopesForMetric(metric, jobMetrics).length == 1}>
                            {#each scopesForMetric(metric, jobMetrics) as scope}
                                <option value={scope}>{scope}</option>
                            {/each}
                        </select>
                    </InputGroup>
                </th>
            {/each}
        </tr>
        <tr>
            <th>Node</th>
            {#each selectedMetrics as metric}
                {#if selectedScopes[metric] != 'node'}
                    <th>Id</th>
                {/if}
                {#each ['min', 'avg', 'max'] as stat}
                    <th on:click={() => sortBy(metric, stat)}>
                        {stat}
                        {#if selectedScopes[metric] == 'node'}
                            <Icon name="caret-{sorting[metric][stat].dir}{sorting[metric][stat].active ? '-fill' : ''}" />
                        {/if}
                    </th>
                {/each}
            {/each}
        </tr>
    </thead>
    <tbody>
        {#each hosts as host (host)}
            <tr>
                <th scope="col">{host}</th>
                {#each selectedMetrics as metric (metric)}
                    <StatsTableEntry
                        host={host} metric={metric}
                        scope={selectedScopes[metric]}
                        jobMetrics={jobMetrics} />
                {/each}
            </tr>
        {/each}
    </tbody>
</Table>

<br/>

<MetricSelection
    cluster={job.cluster}
    configName='job_view_nodestats_selectedMetrics'
    allMetrics={new Set(allMetrics)}
    bind:metrics={selectedMetrics}
    bind:isOpen={isMetricSelectionOpen} />