import { Box, Text, Progress, Image, Popover, Title, Stack } from "@mantine/core";
import { usePlayerBadges, useAllBadges } from "../queries";
import { useAuth } from "@/contexts/auth-context";
import { Badge, BadgeProgress } from "../types";
import { useMemo, useState } from "react";
import { MedalIcon, LockKeyIcon } from "@phosphor-icons/react";
import { Trans } from "@lingui/react/macro";

interface BadgeShowcaseProps {
  playerId: string;
}

interface BadgeDisplay {
  badge: Badge;
  progress?: BadgeProgress;
  earned: boolean;
  progressText: string;
}

interface BadgeIconProps {
  badge: Badge;
  filled: boolean;
}

export const BadgeIcon = ({ badge, filled, size = 48 }: BadgeIconProps & { size?: number }) => {
  const [imageError, setImageError] = useState(false);
  const imagePath = `/static/img/${badge.key}.png`;

  if (imageError) {
    return filled ? (
      <MedalIcon
        size={size}
        weight="fill"
        color="var(--mantine-primary-color-6)"
      />
    ) : (
      <LockKeyIcon
        size={size - 4}
        weight="regular"
        color="var(--mantine-color-dimmed)"
      />
    );
  }

  return (
    <Image
      src={imagePath}
      alt={badge.name}
      width={size}
      height={size}
      loading="lazy"
      onError={() => setImageError(true)}
      style={{
        objectFit: 'contain',
        opacity: filled ? 1 : 0.4,
      }}
    />
  );
};


const badgeTileCss = `
.flxn-badge-tile {
  transition: transform 160ms cubic-bezier(0.32, 0.72, 0, 1);
}
@media (hover: hover) {
  .flxn-badge-tile:hover {
    transform: translateY(-2px);
  }
}
.flxn-badge-tile:active {
  transform: scale(0.97);
}
@media (prefers-reduced-motion: reduce) {
  .flxn-badge-tile,
  .flxn-badge-tile:hover,
  .flxn-badge-tile:active {
    transition: none;
    transform: none;
  }
}
`;

