import PageHeading from '@/components/common/page-heading';
import LoaderIcon from '@/components/icons/loader-icon';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from '@/components/ui/input-group';
import { Skeleton } from '@/components/ui/skeleton';
import MarketGridCard, {
  MarketGridCardSkeleton,
} from '@/components/user/dashboard/market-grid-card';
import { useInitials } from '@/hooks/use-initials';
import { useApiSWR } from '@/hooks/useSWR';
import fetcher from '@/lib/fetcher';
import { cn } from '@/lib/utils';
import { TMarket, TMarketCategory } from '@/types/market.types';
import { getImageUrl } from '@/utils/getImageUrl';
import {
  BookmarkSimpleIcon,
  MagnifyingGlassIcon,
  SquaresFourIcon,
} from '@phosphor-icons/react';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import useSWRInfinite from 'swr/infinite';

const LIMIT = 12;

const SORTS = [
  { key: '-total_volume', label: 'Trending' },
  { key: '-created_at', label: 'New' },
  { key: 'closes_at', label: 'Ending Soon' },
] as const;

function getInitialCategory(): number | null {
  const param = new URLSearchParams(window.location.search).get('category_id');
  return param ? Number(param) : null;
}

function getInitialWatchlist(): boolean {
  return new URLSearchParams(window.location.search).get('watchlist') === '1';
}

function getInitialSort(): string {
  const param = new URLSearchParams(window.location.search).get('sort');
  return param && SORTS.some((s) => s.key === param) ? param : '-total_volume';
}

