"use client";
// import { Vault } from "components/treasury";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Controls, Elements, Layouts } from "../../../../components";
import { Modals } from "../../../../containers";
import { useMobile, usePortal, useTheme, useWindowSize } from "../../../../hooks";
import { Root } from "../../../../lib/style";
import { format, HexToColor, parseNumber } from "../../../../lib/utils";
export default function Listing(props) {
    const { windowWidth } = useWindowSize();
    const { isMobile } = useMobile();
    const { theme } = useTheme();
    const [asset, setAsset] = useState();
    const [pair, setPair] = useState([]);
    const [address, setAddress] = useState("");
    const [currentValue, setCurrentValue] = useState(0);
    const [validate, setValidate] = useState({ state: false });
    const [loading, setLoading] = useState(false);
    const [process, setProcess] = useState(null);
    const [fetching, setFetching] = useState(false);
    const keyTokens = useMemo(() => props?.keyTokens?.filter(({ address: k }) => !pair?.find(({ address: p }) => k?.toLowerCase() === p?.toLowerCase())) || [], [props?.keyTokens, pair]);
    const tokens = useMemo(() => pair?.map((p) => ({
        ...props?.tokens?.find(({ address }) => address?.toLowerCase() === p?.address?.toLowerCase()),
        ...p,
    })), [props?.tokens, pair]);
    const max = (pair &&
        pair?.length > 0 &&
        asset?.amount &&
        Math.max(...[
            ...pair,
            {
                ...asset,
                amount: parseNumber(asset?.amount || 0) / pair?.length,
            },
        ]?.map((p) => parseNumber(p?.amount || 0, "number")))) ||
        0;
    const estimate = useMemo(() => {
        const target = {
            ...asset,
            ...(props?.tokens &&
                props?.tokens?.length > 0 &&
                props?.tokens?.find(({ address }) => address?.toLowerCase() === asset?.address?.toLowerCase())),
        };
        return pair?.reduce((a, b) => {
            const token = tokens?.find(({ address }) => address === b?.address);
            const quote = {
                amount: parseNumber(token?.amount),
                weight: parseNumber(token?.weight),
                locked: parseNumber(token?.locked),
            };
            const base = {
                amount: parseNumber(target?.amount),
                weight: parseNumber(target?.weight),
                locked: parseNumber(target?.locked),
            };
            return (a +
                (quote?.weight > 0
                    ? (quote?.amount * quote?.weight) / quote?.locked
                    : base?.weight > 0
                        ? (base?.amount * base?.weight) / base?.locked
                        : 0));
        }, 0);
    }, [props?.tokens, tokens, asset, pair]);
    const handleTokenValidate = (address) => {
        if (address === asset?.address && validate?.state)
            return;
        let check = { state: false };
        if (!!address && address !== "" && address !== "0" && address !== "0x") {
            const pattern = /^[a-zA-Z0-9]+$/;
            if (!address?.startsWith("0x"))
                check = { state: true, message: "The typed address form of a Token Contract is Invalid." };
            else if (!pattern.test(address))
                check = { state: true, message: "The unacceptable charater is used in address form." };
            else if (address?.length < 42)
                check = { state: true, message: "The address is too short." };
            else if (address?.length > 42)
                check = { state: true, message: "The address is too long." };
        }
        setValidate(check);
        if (address !== asset?.address)
            setAsset(() => ({ address }));
    };
    const handleAddPair = (v) => {
        setPair((state) => [...(state && state), { ...v, amount: 0 }]);
    };
    const handleRemovePair = (target) => {
        setPair((state) => state?.filter(({ address }) => address !== target));
    };
    const maxValue = useCallback(() => {
        const pairs = pair?.map((p) => {
            const value = parseNumber(p?.value);
            const balance = parseNumber(p?.balance?.amount);
            return {
                address: p?.address?.toLowerCase(),
                total: balance * value,
                value,
            };
        });
        const max_value = Math.max(...pairs?.map(({ total }) => total));
        const min_value = Math.min(...pairs?.map(({ total }) => total));
        return min_value > 0 && min_value < max_value ? min_value : max_value;
    }, [pair]);
    const maxAmount = useCallback((address) => {
        const target = pair?.find((p) => p?.address?.toLowerCase() === address?.toLowerCase());
        const max = maxValue();
        return max && !isNaN(max) ? max / parseNumber(target?.value) : undefined;
    }, [pair, maxValue]);
    const handleChangeAmount = (address, amount) => {
        const max_amount = maxAmount(address);
        const a = parseNumber(amount);
        const v = parseNumber(pair?.find((p) => p?.address?.toLowerCase() === address?.toLowerCase())?.value);
        const c = a * v;
        if (!(max_amount && a > max_amount))
            setCurrentValue(c);
        setPair((state) => state?.map((s) => ({
            ...s,
            amount: s?.address?.toLowerCase() === address?.toLowerCase()
                ? max_amount && a > max_amount
                    ? max_amount
                    : amount
                : max_amount && a > max_amount
                    ? maxAmount(s?.address)
                    : c / parseNumber(s?.value),
        })));
    };
    const validating = () => {
        if (!asset?.amount)
            return false;
        const quantity = parseNumber(asset?.amount);
        if (isNaN(quantity))
            return false;
        if (quantity <= 0)
            return false;
        let validate = true;
        let pairs = pair;
        pair?.map((p) => {
            const amount = parseNumber(p?.amount);
            if (p?.address?.toLowerCase() === asset?.address?.toLowerCase() || !p?.amount || isNaN(amount) || amount <= 0) {
                validate = false;
                pairs = pairs?.map((s) => s?.address?.toLowerCase() === p?.address?.toLowerCase()
                    ? { ...s, amount: parseNumber(amount), error: true, message: "Invalid amount." }
                    : s);
            }
        });
        if (!validate) {
            setPair(pairs);
            return false;
        }
        return true;
    };
    const handleListing = async (e) => {
        if (!validating())
            return;
        setLoading(true);
        try {
            if (typeof props?.onProcess === "function")
                await props?.onProcess(e);
        }
        catch {
            setProcess(false);
        }
        setLoading(false);
    };
    const handleBack = (e) => {
        if (typeof props?.onBack === "function")
            props?.onBack(e);
        setLoading(false);
        setProcess(null);
    };
    const handleClose = (e) => {
        if (typeof props?.onClose === "function")
            props?.onClose(e);
        setLoading(false);
        setProcess(null);
    };
    useEffect(() => {
        if (!!address && address !== "" && address !== "0" && address !== "0x" && address.length === 42)
            (async () => {
                let error;
                try {
                    setFetching(true);
                    if (typeof props?.onAsset === "function")
                        await props?.onAsset();
                }
                catch (e) {
                    setValidate({
                        state: true,
                        message: error || "This token cannot used to be listing.",
                    });
                }
                finally {
                    setFetching(false);
                }
            })();
    }, [asset?.address]);
    const [handleAmountPad, closeAmountPad, resetAmountPad] = usePortal(({ title, asset, onChange }) => (<></>
    // <Vault.BottomSheets.OrderPad
    //     placeholder={"0"}
    //     label={title}
    //     value={asset?.amount}
    //     unit={asset?.symbol}
    //     max={asset?.balance?.amount}
    //     button={{
    //         children: "OK",
    //         onClick: () => closeAmountPad(),
    //     }}
    //     onChange={(e: any, v: any) => typeof onChange === "function" && onChange(e, v)}
    //     onClose={() => closeAmountPad()}
    //     zIndex={200}
    // />
    ));
    return (<Modals.Process width={process === null && !loading && asset?.validate && pair?.length > 0
            ? windowWidth > Root.Device.Tablet
                ? 96
                : 64
            : 64} title={"Listing"} process={process} content={<Layouts.Col gap={2} fill>
                    <Elements.Text height={2} opacity={0.6} align={"center"}>
                        {asset?.validate ? "Please input amount to be list" : "Please enter the token address to be list."}
                    </Elements.Text>
                    <Layouts.Contents.InnerContent scroll>
                        <Layouts.Row responsive={"tablet"} fix>
                            <Layouts.Col gap={2} style={{
                ...(asset?.validate &&
                    pair?.length > 0 &&
                    windowWidth <= Root.Device.Tablet && { flex: "initial" }),
            }}>
                                <Layouts.Col gap={1}>
                                    <Elements.Text type={"desc"} align={"left"}>
                                        Token Address
                                    </Elements.Text>
                                    <Controls.Input placeholder={"0xA1z2b3Y4C5x6d7E8..."} onChange={(e, v) => handleTokenValidate(v)} value={asset?.address} error={validate?.state} message={{
                color: "red",
                children: validate?.message,
            }} left={fetching || asset?.validate
                ? {
                    children: (<Elements.Icon icon={asset?.validate
                            ? "check-bold"
                            : validate?.state
                                ? "x"
                                : "loading"} color={asset?.validate && "green"} style={{
                            ...(!asset?.validate &&
                                !validate?.state && { opacity: 0.45 }),
                        }}/>),
                }
                : {
                    style: { maxWidth: 0, opacity: 0 },
                }} right={asset?.address &&
                asset?.address?.length > 0 && {
                style: { pointerEvents: "initial" },
                children: (<Controls.Button icon={"x"} onClick={() => {
                        setAsset({});
                        setPair([]);
                    }}/>),
            }} autoFocus lock={fetching || asset?.validate}/>
                                </Layouts.Col>
                                {asset?.validate && asset?.balance?.amount > 0 && (<>
                                        <Layouts.Col gap={1}>
                                            <Layouts.Row gap={1} fix>
                                                <Elements.Text type={"desc"} fit>
                                                    Balance:{" "}
                                                </Elements.Text>
                                                <Elements.Text type={"desc"} align={"right"} opacity={1} fix>
                                                    {format(asset?.balance?.amount || 0, "currency", {
                    unit: 9,
                    limit: 12,
                })}
                                                </Elements.Text>
                                            </Layouts.Row>
                                            <Controls.Input type={"currency"} align={"right"} placeholder={"0"} value={asset?.amount} max={asset?.balance?.amount} onChange={(e, v) => setAsset((state) => ({ ...state, amount: v }))} 
            // onFocus={() => isMobile &&
            //     handleAmountPad({
            //         asset,
            //         title: 'Quantity',
            //         onChange: (e: any, v: any) => setAsset((state: any) => ({ ...state, amount: v }))
            //     })
            // }
            // inputMode={isMobile ? 'none' : undefined}
            left={{
                    children: <span>Quantity</span>,
                }} right={{
                    width: 10,
                    children: (<Elements.Text style={{ justifyContent: "flex-start" }}>
                                                            {asset?.symbol || "???"}
                                                        </Elements.Text>),
                }} autoFocus/>
                                            {asset?.amount && asset?.amount !== "" && (<Layouts.Row gap={1} fix>
                                                    <Elements.Text type={"desc"} fit>
                                                        Value:{" "}
                                                    </Elements.Text>
                                                    <Elements.Text type={"desc"} align={"right"} opacity={1} fix>
                                                        ${" "}
                                                        {format(asset?.value
                        ? parseNumber(asset?.amount) * parseNumber(asset?.value)
                        : currentValue > 0
                            ? currentValue * (pair?.length || 1)
                            : 0, "currency", {
                        unit: 9,
                        limit: 12,
                    })}
                                                    </Elements.Text>
                                                </Layouts.Row>)}
                                        </Layouts.Col>
                                        {pair?.length > 0 && (<>
                                                <Layouts.Divider gap={1}>
                                                    <Elements.Icon icon={"plus-small"} scale={0.75}/>
                                                </Layouts.Divider>
                                                {pair?.map((p, i) => (<Layouts.Col key={p?.address || i} gap={1}>
                                                        <Layouts.Row gap={1} fix>
                                                            <Elements.Text type={"desc"} fit>
                                                                Balance:{" "}
                                                            </Elements.Text>
                                                            <Elements.Text type={"desc"} align={"right"} opacity={1} fix>
                                                                {format(p?.balance?.amount || 0, "currency", {
                            unit: 9,
                            limit: 12,
                        })}
                                                            </Elements.Text>
                                                        </Layouts.Row>
                                                        <Controls.Input type={"currency"} align={"right"} placeholder={"0"} value={p?.amount} max={maxAmount(p?.address)} onChange={(e, v) => {
                            address?.toLowerCase() === p?.address?.toLowerCase() &&
                                handleChangeAmount(p?.address, v);
                        }} onFocus={() => setAddress(p?.address)} left={{
                            style: { paddingLeft: ".5em" },
                            children: <Elements.Avatar size={2.5} img={p?.logo}/>,
                        }} right={{
                            width: 10,
                            children: (<Layouts.Row gap={0} align={"center"} fix>
                                                                        <Elements.Text align={"left"} opacity={0.6} style={{ paddingLeft: ".5em" }} fix>
                                                                            {p?.symbol}
                                                                        </Elements.Text>
                                                                        <Controls.Button icon={"x"} onClick={() => handleRemovePair(p?.address)} fit/>
                                                                    </Layouts.Row>),
                        }} error={p?.error} message={{
                            color: "red",
                            children: p?.message,
                        }} autoFocus/>
                                                        {/* {(p?.amount && p?.amount !== '') && (
                            <Layouts.Row gap={1} fix>
                                <Elements.Text type={'desc'} fit>
                                    Value:{' '}
                                </Elements.Text>
                                <Elements.Text type={'desc'} align={'right'} opacity={1} fix>
                                    $ {format(parseNumber(p?.amount) * parseNumber(p?.value), 'currency', {
                                        unit: 9,
                                        limit: 12,
                                    })}
                                </Elements.Text>
                            </Layouts.Row>
                        )} */}
                                                    </Layouts.Col>))}
                                            </>)}
                                        {keyTokens?.length > 0 && (<>
                                                <Layouts.Divider />
                                                <Controls.Dropdown keyName={"symbol"} imgName={"logo"} option={{ icon: "plus-small-bold", symbol: "Select Key Token to Pair" }} options={keyTokens} onClickItem={(e, v, k) => handleAddPair(v)} theme={theme === "light" ? "dark" : "light"}/>
                                            </>)}
                                    </>)}
                            </Layouts.Col>
                            {asset?.validate && pair?.length > 0 && (<Layouts.Box padding={1} style={{
                    background: "rgba(var(--white),var(--o0045))",
                    height: "0",
                    maxHeight: "max-content",
                    ...(windowWidth > Root.Device.Tablet && { maxWidth: "calc(50% - 4em)" }),
                    ...(asset?.validate &&
                        pair?.length > 0 &&
                        windowWidth <= Root.Device.Tablet && { minHeight: "initial" }),
                }}>
                                    <Layouts.Col gap={1} fill>
                                        <Layouts.Contents.InnerContent>
                                            <Layouts.Col gap={1} fill>
                                                <Elements.Text type={"desc"} fit>
                                                    Pairs
                                                </Elements.Text>
                                                <Layouts.Contents.InnerContent scroll>
                                                    <Layouts.Col gap={1} fill>
                                                        {pair?.map((p, i) => (<Controls.Card key={p?.address || i} padding={1} style={{ background: "rgba(var(--white),var(--o0045))" }}>
                                                                <Layouts.Col gap={1}>
                                                                    <Layouts.Col gap={0.5}>
                                                                        <Layouts.Row gap={1}>
                                                                            <Elements.Text type={"desc"} fit>
                                                                                {asset?.symbol}
                                                                            </Elements.Text>
                                                                            <Elements.Text type={"desc"} align={"right"}>
                                                                                {parseNumber(asset?.amount || 0) / pair?.length}
                                                                            </Elements.Text>
                                                                        </Layouts.Row>
                                                                        <div style={{
                        height: "1em",
                        width: `${Math.max(1, ((parseNumber(asset?.amount || 0) /
                            pair?.length) *
                            100) /
                            max)}%`,
                        backgroundColor: `#${HexToColor(asset?.address)}`,
                        transition: ".3s ease",
                    }}/>
                                                                    </Layouts.Col>
                                                                    <Layouts.Col gap={0.5}>
                                                                        <Layouts.Row gap={1}>
                                                                            <Elements.Text type={"desc"} fit>
                                                                                {p?.symbol || "???"}
                                                                            </Elements.Text>
                                                                            <Elements.Text type={"desc"} align={"right"}>
                                                                                {p?.amount || 0}
                                                                            </Elements.Text>
                                                                        </Layouts.Row>
                                                                        <div style={{
                        height: "1em",
                        width: `${Math.max(1, parseNumber(p?.amount || 0) * 100) / max}%`,
                        backgroundColor: `#${HexToColor(p?.address)}`,
                        transition: ".3s ease",
                    }}/>
                                                                    </Layouts.Col>
                                                                </Layouts.Col>
                                                            </Controls.Card>))}
                                                    </Layouts.Col>
                                                </Layouts.Contents.InnerContent>
                                            </Layouts.Col>
                                        </Layouts.Contents.InnerContent>
                                        <Layouts.Divider />
                                        <Layouts.Col gap={1}>
                                            <Elements.Text type={"desc"} align={"left"}>
                                                Estimate earning reward:
                                            </Elements.Text>
                                            <Layouts.Row gap={1} align={"center"} style={{ padding: ".5em" }} fix>
                                                <Elements.Avatar img={props?.standard?.logo} name="MECA" character={1} hideName size={2.5}/>
                                                <Layouts.Row gap={2} fix>
                                                    <Elements.Text align={"right"} fix>
                                                        {estimate ? format(estimate, "currency") : "Cannot Estimate"}
                                                    </Elements.Text>
                                                    <Elements.Text align={"left"} opacity={0.3} fit>
                                                        MECA
                                                    </Elements.Text>
                                                </Layouts.Row>
                                            </Layouts.Row>
                                        </Layouts.Col>
                                    </Layouts.Col>
                                </Layouts.Box>)}
                        </Layouts.Row>
                    </Layouts.Contents.InnerContent>
                    <Layouts.Row gap={windowWidth <= Root.Device.Tablet ? 2 : undefined} fix>
                        <Controls.Button onClick={(e) => handleClose(e)}>Close</Controls.Button>
                        {asset?.validate && pair?.length > 0 && (<Controls.Button onClick={(e) => handleListing(e)}>Listing</Controls.Button>)}
                    </Layouts.Row>
                </Layouts.Col>} failure={{
            message: "Processing has failed.",
            children: <Controls.Button onClick={(e) => handleBack(e)}>Go Back</Controls.Button>,
        }} loading={{
            active: loading,
            message: "Please wait until the processing is complete.",
        }} success={{
            message: "Processing succeeded.",
            children: <Controls.Button onClick={(e) => handleClose(e)}>OK</Controls.Button>,
        }} onClose={(e) => handleClose(e)} close/>);
}
//# sourceMappingURL=Listing.jsx.map