/* @flow */

import Observer from '@researchgate/react-intersection-observer'
import withColours from 'Components/utils/withColours'
import React, { Component } from 'react'
import emoji from 'react-easy-emoji'
import { Trans } from 'react-i18next'
import { connect } from 'react-redux'
import { config, Spring } from 'react-spring'
import { compose } from 'redux'
import répartitionSelector from 'Selectors/repartitionSelectors'
import { isIE } from '../utils'
import './Distribution.css'
import Montant from './Montant'
import './PaySlip'
import RuleLink from './RuleLink'

import type { Répartition, Branche } from 'Types/ResultViewTypes.js'

const brancheToEmoji: { [Branche]: string } = {
	retraite: '👵',
	santé: '🏥',
	famille: '👶',
	formation: '👩‍🎓',
	logement: '🏡',
	'accidents du travail / maladies professionnelles': '☣️',
	'assurance chômage': '💸',
	transport: '🚌',
	autres: '🔧'
}

const brancheToCounterparts: { [Branche]: string } = {
	retraite: "Garantit en moyenne 60 à 70 % de votre dernier revenu d'activité.",
	santé:
		"Couvre la plupart des soins de santé de la vie quotidienne et 100 % des maladies graves comme les séjours à l'hôpital.",
	famille:
		"Offre une vie professionnelle et familiale équilibrée. Finance des crèches et divers services de garde d'enfants.",
	formation: "Donne aux employés l'accès à la formation professionnelle.",
	logement: 'Aide à la construction de logements neufs et abordables.',
	'accidents du travail / maladies professionnelles':
		'Offre une couverture complète des maladies ou accidents du travail.',
	'assurance chômage':
		"Assure un revenu aux travailleurs à la recherche d'un nouvel emploi.",
	transport:
		"Aide à maintenir le prix d'un billet de transport en commun à un bas prix.",
	autres: 'Autres contributions au système social.'
}

const brancheToLabel: { [Branche]: string } = {
	'accidents du travail / maladies professionnelles': 'accidents',
	'assurance chômage': 'chômage'
}

type Props = Répartition & {
	colours: { colour: string }
}
type State = {
	branchesInViewport: Array<Branche>
}

const ANIMATION_SPRING = config.gentle
class Distribution extends Component<Props, State> {
	elementRef = null
	state = {
		branchesInViewport: []
	}
	handleBrancheInViewport = branche => (event, unobserve) => {
		if (!event.isIntersecting) {
			return
		}
		unobserve()
		this.setState(({ branchesInViewport }) => ({
			branchesInViewport: [branche, ...branchesInViewport]
		}))
	}

	render() {
		const {
			répartition,
			cotisationMaximum,
			total,
			salaireChargé,
			salaireNet,
			colours: { colour }
		} = this.props
		return (
			<>
				<div className="distribution-chart__container">
					{répartition.map(([branche, { partPatronale, partSalariale }]) => {
						const brancheInViewport =
							this.state.branchesInViewport.indexOf(branche) !== -1
						const montant = brancheInViewport
							? partPatronale + partSalariale
							: 0
						return (
							<Observer
								key={branche}
								threshold={[0.33]}
								onChange={this.handleBrancheInViewport(branche)}>
								<Spring
									config={ANIMATION_SPRING}
									to={{
										flex: montant / cotisationMaximum,
										opacity: montant ? 1 : 0
									}}>
									{styles => (
										<div
											className="distribution-chart__item"
											style={{
												opacity: styles.opacity
											}}>
											<ChartItemLegend branche={branche} />
											<div className="distribution-chart__item-content">
												<p className="distribution-chart__counterparts">
													<span className="distribution-chart__branche-name">
														<Trans i18nKey={`branches.${branche}.name`}>
															{brancheToLabel[branche] || branche}
														</Trans>.{' '}
													</span>
													<Trans i18nKey={`branches.${branche}.counterpart`}>
														{brancheToCounterparts[branche]}
													</Trans>
												</p>
												<ChartItemBar {...{ styles, colour, montant, total }} />
											</div>
										</div>
									)}
								</Spring>
							</Observer>
						)
					})}
				</div>
				<div className="distribution-chart__total">
					<span />
					<RuleLink {...salaireNet} />
					<Montant numFractionDigit={2}>{salaireNet.montant}</Montant>
					<span>+</span>
					<Trans>Cotisations</Trans>
					<Montant numFractionDigit={2}>
						{total.partPatronale + total.partSalariale}
					</Montant>
					<span />
					<div className="distribution-chart__total-border" />
					<span>=</span>
					<RuleLink {...salaireChargé} />
					<Montant numFractionDigit={2}>{salaireChargé.montant}</Montant>
				</div>
			</>
		)
	}
}
export default compose(
	withColours,
	connect(
		répartitionSelector,
		{}
	)
)(Distribution)

let ChartItemBar = ({ styles, colour, montant, total }) => (
	<div className="distribution-chart__bar-container">
		<div
			className="distribution-chart__bar"
			style={{
				backgroundColor: colour,
				...(!isIE()
					? { flex: styles.flex }
					: { minWidth: styles.flex * 500 + 'px' })
			}}
		/>
		<div>
			<Montant
				className="distribution-chart__amount"
				numFractionDigit={0}
				style={{ color: colour }}>
				{montant}
			</Montant>
			<Montant
				numFractionDigit={0}
				type="percent"
				className="distribution-chart__percent">
				{montant / (total.partPatronale + total.partSalariale)}
			</Montant>
		</div>
	</div>
)

let ChartItemLegend = ({ branche }) => (
	<div className="distribution-chart__legend">
		<span className="distribution-chart__icon">
			{emoji(brancheToEmoji[branche])}
		</span>
	</div>
)