import {
    Leaderboard,
    LeaderboardApi,
    LeaderboardCode,
    LeaderboardFrequency,
    LeaderboardRow,
} from "@/api_fsb";
import { useAppSelector } from "@/hooks";
import { bpid, formatCentsToUSD, truncate, } from "@/lib/utils";
import { activeSurveys, activeUsers, maxPayout } from "@/models/grlStatsSlice";
import { clsx } from "clsx";
import moment from 'moment';
import { useEffect, useState } from 'react';

const showSmartRank = (
    item: LeaderboardRow,
    index: number,
    items: LeaderboardRow[] | undefined
): boolean => {
    /**
     * Smart rank calculation - this determines if we should show the rank
     *  value. It's confusing to show people that multiple individuals ranked
     *  in the same place, so this will only display the next ranked value, eg:
     *
     *  - 1st
     *  - ___
     *  - 3rd
     *  - ___
     *  - ___
     *  - 6th
     *
     * @returns number
     */
    if (!items) return false;

    const thisRank = item.rank;
    if (index >= 1) {
        const prevRank = items[index - 1].rank;
        if (thisRank === prevRank) {
            return false;
        }
    }
    return true;
};

interface FrequencyButtonsProps {
    selected: LeaderboardFrequency;
    onChange: (frequency: LeaderboardFrequency) => void;
}

const frequency_map = [
    { label: 'Day', value: LeaderboardFrequency.Daily },
    { label: 'Week', value: LeaderboardFrequency.Weekly },
    { label: 'Month', value: LeaderboardFrequency.Monthly },
];

const ThreeButtonToggle = ({ selected, onChange }: FrequencyButtonsProps) => {
    return (
        <div className="inline-flex rounded shadow-sm" role="group">
            {frequency_map.map((button, idx) => (
                <button
                    type="button"
                    key={button.value}
                    onClick={() => onChange(button.value)}
                    className={clsx(
                        "px-2 py-1 text-[10px] font-medium",
                        "border-t border-b border-gray-200",
                        "hover:cursor-pointer hover:bg-zinc-200 hover:text-zinc-950",
                        idx === 0 && "rounded-l",
                        idx === frequency_map.length - 1 && "rounded-r",
                        selected === button.value
                            ? 'text-zinc-50 bg-zinc-400'
                            : 'text-zinc-950 bg-zinc-50',
                    )}>
                    {button.label}
                </button>
            ))}
        </div>
    );
};



