import React, { useContext } from 'react';
import { makeStyles } from '../../shared/makeStyles';
import { Divider } from '../DiceMessageWrapper/images/Divider';
import { DividerResult } from '../DiceMessageWrapper/images/DividerResult';
import { DieIcon } from '../DieIcon';
import { Flex } from '../Flex';
import { GameLogContext, toggleMessageExpandedActionType, } from '../GameLogContextProvider';
// TODO: clean up when dice is more tree-shake-able
var RollKind;
(function (RollKind) {
    RollKind["None"] = "";
    RollKind["Advantage"] = "advantage";
    RollKind["Disadvantage"] = "disadvantage";
    RollKind["CriticalHit"] = "critical hit";
})(RollKind || (RollKind = {}));
/**
 * returns `''` for 0 or undefined, `'+ 1'` for 1, `'- 2'` for -2, etc.
 */
const toSigned = (value) => value && value !== 0
    ? value > 0
        ? `+ ${value}`
        : `- ${Math.abs(value)}`
    : '';
/**
 * returns `'1 + 2 + 3'`, or in the case of adv/dis: `'(1, 2) + 3'`, or just
 * `'?'` if no result exists yet
 */
const getRollText = ({ result, rollKind }) => result
    ? `${rollKind === RollKind.Advantage || rollKind === RollKind.Disadvantage
        ? `(${result.values.join(', ')})`
        : result.values.join(' + ')} ${toSigned(result.constant)}`
    : '?';
/**
 * `'1d4+1d6+3'` or, in the case of adv: `'2d20kh1+3'`, or dis: `'2d20kl1+3'`
 *
 * TODO: this used to create `DiceNotation` and `DieTerm` class instances just
 * to call `toString` on them (see below). It seems wrong-ish to do all that
 * "extra" work, but also not reusing complicated serialization logic seems
 * wrong too ... maybe some kind of shared utils lib? The approach listed below
 * failed in test, and I just kinda don't want to dig into why (Jest, Babel,
 * Rollup, et al configs) until we figure this out.
 *
 * ```ts
 * const getRollNotation = (roll: RollRequestRoll): string =>
 *   new DiceNotation(
 *     roll.diceNotation.set.map(
 *       ({ count, dieType, operation, operand }) =>
 *         new DieTerm(count, dieType, operation, operand),
 *     ),
 *     roll.diceNotation.constant,
 *   ).toDiceNotationString();
 * ```
 *
 * n.b. need also to keep in mind Avrae and rolls generated by sources other
 * than `@dndbeyond/dice`
 *
 * @see https://github.com/DnDBeyond/ddb-game-log/pull/92#pullrequestreview-569551274
 * @see https://wikia-inc.atlassian.net/browse/DDBADV-1922
 */
const getRollNotation = (roll) => `${roll.diceNotation.set
    .map((set) => `${set === null || set === void 0 ? void 0 : set.count}${set === null || set === void 0 ? void 0 : set.dieType}`)
    .join('+')}${roll.rollKind === RollKind.Advantage ? 'kh1' : ''}${roll.rollKind === RollKind.Disadvantage ? 'kl1' : ''}${toSigned(roll.diceNotation.constant).replace(' ', '')}`;
