import { Popover } from '@base-ui/react/popover';
import { FC, MouseEvent, useEffect, useRef, useState } from 'react';
import { HabbiconEntry, localizeHabbiconName, localizeWithFallback, useHabbiconCatalog } from '../../../../api';
import { HabbiconFavorite, HabbiconHeaderPattern, HabbiconsLogo } from '../../../../assets/images/habbicons';
import { DraggableWindowPosition, LayoutCurrencyIcon, LayoutHabbiconImageView, OctaneCardHeaderView, OctaneCardView } from '../../../../common';
import { HabbiconProgressBarView } from './HabbiconProgressBarView';
import { HabbiconPurchaseView } from './HabbiconPurchaseView';
import { TabBar, TabBarTab } from '../../../../common/TabBar';
import { BaseButton } from '../../../../common/BaseButton';
import { Hint } from '../../../../common/Tooltip';
import { NativeTextTree } from '../../../../common/native-text/NativeTextTree';

export const HabbiconPrice: FC<{ priceCredits: number; priceActivityPoints: number; activityPointType: number }> = ({
    priceCredits,
    priceActivityPoints,
    activityPointType
}) => (
    <span className="habbicon-price">
        {priceCredits > 0 && (
            <>
                {priceCredits}
                <LayoutCurrencyIcon type={-1} />
            </>
        )}
        {priceCredits > 0 && priceActivityPoints > 0 && ' + '}
        {priceActivityPoints > 0 && (
            <>
                {priceActivityPoints}
                <LayoutCurrencyIcon type={activityPointType} />
            </>
        )}
    </span>
);