// Leaderboards Component
export const Leaderboards = () => {
    /**
     * Leaderboards do not do any caching, or better state management. This is okay because 
     * the API is handled to take it. However, it can easily handled better client 
     * side rather than making the 
     * **/

    const [frequency, setFrequency] = useState<LeaderboardFrequency>(
        LeaderboardFrequency.Daily
    );

    const [payouts, setPayouts] = useState<Leaderboard | null>(null);
    const [completes, setCompletes] = useState<Leaderboard | null>(null);

    // const bpuid = useAppSelector(state => state.app.bpuid)
    const bpuid = undefined

    useEffect(() => {
        new LeaderboardApi().timespanLeaderboardProductIdLeaderboardTimespanBoardCodeGet(
            bpid,
            LeaderboardCode.CompleteCount,
            frequency,
            "us",
            bpuid,  // bpuid
            undefined,  // within_time
            10)
            .then(res => {
                setCompletes(res.data.leaderboard as Leaderboard)
            })

        new LeaderboardApi().timespanLeaderboardProductIdLeaderboardTimespanBoardCodeGet(
            bpid,
            LeaderboardCode.SumUserPayout,
            frequency,
            "us",
            bpuid,
            undefined,
            10)
            .then(res => {
                setPayouts(res.data.leaderboard as Leaderboard)
            })
    }, [frequency]);

    let dateRange = " - "
    if (completes) {
        const start = moment(completes?.start_timestamp * 1000).format("MMM Do, ha");
        const end = moment(completes?.end_timestamp * 1000).format("MMM Do, h:mm:ssa");
        //dateRange = `${start} – ${end} (${completes?.timezone_name})`;
        dateRange = `${start} – ${end}`;
    }

    const freq_label = frequency_map.find(f => f.value === frequency)?.label.toLocaleLowerCase()

    return (
        <div className="my-2 mx-4 py-0">
            <div className="w-full flex items-center justify-between my-1">
                {/* Left spacer (hidden on small screens) */}
                <div className="hidden md:block md:w-1/3"></div>

                {/* Centered text */}
                <h3 className="text-center flex-1 md:1/3">
                    Leaderboards
                </h3>

                {/* Right-aligned button group */}
                <div className="flex md:w-1/3 justify-end">
                    <ThreeButtonToggle
                        selected={frequency}
                        onChange={setFrequency}
                    />
                </div>
            </div>

            <div className="grid grid-cols-1 mb-2 text-zinc-700">
                <p className="text-center text-[10px] font-thin">
                    {dateRange}
                </p>
            </div>

            <div className="grid grid-cols-1 gap-4 px-12 md:px-0
            md:grid-cols-2">
                <table className="border-collapse text-emerald-950 text-[8px] md:text-sm">
                    <caption className="caption-top text-xs font-semibold">
                        Most earned in the past {freq_label}.
                    </caption>
                    <thead>
                        <tr className="
                            font-mono font-semibold text-center
                            border border-zinc-150">
                            <th>Rank</th>
                            <th>Bonus</th>
                            <th>User</th>
                        </tr>
                    </thead>
                    <tbody className="font-mono">

                        {payouts?.rows?.map((dataItem: LeaderboardRow) => (
                            <tr key={dataItem.bpuid} className="
                            text-center 
                            border border-zinc-100">
                                <td className="font-medium">
                                    {dataItem.rank}
                                </td>
                                <td className="font-semibold">
                                    {formatCentsToUSD(dataItem.value)}
                                </td>
                                <td className="font-light">
                                    {truncate(dataItem.bpuid, 6, "*****").toUpperCase()}
                                </td>
                            </tr>
                        ))}
                    </tbody>
                </table>

                <table className="border-collapse border border-gray-400
                text-emerald-950 text-[8px] md:text-sm">
                    <caption className="caption-top text-xs font-semibold">
                        Top completes in the past {freq_label}.
                    </caption>
                    <thead>
                        <tr className="
                            font-mono font-semibold text-center
                            border border-zinc-150 rounded">
                            <th>Rank</th>
                            <th>Completes</th>
                            <th>User</th>
                        </tr>
                    </thead>
                    <tbody className="font-mono">

                        {completes?.rows?.map((dataItem: LeaderboardRow, index: number) => (
                            <tr key={dataItem.bpuid} className="
                            text-center
                            border border-zinc-100">
                                <td className="font-medium">
                                    {dataItem.rank ?? showSmartRank(dataItem, index, completes?.rows)}
                                </td>
                                <td className="font-semibold">
                                    {dataItem.value}
                                </td>
                                <td className="font-light">
                                    {truncate(dataItem.bpuid, 6, "*****").toUpperCase()}
                                </td>
                            </tr>
                        ))}
                    </tbody>
                </table>
            </div>
        </div>
    );
};



// Preview Component
const Preview = () => {
    /**
     *
     * @returns {JSX.Element}
     */

    const users = useAppSelector(state => activeUsers(state))
    const users_f: string = users?.toLocaleString() ?? " – "

    const surveys = useAppSelector(state => activeSurveys(state))
    const surveys_f: string = surveys?.toLocaleString() ?? " – "

    const survey_max_cpi = useAppSelector(state => maxPayout(state))
    const formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
    });
    const survey_max_cpi_f: string = formatter.format((survey_max_cpi ?? 0) / 100)

    return (
        <div className="max-h-[calc(100vh-10rem)] overflow-y-auto">

            <div className="bg-zinc-100 rounded py-2 m-0">
                <p className="text-center text-sm italic text-zinc-600">
                    {users_f} people are actively attempting {surveys_f} available surveys right now.
                </p>
            </div>

            <Leaderboards />

            <div className="bg-zinc-100 rounded py-2 px-6 m-0 text-xs text-center">
                <p className="py-1">
                    Get paid to take surveys. Our algorithm attempts to pair you with the
                    highest paying survey available at the moment (right now, the highest
                    paying survey is {survey_max_cpi_f}) that you are eligible for,
                    each attempt is a valid HIT. Try as many as you can, our system will
                    self regulate you: we want to ensure you have a high chance of being
                    paired with a survey based on what surveys are available, as their
                    availability constantly changes.</p>
                <p className="py-1">
                    Each HIT is paid when you attempt to take a survey and if you complete
                    the survey, you will be awarded a bonus equal to that in which the
                    survey pays out.</p>
            </div>
        </div>
    );
};
export default Preview;