const rollTypeToColor = ({ rollTypeRollColor, rollTypeToHitColor, rollTypeDamageColorSelf, rollTypeDamageColor, rollTypeCheckColorSelf, rollTypeCheckColor, rollTypeSaveColor, rollTypeAdvantageColor, rollTypeDisadvantageColor, rollTypeDefaultColor, }, { roll, isSelf }) => {
    var _a;
    return ((_a = {
        roll: rollTypeRollColor,
        'to hit': rollTypeToHitColor,
        damage: isSelf ? rollTypeDamageColorSelf : rollTypeDamageColor,
        check: isSelf ? rollTypeCheckColorSelf : rollTypeCheckColor,
        spell: isSelf ? rollTypeCheckColorSelf : rollTypeCheckColor,
        save: rollTypeSaveColor,
        heal: rollTypeSaveColor,
        advantage: rollTypeAdvantageColor,
        disadvantage: rollTypeDisadvantageColor,
    }[roll.rollType]) !== null && _a !== void 0 ? _a : rollTypeDefaultColor);
};
const rollTypeToColorForTotalHeader = ({ rollTypeAdvantageColorSelf, rollTypeAdvantageColor, rollTypeDisadvantageColorSelf, rollTypeDisadvantageColor, }, { roll, isSelf }) => ({
    advantage: isSelf ? rollTypeAdvantageColorSelf : rollTypeAdvantageColor,
    disadvantage: isSelf
        ? rollTypeDisadvantageColorSelf
        : rollTypeDisadvantageColor,
}[roll.rollType]);
const useStyles = makeStyles()(({ gameLog: { actionColorPending, fontRoboto, fontRobotoCondensed, messageColorOther, rollTypeAdvantageColor, rollTypeAdvantageColorSelf, rollTypeCheckColor, rollTypeCheckColorSelf, rollTypeDamageColor, rollTypeDamageColorSelf, rollTypeDefaultColor, rollTypeDisadvantageColor, rollTypeDisadvantageColorSelf, rollTypeRollColor, rollTypeSaveColor, rollTypeToHitColor, targetColorSelf, valueColorOther, valueColorPending, valueColorSelf, }, }, { roll, isSelf }, classes) => ({
    DiceResultContainer: {
        width: '100%',
        cursor: 'pointer',
    },
    Line: {
        overflow: 'hidden',
        whiteSpace: 'nowrap',
        textOverflow: 'ellipsis',
    },
    Notation: {
        fontSize: '14px',
        color: messageColorOther,
        fontFamily: fontRoboto,
        fontWeight: 500,
    },
    Title: {
        fontFamily: fontRobotoCondensed,
        textTransform: 'uppercase',
        fontWeight: 700,
        [`&.${classes.Self}`]: {
            color: targetColorSelf,
        },
    },
    Breakdown: {
        fontSize: '1.25rem',
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'flex-start',
        width: '100%',
        fontFamily: fontRoboto,
        fontWeight: 500,
        '& > svg': {
            flex: '0 0 auto',
        },
    },
    Number: {
        [`&.${classes.Self}`]: {
            color: valueColorSelf,
        },
        [`&.${classes.Other}`]: {
            color: valueColorOther,
        },
        [`&.${classes.Pending}`]: {
            color: valueColorPending,
        },
    },
    Target: {
        [`&.${classes.Self}`]: {
            color: targetColorSelf,
        },
        [`&.${classes.Other}`]: {
            color: messageColorOther,
        },
    },
    Action: {
        [`&.${classes.Pending}`]: {
            color: actionColorPending,
        },
    },
    RollType: {
        color: rollTypeToColor({
            rollTypeRollColor,
            rollTypeToHitColor,
            rollTypeDamageColorSelf,
            rollTypeDamageColor,
            rollTypeCheckColorSelf,
            rollTypeCheckColor,
            rollTypeSaveColor,
            rollTypeAdvantageColor,
            rollTypeDisadvantageColor,
            rollTypeDefaultColor,
        }, { roll, isSelf }),
    },
    Result: {
        flex: '1 1 auto',
        minWidth: 0,
        overflow: 'hidden',
    },
    Divider: {
        margin: '0 12px',
        flex: '0 0 auto',
    },
    DividerResult: {
        margin: '0 12px',
        flex: '0 0 auto',
        '&$Target': {
            marginTop: '12px',
        },
    },
    TotalContainer: {
        position: 'relative',
        alignSelf: 'stretch',
    },
    TotalHeader: {
        fontFamily: fontRobotoCondensed,
        fontSize: '0.75rem',
        fontWeight: 'bold',
        textTransform: 'uppercase',
        position: 'absolute',
        top: '1px',
        color: rollTypeToColorForTotalHeader({
            rollTypeAdvantageColorSelf,
            rollTypeAdvantageColor,
            rollTypeDisadvantageColorSelf,
            rollTypeDisadvantageColor,
        }, { roll, isSelf }),
    },
    Total: {
        minWidth: '2.5rem',
        fontSize: '2rem',
        fontWeight: 'bold',
        flex: '0 0 auto',
        lineHeight: 1,
        [`&.${classes.Self}`]: {
            color: valueColorSelf,
        },
        [`&.${classes.Other}`]: {
            color: valueColorOther,
        },
        [`&.${classes.Collapsed}`]: {
            fontSize: '1.4rem',
        },
        [`&.${classes.Pending}`]: {
            color: valueColorPending,
        },
        [`&.${classes.Target}`]: {
            marginTop: '13px',
        },
    },
    DieIcon: {
        marginRight: '6px',
        color: messageColorOther,
    },
    Self: {},
    Other: {},
    Pending: {},
    Collapsed: {},
}));
export const DiceMessage = (props) => {
    var _a, _b, _c, _d, _e, _f, _g;
    const { message, isSelf, roll, isPending, isCollapsed } = props;
    const { classes, cx } = useStyles({ roll, isSelf });
    const [{ userId, activeCampaign }, dispatch] = useContext(GameLogContext);
    const dmUserId = (_b = (_a = activeCampaign === null || activeCampaign === void 0 ? void 0 : activeCampaign.dmId) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '';
    const toggleIsExpanded = () => {
        var _a;
        return dispatch({
            type: toggleMessageExpandedActionType,
            payload: {
                messageId: (_a = message.data.rollId) !== null && _a !== void 0 ? _a : '',
                wasExpandedByUser: true,
            },
        });
    };
    return (React.createElement(Flex, { className: classes.DiceResultContainer, justifyContent: "space-between", onClick: toggleIsExpanded },
        React.createElement("div", { className: classes.Result },
            React.createElement("div", { className: cx(classes.Line, classes.Title, isSelf ? classes.Self : classes.Other) },
                React.createElement("span", { className: cx(classes.Action, isPending && classes.Pending) }, message.data.action),
                ": ",
                React.createElement("span", { className: cx(classes.RollType) }, roll.rollType)),
            message.messageScope === 'userId' && (React.createElement("div", { className: cx(classes.Line, classes.Title) },
                React.createElement("span", { className: cx(classes.Target, isSelf ? classes.Self : classes.Other) },
                    "TO:",
                    ' ',
                    message.messageTarget === dmUserId &&
                        message.messageTarget !== userId
                        ? 'DM'
                        : 'Self'))),
            !isCollapsed && (React.createElement(React.Fragment, null,
                React.createElement("div", { className: cx(classes.Line, classes.Breakdown) },
                    roll.diceNotation.set.length > 0 && (React.createElement(DieIcon, { className: classes.DieIcon, forDie: (_e = (_d = (_c = roll.diceNotation.set[0]) === null || _c === void 0 ? void 0 : _c.dice[0]) === null || _d === void 0 ? void 0 : _d.dieType) !== null && _e !== void 0 ? _e : 'd20' })),
                    React.createElement("span", { className: cx(classes.Line, classes.Number, isSelf ? classes.Self : classes.Other, isPending && classes.Pending), title: getRollText(roll) }, getRollText(roll))),
                React.createElement("div", { className: cx(classes.Line, classes.Notation) },
                    React.createElement("span", null, getRollNotation(roll)))))),
        isCollapsed ? (React.createElement(Divider, { className: classes.Divider })) : (React.createElement(DividerResult, { className: cx(classes.DividerResult, message.messageScope === 'userId' ? classes.Target : '') })),
        React.createElement(Flex, { className: classes.TotalContainer, flexDirection: "column" },
            !isCollapsed &&
                (roll.rollKind === RollKind.Advantage ||
                    roll.rollKind === RollKind.Disadvantage) && (React.createElement("small", { className: cx(classes.TotalHeader) },
                React.createElement("span", null,
                    roll.rollKind === RollKind.Advantage && '+ADV',
                    roll.rollKind === RollKind.Disadvantage && '-DIS'))),
            React.createElement(Flex, { className: cx(classes.Total, isSelf ? classes.Self : classes.Other, isCollapsed && classes.Collapsed, isPending && classes.Pending, message.messageScope === 'userId' && !isCollapsed
                    ? classes.Target
                    : '') },
                React.createElement("span", null, (_g = (_f = roll.result) === null || _f === void 0 ? void 0 : _f.total) !== null && _g !== void 0 ? _g : '...')))));
};
//# sourceMappingURL=DiceMessage.js.map