const BadgeShowcase = ({ playerId }: BadgeShowcaseProps) => {
  const { user } = useAuth();
  const { data: badgeProgress } = usePlayerBadges(playerId);
  const { data: allBadges } = useAllBadges();

  const isCurrentUser = user?.id === playerId;

  const badgesToDisplay = useMemo(() => {
    const displays: BadgeDisplay[] = [];

    if (isCurrentUser) {
      for (const badge of allBadges) {
        const progress = badgeProgress.find(bp => bp.badge.id === badge.id);
        const earned = progress?.earned || false;

        if (badge.type === 'manual' && !earned) {
          continue;
        }

        const isVeteranBadge = /^veteran_\d+_badge$/.test(badge.key);
        if (isVeteranBadge && !earned) {
          continue;
        }

        if (badge.key === 'new_player_badge') {
          continue;
        }

        let progressText = "";
        if (progress) {
          const target = getTargetProgress(badge);
          progressText = `${progress.progress} / ${target}`;
        } else {
          const target = getTargetProgress(badge);
          progressText = `0 / ${target}`;
        }

        displays.push({
          badge,
          progress,
          earned,
          progressText,
        });
      }

      displays.sort((a, b) => {
        if (a.earned && !b.earned) return -1;
        if (!a.earned && b.earned) return 1;
        return a.badge.order - b.badge.order;
      });
    } else {
      const earnedProgress = badgeProgress.filter(bp => bp.earned);
      for (const progress of earnedProgress) {
        const badge: Badge = {
          ...progress.badge,
          criteria: {},
          created: progress.created,
          updated: progress.updated,
        };

        const target = getTargetProgress(badge);
        displays.push({
          badge,
          progress,
          earned: true,
          progressText: `${progress.progress} / ${target}`,
        });
      }

      displays.sort((a, b) => a.badge.order - b.badge.order);
    }

    return displays;
  }, [allBadges, badgeProgress, isCurrentUser]);

  if (badgesToDisplay.length === 0) {
    return null;
  }

  return (
    <Box mb="lg">
      <style href="flxn-badge-tile" precedence="medium">
        {badgeTileCss}
      </style>
      <Box
        px="md"
        style={{
          maxHeight: '240px',
          overflowY: 'auto',
          overflowX: 'hidden',
          width: '100%',
        }}
      >
        <Box
          style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fill, minmax(85px, 1fr))',
            gap: 'var(--mantine-spacing-md)',
            paddingBottom: 'var(--mantine-spacing-sm)',
            width: '100%',
          }}
        >
          {badgesToDisplay.map((display) => {
            const isStackableBadge = ['winner_badge', 'silver_medal_badge', 'bronze_medal_badge'].includes(display.badge.key);
            const stackCount = display.earned && isStackableBadge
              ? (display.progress?.progress || 0)
              : 1;
            const showStack = stackCount > 1;

            return (
              <Popover key={display.badge.id} width={280} position="top" withArrow shadow="md" withinPortal>
                <Popover.Target>
                  <Box
                    className="flxn-badge-tile"
                    style={{
                      cursor: "pointer",
                      position: 'relative',
                    }}
                  >
                    {showStack && (
                      <>
                        {[...Array(Math.min(stackCount - 1, 2))].map((_, i) => (
                          <Box
                            key={i}
                            style={{
                              width: '100px',
                              height: '100px',
                              borderRadius: '12px',
                              background: 'light-dark(var(--mantine-color-white), var(--mantine-color-dark-7))',
                              border: '2px solid var(--mantine-primary-color-5)',
                              position: 'absolute',
                              top: `${(i + 1) * 4}px`,
                              left: `${(i + 1) * 4}px`,
                              opacity: 0.3 - (i * 0.1),
                              zIndex: -(i + 1),
                            }}
                          />
                        ))}
                      </>
                    )}

                    <Box
                      style={{
                        width: '100px',
                        height: '100px',
                        borderRadius: '12px',
                        background: 'light-dark(var(--mantine-color-white), var(--mantine-color-dark-7))',
                        border: display.earned
                          ? '2px solid var(--mantine-primary-color-6)'
                          : '2px dashed var(--mantine-primary-color-4)',
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        flexDirection: 'column',
                        gap: '4px',
                        padding: 'var(--mantine-spacing-sm)',
                        position: 'relative',
                        boxShadow: display.earned
                          ? '0 0 0 1px color-mix(in srgb, var(--mantine-primary-color-6) 20%, transparent)'
                          : 'none',
                        opacity: display.earned ? 1 : 0.4,
                        zIndex: 1,
                      }}
                    >
                      <BadgeIcon badge={display.badge} filled={display.earned} />

                      {showStack && (
                        <Box
                          style={{
                            position: 'absolute',
                            top: '4px',
                            right: '4px',
                            color: 'var(--mantine-primary-color-6)',
                            width: '20px',
                            height: '20px',
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                            fontSize: '10px',
                            fontWeight: 700,
                          }}
                        >
                          x{stackCount}
                        </Box>
                      )}

                      <Text
                        size="xs"
                        px={4}
                        fw={display.earned ? 600 : 500}
                        ta="center"
                        c={display.earned ? undefined : 'dimmed'}
                        style={{ lineHeight: 1.1 }}
                      >
                        {display.badge.name}
                      </Text>
                    </Box>
                  </Box>
                </Popover.Target>
                <Popover.Dropdown>
                  <Stack gap={4} align="center">
                    <Box style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                      <BadgeIcon badge={display.badge} filled={display.earned} size={80} />
                    </Box>

                    <Title order={5} ta="center">
                      {display.badge.name}
                    </Title>

                    <Text size="sm" c="dimmed" ta="center">
                      {display.badge.description}
                    </Text>

                    {isCurrentUser && (
                      <Box>
                        <Box mb="xs" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                          <Text size="sm" fw={500} c="dimmed">
                            <Trans>Progress&nbsp;</Trans>
                          </Text>
                          <Text size="sm" fw={600} c="dimmed">
                            {display.progressText}
                          </Text>
                        </Box>
                        <Progress
                          value={(display.progress?.progress || 0) / getTargetProgress(display.badge) * 100}
                          size="sm"
                          radius="sm"
                          color={display.earned ? "green" : undefined}
                        />
                      </Box>
                    )}
                  </Stack>
                </Popover.Dropdown>
              </Popover>
            );
          })}
        </Box>
      </Box>
    </Box>
  );
};

function getTargetProgress(badge: Badge): number {
  const criteria = badge.criteria;
  return (
    criteria.matches_played ||
    criteria.tournament_wins ||
    criteria.tournaments_attended ||
    criteria.overtime_matches ||
    criteria.overtime_wins ||
    criteria.consecutive_wins ||
    1
  );
}

export default BadgeShowcase;
