/** @module */
import colorBlender, { rgbToString } from './colorBlender.js'
import getResultsPhaseOptions from '../phase/getResultsPhaseOptions.js'
import getTallyFractions from './getTallyFractions.js'
export default function districtColors(districtElectionResults, candidateList, optionsBag, simOptions) {
    const {
        votesByTract,
        votesByDistrict,
        scResultsByDistrict,
    } = districtElectionResults
    const canList = candidateList.getEntities()
    const colorByTract = colorTracts(votesByTract, canList)
    const colorOfWinsByDistrict = colorDistrictWins(scResultsByDistrict, canList, optionsBag, simOptions)
    const colorOfVoteByDistrict = colorDistrictVote(votesByDistrict, canList)
    const gc = {
        colorByTract,
        colorOfVoteByDistrict,
        colorOfWinsByDistrict,
    }
    return gc
}
function colorTracts(votesByTract, canList) {
    // get color
    const colorSet = canList.map((can) => can.colorRGBA)
    const colorByTract = votesByTract.map(
        (row) => row.map(
            (votes) => {
                const tallyFractions = getTallyFractions(votes)
                const color = colorBlender(tallyFractions, colorSet)
                return color
            },
        ),
    )
    return colorByTract
}
function colorDistrictWins(scResultsByDistrict, canList, optionsBag, simOptions) {
    // calculate color for win map
    let colorOfWinsByDistrict
    const resultsPhaseOptions = getResultsPhaseOptions(optionsBag, simOptions)
    const { socialChoiceType } = resultsPhaseOptions
    if (socialChoiceType === 'singleWinner') {
        colorOfWinsByDistrict = scResultsByDistrict.map(
            (socialChoiceResults) => canList[socialChoiceResults.iWinner].color,
        )
    } else {
        const colorSet = canList.map((can) => can.colorRGBA)
        colorOfWinsByDistrict = scResultsByDistrict.map(
            (socialChoiceResults) => {
                const { allocation } = socialChoiceResults
                const sum = allocation.reduce((p, c) => p + c)
                const fractions = allocation.map((x) => x / sum)
                const color = rgbToString(colorBlender(fractions, colorSet))
                return color
            },
        )
    }
    return colorOfWinsByDistrict
}
/**
 * Update color for each district, based on votes for each candidate.
 * Blend candidate colors in proportion to their votes.
 * @param {Candidate[]} canList - An array of Candidate objects.
 * @returns {String[]} - List of color strings indexed by district.
 */
function colorDistrictVote(votesByDistrict, canList) {
    const colorOfVoteByDistrict = votesByDistrict.map((votes) => {
        const tallyFractions = getTallyFractions(votes)
        const colorSet = canList.map((can) => can.colorRGBA)
        const color = rgbToString(colorBlender(tallyFractions, colorSet))
        return color
    })
    return colorOfVoteByDistrict
}