const Markets = () => {
  const { t } = useTranslation();
  const getInitials = useInitials();
  const [activeCategoryId, setActiveCategoryId] = useState<number | null>(
    getInitialCategory,
  );
  const [showWatchlist, setShowWatchlist] = useState(getInitialWatchlist);
  const [search, setSearch] = useState('');
  const [sort, setSort] = useState<string>(getInitialSort);

  const { data: categories, isLoading: categoriesLoading } = useApiSWR<
    TMarketCategory[]
  >('/markets/categories');

  const getKey = (pageIndex: number) => {
    let base: string;
    if (showWatchlist) {
      base = '/api/markets?watchlist=1';
    } else if (activeCategoryId) {
      base = `/api/markets?filter[status]=open&filter[category_id]=${activeCategoryId}`;
    } else {
      base = '/api/markets?filter[status]=open';
    }
    return `${base}&sort=${sort}&limit=${LIMIT}&page=${pageIndex + 1}`;
  };

  const {
    data: pages,
    isLoading,
    isValidating,
    size,
    setSize,
  } = useSWRInfinite(getKey, fetcher, { revalidateFirstPage: false });

  useEffect(() => {
    setSize(1);
  }, [activeCategoryId, showWatchlist, sort, setSize]);

  const allMarkets: TMarket[] = pages?.flatMap((p) => p?.data ?? []) ?? [];
  const markets = search
    ? allMarkets.filter((m) =>
        m.title.toLowerCase().includes(search.toLowerCase()),
      )
    : allMarkets;
  const hasMore = (pages?.[pages.length - 1]?.data?.length ?? 0) >= LIMIT;
  const isLoadingMore = isValidating && size > 1;

  const activeCategory = categories?.find((c) => c.id === activeCategoryId);

  return (
    <div className="space-y-5">
      <PageHeading
        title={
          showWatchlist
            ? t('Watchlist')
            : activeCategory
              ? activeCategory.name
              : t('Markets')
        }
        description={
          showWatchlist
            ? t('Markets you are watching.')
            : t('Browse and trade on prediction markets.')
        }
        variant="default"
        actionButton={
          <InputGroup className="max-w-96 border-0 bg-muted">
            <InputGroupAddon>
              <MagnifyingGlassIcon weight="bold" className="size-4" />
            </InputGroupAddon>
            <InputGroupInput
              placeholder={t('Search markets…')}
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
          </InputGroup>
        }
      />

      <div className="flex gap-6">
        <div className="hidden w-[250px] shrink-0 lg:block">
          <div className="sticky top-4">
            <Card className="gap-0 rounded-2xl bg-transparent p-0 dark:border-white/8">
              <div className="space-y-1 p-1.5">
                <button
                  onClick={() => {
                    setActiveCategoryId(null);
                    setShowWatchlist(false);
                  }}
                  className={cn(
                    'flex h-10 w-full cursor-pointer items-center gap-3 rounded-xl px-2 py-2 text-left transition-colors',
                    activeCategoryId === null && !showWatchlist
                      ? 'bg-pm-surface-2 text-card-foreground'
                      : 'text-black/60 hover:bg-black/4 dark:text-white/60 dark:hover:bg-white/5',
                  )}
                >
                  <span className="flex size-8 shrink-0 items-center justify-center">
                    <SquaresFourIcon
                      weight={
                        activeCategoryId === null && !showWatchlist
                          ? 'fill'
                          : 'regular'
                      }
                      className={cn(
                        'size-4',
                        activeCategoryId === null && !showWatchlist
                          ? 'text-primary'
                          : 'text-black/40 dark:text-white/40',
                      )}
                    />
                  </span>
                  <span className="flex-1 truncate text-sm font-medium">
                    {t('All Markets')}
                  </span>
                </button>

                <button
                  onClick={() => {
                    setShowWatchlist(true);
                    setActiveCategoryId(null);
                  }}
                  className={cn(
                    'flex h-10 w-full cursor-pointer items-center gap-3 rounded-xl px-2 py-2 text-left transition-colors',
                    showWatchlist
                      ? 'bg-pm-surface-2 text-card-foreground'
                      : 'text-black/60 hover:bg-black/4 dark:text-white/60 dark:hover:bg-white/5',
                  )}
                >
                  <span className="flex size-8 shrink-0 items-center justify-center">
                    <BookmarkSimpleIcon
                      weight={showWatchlist ? 'fill' : 'regular'}
                      className={cn(
                        'size-4',
                        showWatchlist
                          ? 'text-primary'
                          : 'text-black/40 dark:text-white/40',
                      )}
                    />
                  </span>
                  <span className="flex-1 truncate text-sm font-medium">
                    {t('Watchlist')}
                  </span>
                </button>

                {categoriesLoading
                  ? Array.from({ length: 5 }).map((_, i) => (
                      <div
                        key={i}
                        className="flex items-center gap-3 px-4 py-2"
                      >
                        <Skeleton className="size-4 shrink-0 rounded" />
                        <Skeleton className="h-3.5 flex-1" />
                      </div>
                    ))
                  : (categories ?? []).map((cat) => {
                      const isActive =
                        activeCategoryId === cat.id && !showWatchlist;
                      return (
                        <button
                          key={cat.id}
                          onClick={() => {
                            setActiveCategoryId(cat.id);
                            setShowWatchlist(false);
                          }}
                          className={cn(
                            'flex h-10 w-full cursor-pointer items-center gap-3 rounded-xl px-2 py-2 text-left transition-colors',
                            isActive
                              ? 'bg-pm-surface-2 text-card-foreground'
                              : 'text-black/60 hover:bg-black/4 dark:text-white/60 dark:hover:bg-white/5',
                          )}
                        >
                          <Avatar className="size-8 overflow-hidden rounded-full">
                            <AvatarImage
                              src={getImageUrl(cat.icon ?? undefined)}
                              alt={cat.name}
                            />
                            <AvatarFallback className="text-sm font-semibold">
                              {getInitials(cat.name)}
                            </AvatarFallback>
                          </Avatar>
                          <span className="flex-1 truncate text-sm font-medium">
                            {cat.name}
                          </span>
                          {cat.markets_count != null && (
                            <span className="shrink-0 text-xs text-black/30 dark:text-white/30">
                              {cat.markets_count}
                            </span>
                          )}
                        </button>
                      );
                    })}
              </div>
            </Card>

            {activeCategoryId !== null && (
              <Button
                variant="ghost"
                size="sm"
                className="mt-2 w-full text-black/40 dark:text-white/40"
                onClick={() => setActiveCategoryId(null)}
              >
                {t('Clear filter')}
              </Button>
            )}
          </div>
        </div>

        <div className="min-w-0 flex-1">
          <div className="mb-4 flex items-center gap-1.5">
            {SORTS.map((s) => (
              <button
                key={s.key}
                onClick={() => setSort(s.key)}
                className={cn(
                  'cursor-pointer rounded-full px-3.5 py-1.5 text-sm font-medium transition-colors',
                  sort === s.key
                    ? 'bg-foreground text-background'
                    : 'bg-black/5 text-black/60 hover:bg-black/10 dark:bg-white/5 dark:text-white/60 dark:hover:bg-white/10',
                )}
              >
                {t(s.label)}
              </button>
            ))}
          </div>

          {isLoading ? (
            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
              {Array.from({ length: 9 }).map((_, i) => (
                <MarketGridCardSkeleton key={i} />
              ))}
            </div>
          ) : markets.length === 0 ? (
            <Card className="rounded-2xl border border-dashed border-black/10 py-16 text-center text-sm text-black/40 dark:border-white/10 dark:text-white/40">
              {showWatchlist
                ? t(
                    'Your watchlist is empty. Bookmark markets to see them here.',
                  )
                : t('No markets found.')}
            </Card>
          ) : (
            <>
              <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
                {markets.map((market) => (
                  <MarketGridCard key={market.id} market={market} />
                ))}
              </div>
              {hasMore && (
                <div className="mt-6 flex justify-center">
                  <Button
                    variant="primary"
                    onClick={() => setSize((s) => s + 1)}
                    disabled={isLoadingMore}
                  >
                    {isLoadingMore && <LoaderIcon />}
                    {t('Load More')}
                  </Button>
                </div>
              )}
            </>
          )}
        </div>
      </div>
    </div>
  );
};

Markets.title = 'Markets';

export default Markets;