export const HabbiconHubView: FC = () => {
    const catalog = useHabbiconCatalog();
    const [tab, setTab] = useState('all_sets');
    const [activeSetId, setActiveSetId] = useState('');
    const [popup, setPopup] = useState<{ id: number; anchor: HTMLElement } | null>(null);
    const bodyRef = useRef<HTMLDivElement>(null);
    const { sets, entries, ownedEntries, ownedSets } = catalog;
    const activeSet = sets.find((set) => set.id === activeSetId) || sets[0];
    const popupEntry = entries.find((entry) => entry.id === popup?.id);
    const completedSets = sets.filter((set) => set.total > 0 && set.completed >= set.total).length;
    const collected = sets.reduce((total, set) => total + set.completed + Number(set.reward?.owned || false), 0);
    const total = sets.reduce((total, set) => total + set.total + Number(!!set.reward), 0);
    const favoriteEntries = ownedEntries.filter((entry) => entry.favorite);

    useEffect(() => {
        if (!catalog.bookVisible) return;

        catalog.clearUnseen();
        catalog.refresh();
    }, [catalog.bookVisible]);

    if (!catalog.enabled || !catalog.bookVisible) return null;

    const showPopup = (event: MouseEvent<HTMLElement>, entry: HabbiconEntry) => {
        const anchor = event.currentTarget;

        setPopup((current) => (current?.id === entry.id ? null : { id: entry.id, anchor }));
        if (!entry.owned && !entry.claimable && !entry.isReward) catalog.getInfo(entry.id);
    };

    const renderTile = (entry: HabbiconEntry) => (
        <Hint key={entry.id} content={localizeHabbiconName(entry)}>
            <BaseButton aria-label={localizeHabbiconName(entry)}
                className={`habbicon-tile air-bitmap-surface ${entry.owned ? 'owned' : 'unowned'} ${entry.claimable ? 'claimable' : ''} ${popup?.id === entry.id ? 'active' : ''}`}
                type="button"
                onClick={(event) => showPopup(event, entry)}
            >
                <LayoutHabbiconImageView id={entry.id} className="habbicon-tile-image" />
                {entry.favorite && <img alt="" className="habbicon-hub-fav" src={HabbiconFavorite} />}
                {entry.claimable && <span className="habbicon-claimable-marker" />}
            </BaseButton>
        </Hint>
    );

    return (
        <NativeTextTree>
            <>
                <svg width="0" height="0" aria-hidden="true" style={{ position: 'absolute' }}>
                    <filter id="habbicon-unowned-filter" colorInterpolationFilters="sRGB">
                        <feColorMatrix type="matrix" values=".35 0 0 0 .35294 0 .35 0 0 .33333 0 0 .35 0 .31373 0 0 0 .65 0" />
                    </filter>
                </svg>
                <OctaneCardView
                    classNames={['habbicon-hub-window']}
                    frameStyle={3}
                    isResizable={false}
                    uniqueKey="habbicon-hub"
                    windowPosition={DraggableWindowPosition.CENTER}
                >
                    <OctaneCardHeaderView
                        headerText={localizeWithFallback('habbicon_book.title', 'Habbicons Collection')}
                        onCloseClick={() => {
                            catalog.setBookVisible(false);
                            setPopup(null);
                        }}
                    />
                    <div className="habbicon-hub-body air-bitmap-surface" ref={bodyRef} onScrollCapture={() => setPopup(null)}>
                        <div className="habbicon-hub-header">
                            <div className="habbicon-hub-header-surface air-bitmap-surface">
                                <div className="habbicon-hub-header-pattern" style={{ backgroundImage: `url(${HabbiconHeaderPattern})` }} />
                                <img alt="" className="habbicon-hub-logo" src={HabbiconsLogo} />
                                <div className="habbicon-hub-header-copy">
                                    <strong>{localizeWithFallback('habbicons.hud.title', 'Habbicons')}</strong>
                                    <span>
                                        {localizeWithFallback('habbicon_book.subtitle', 'Collect sets, unlock animated Habbicons, and use them inside rooms!')}
                                    </span>
                                </div>
                                <div className="habbicon-hub-stat owned air-bitmap-surface">
                                    <span>{localizeWithFallback('habbicons.owned.description', 'Owned habbicons')}</span>
                                    <strong>{ownedEntries.length}</strong>
                                </div>
                                <div className="habbicon-hub-stat completed air-bitmap-surface">
                                    <span>{localizeWithFallback('habbicon_book.sets_completed', 'Sets completed')}</span>
                                    <strong>{completedSets}</strong>
                                </div>
                                <div className="habbicon-hub-progress">
                                    <HabbiconProgressBarView completed={collected} total={total} variant="album" />
                                    <strong>
                                        {collected} / {total}
                                    </strong>
                                </div>
                            </div>
                        </div>

                        <TabBar className="habbicon-hub-tabs" value={tab}>
                            {['all_sets', 'owned', 'favourited'].map((value, index) => (
                                <TabBarTab
                                    className={tab === value ? 'active' : ''}
                                    key={value}
                                    value={value}
                                    onClick={() => {
                                        setTab(value);
                                        setPopup(null);
                                    }}
                                >
                                    {localizeWithFallback(`habbicon_book.tab.${value}`, ['All sets', 'Owned', 'Favourited'][index])}
                                </TabBarTab>
                            ))}
                        </TabBar>

                        {(!catalog.loaded || catalog.assetError) && (
                            <div className="habbicon-hub-empty" role="status">
                                {catalog.assetError
                                    ? localizeWithFallback('habbicons.assets.failed', 'Habicon images could not be loaded.')
                                    : catalog.error || localizeWithFallback('generic.loading', 'Loading…')}
                            </div>
                        )}

                        {!catalog.loaded && catalog.error && (
                            <BaseButton type="button" className="habbicon-action habbicon-hub-retry" onClick={catalog.retry}>
                                {localizeWithFallback('generic.retry', 'Try again')}
                            </BaseButton>
                        )}

                        {catalog.loaded && tab === 'all_sets' && (
                            <div className="habbicon-hub-all-sets">
                                <div className="habbicon-hub-rail air-bitmap-surface">
                                    <div className="habbicon-hub-rail-list has-classic-scrollbar">
                                        {sets.map((set) => (
                                            <BaseButton
                                                className={`air-bitmap-surface ${set.id === activeSet?.id ? 'active' : ''}`}
                                                key={set.id}
                                                type="button"
                                                onClick={() => {
                                                    setActiveSetId(set.id);
                                                    setPopup(null);
                                                }}
                                            >
                                                {set.entries[0] && <LayoutHabbiconImageView id={set.entries[0].id} />}
                                                <div>
                                                    <strong>{set.title}</strong>
                                                    <HabbiconProgressBarView completed={set.completed} total={set.total} variant="rail" />
                                                </div>
                                            </BaseButton>
                                        ))}
                                    </div>
                                </div>
                                {activeSet && (
                                    <div className="habbicon-hub-page">
                                        <div className="habbicon-hub-page-background air-bitmap-surface" />
                                        <div className="habbicon-hub-page-header air-bitmap-surface">
                                            <h3>{activeSet.title}</h3>
                                            <p>{activeSet.description}</p>
                                            <div className="habbicon-hub-set-progress">
                                                <HabbiconProgressBarView key={activeSet.id} completed={activeSet.completed} total={activeSet.total} variant="set" />
                                                <strong>
                                                    {activeSet.completed} / {activeSet.total}
                                                </strong>
                                            </div>
                                        </div>
                                        <div className="habbicon-hub-grid has-classic-scrollbar">
                                            {activeSet.entries.map(renderTile)}
                                            {Array.from({ length: Math.max(0, 20 - activeSet.entries.length) }, (_, index) => (
                                                <div className="habbicon-empty-tile air-bitmap-surface" key={`empty-${index}`} />
                                            ))}
                                        </div>
                                        {activeSet.reward && (
                                            <div className="habbicon-hub-reward air-bitmap-surface">
                                                <strong>{localizeWithFallback('habbicon_book.reward.title', 'Set reward')}</strong>
                                                <div className="habbicon-hub-reward-image air-bitmap-surface">
                                                    <LayoutHabbiconImageView id={activeSet.reward.id} />
                                                </div>
                                                <p>
                                                    {localizeWithFallback(
                                                        `habbicon_book.reward.${activeSet.reward.owned ? 'claimed' : activeSet.reward.claimable ? 'claimable' : 'locked'}`,
                                                        activeSet.reward.owned
                                                            ? 'Reward claimed.'
                                                            : activeSet.reward.claimable
                                                              ? 'Reward ready to claim.'
                                                              : 'Complete this set to unlock the reward.'
                                                    )}
                                                </p>
                                                <BaseButton
                                                    className="habbicon-action"
                                                    type="button"
                                                    disabled={!activeSet.reward.claimable || !!catalog.pending}
                                                    onClick={() => catalog.claim(activeSet.reward.id)}
                                                >
                                                    {localizeWithFallback(
                                                        activeSet.reward.owned ? 'habbicon_reward.claimed' : 'habbicon_reward.claim',
                                                        activeSet.reward.owned ? 'Claimed' : 'Claim'
                                                    )}
                                                </BaseButton>
                                                {activeSet.canBuy && !activeSet.reward.owned && !activeSet.reward.claimable && (
                                                    <div className="habbicon-hub-buy-set">
                                                        <strong>{localizeWithFallback('habbicon_book.buy_set', 'Buy set')}</strong>
                                                        <div className="habbicon-hub-buy-row">
                                                            <HabbiconPrice {...activeSet} />
                                                            <BaseButton
                                                                className="habbicon-action"
                                                                type="button"
                                                                disabled={!!catalog.pending}
                                                                onClick={() => catalog.setPurchase({ id: activeSet.collectionId, collection: true })}
                                                            >
                                                                {localizeWithFallback('generic.buy', 'Buy')}
                                                            </BaseButton>
                                                        </div>
                                                    </div>
                                                )}
                                            </div>
                                        )}
                                    </div>
                                )}
                            </div>
                        )}

                        {catalog.loaded && tab !== 'all_sets' && (
                            <div className="habbicon-hub-tray air-bitmap-surface">
                                <h3>{localizeWithFallback(`habbicon_book.tab.${tab}`, tab === 'owned' ? 'Owned' : 'Favourited')}</h3>
                                <p>{localizeWithFallback('habbicon_book.tray.summary', 'Habicons you own, grouped by set.')}</p>
                                <div className="habbicon-hub-tray-groups has-classic-scrollbar">
                                    {(tab === 'owned'
                                        ? ownedSets
                                        : [{ id: 'favourites', title: localizeWithFallback('habbicons.favourites.title', 'Favourites'), entries: favoriteEntries }]
                                    ).map(
                                        (set) =>
                                            set.entries.length > 0 && (
                                                <section className="air-bitmap-surface" key={set.id}>
                                                    <strong>{set.title}</strong>
                                                    <div className="habbicon-hub-tray-grid">{set.entries.map(renderTile)}</div>
                                                </section>
                                            )
                                    )}
                                    {(tab === 'owned' ? ownedEntries : favoriteEntries).length === 0 && (
                                        <p>{localizeWithFallback('habbicons.no_habbicons', 'No Habicons')}</p>
                                    )}
                                </div>
                            </div>
                        )}

                        {popupEntry && popup && (
                            <Popover.Root
                                open
                                onOpenChange={(open) => {
                                    if (!open) setPopup(null);
                                }}
                            >
                                {/* Mounted inside the hub body so it scrolls and drags with the window. */}
                                <Popover.Portal container={bodyRef}>
                                    <Popover.Positioner
                                        anchor={popup.anchor}
                                        align="center"
                                        className="habbicon-hub-popup-positioner"
                                        collisionPadding={4}
                                        side="top"
                                        sideOffset={8}
                                    >
                                        <Popover.Popup className="habbicon-hub-popup air-bitmap-surface" finalFocus={{ current: popup.anchor }}>
                                            <Popover.Arrow className="habbicon-hub-popup-arrow" />
                                            <strong>{localizeHabbiconName(popupEntry)}</strong>
                                            {popupEntry.owned ? (
                                                <BaseButton
                                                    className={`habbicon-action ${popupEntry.favorite ? 'remove' : ''}`}
                                                    type="button"
                                                    disabled={!!catalog.pending}
                                                    onClick={() => catalog.toggleFavorite(popupEntry.id)}
                                                >
                                                    {localizeWithFallback(
                                                        popupEntry.favorite ? 'habbicon.favourite.remove' : 'habbicon.favourite.add',
                                                        popupEntry.favorite ? 'Remove from favourites' : 'Add to favourites'
                                                    )}
                                                </BaseButton>
                                            ) : popupEntry.claimable ? (
                                                <BaseButton
                                                    className="habbicon-action"
                                                    type="button"
                                                    disabled={!!catalog.pending}
                                                    onClick={() => catalog.claim(popupEntry.id)}
                                                >
                                                    {localizeWithFallback('habbicon_reward.claim', 'Claim')}
                                                </BaseButton>
                                            ) : (
                                                <>
                                                    <p>
                                                        {localizeWithFallback(
                                                            popupEntry.isReward ? 'habbicon.popup.desc.locked' : 'habbicon.popup.desc.not_owned',
                                                            popupEntry.isReward ? 'Locked' : 'Not owned'
                                                        )}
                                                    </p>
                                                    {popupEntry.purchasable && (
                                                        <div className="habbicon-popup-purchase">
                                                            <HabbiconPrice {...popupEntry} />
                                                            <BaseButton
                                                                className="habbicon-action"
                                                                type="button"
                                                                disabled={!!catalog.pending}
                                                                onClick={() => catalog.setPurchase({ id: popupEntry.id, collection: false })}
                                                            >
                                                                {localizeWithFallback('generic.buy', 'Buy')}
                                                            </BaseButton>
                                                        </div>
                                                    )}
                                                </>
                                            )}
                                        </Popover.Popup>
                                    </Popover.Positioner>
                                </Popover.Portal>
                            </Popover.Root>
                        )}
                        {catalog.error && !catalog.purchase && (
                            <div className="habbicon-error" role="alert">
                                {catalog.error}
                            </div>
                        )}
                    </div>
                </OctaneCardView>
                {catalog.purchase && <HabbiconPurchaseView />}
            </>
        </NativeTextTree>
    );
};
