import { FC, useEffect, useState } from 'react';
import { LocalizeText, localizeWithFallback, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { normalizeWiredValueTarget, variableTokenFromId, WiredValueOrVariableField, wiredValueTargetKey } from '../WiredValueOrVariableField';
import { readWiredVariableToken, toWiredVariableId, wiredVariableIdList } from '../WiredVariableIds';
import { getCustomVariableItemId } from '../WiredVariablePickerData';
import { WiredExtraBaseView } from './WiredExtraBaseView';
import { Checkbox } from '../../../../common/Checkbox';
import { NativeTextTree } from '../../../../common/native-text/NativeTextTree';

const MIN_FILTER = 1;
const MAX_FILTER = 1000;
const TARGET_USER = 1;

const clampValue = (value: number) => {
    if (isNaN(value)) return MIN_FILTER;

    return Math.max(MIN_FILTER, Math.min(MAX_FILTER, Math.floor(value)));
};

/**
 * Official layout: [N, N from a variable, variable target], variable ids [N variable], no string; ours follow:
 * [random pick]. The variable is read on the triggering holder.
 */
export const WiredExtraFilterAmountView: FC<{}> = () => {
    const { trigger = null, setIntParams = null, setStringParam = null, setVariableIds = null } = useWired();
    const [amount, setAmount] = useState(String(MIN_FILTER));
    const [fromVariable, setFromVariable] = useState(false);
    const [target, setTarget] = useState(TARGET_USER);
    const [token, setToken] = useState('');
    const [randomPick, setRandomPick] = useState(true);
    const [amountValid, setAmountValid] = useState(true);

    useEffect(() => {
        if (!trigger) return;

        const d = trigger.intData;

        setAmount(String(clampValue(d[0] ?? 0)));
        setFromVariable(d[1] === 1);
        setTarget(d.length > 2 ? normalizeWiredValueTarget(d[2]) : TARGET_USER);
        setRandomPick(d.length > 3 ? d[3] === 1 : true);
        setToken(readWiredVariableToken(trigger.variableIds, 0, variableTokenFromId(trigger.stringData)));
    }, [trigger]);

    const save = () => {
        const variableId = fromVariable ? getCustomVariableItemId(token) : 0;

        setIntParams([clampValue(Number(amount)), fromVariable ? 1 : 0, target, randomPick ? 1 : 0]);
        setStringParam('');
        setVariableIds(wiredVariableIdList(variableId > 0 ? toWiredVariableId(wiredValueTargetKey(target), token) : ''));
    };

    const validate = () => amountValid && (!fromVariable || getCustomVariableItemId(token) > 0);

    return (
        <NativeTextTree>
            <WiredExtraBaseView hasSpecialInput={true} requiresFurni={WiredFurniType.STUFF_SELECTION_OPTION_NONE} save={save} validate={validate} cardStyle={{ width: 360 }}>
                <div className="flex flex-col gap-2">
                    <Text bold>{LocalizeText('wiredfurni.params.setfilter')}</Text>
                    {/* AIR SelectorFilter / VariableFilter: createValueOrVariableSection(0, mergedSourceOptions(0), setfilter, 1, 1000).
                        The server reads the variable on the triggering holder, so the popup offers the type selector only. */}
                    <WiredValueOrVariableField
                        isVariable={fromVariable}
                        label={LocalizeText('wiredfurni.params.setfilter')}
                        literal={amount}
                        max={MAX_FILTER}
                        min={MIN_FILTER}
                        target={target}
                        token={token}
                        onIsVariableChange={setFromVariable}
                        onLiteralChange={setAmount}
                        onTargetChange={setTarget}
                        onTokenChange={setToken}
                        onValidityChange={setAmountValid}
                    />
                    <label className="flex items-center gap-1">
                        <Checkbox checked={randomPick} onCheckedChange={(nextChecked) => setRandomPick(nextChecked)} />
                        <Text>{localizeWithFallback('wiredfurni.params.filter.random', 'Pick at random (off: the first N)')}</Text>
                    </label>
                </div>
            </WiredExtraBaseView>
        </NativeTextTree>
    );
};
