import { Badge, Box, Group, Stack, Text, Tooltip } from "@mantine/core";
import { IconLayoutGrid, IconLink, IconWorld } from "@tabler/icons-react";
import moment from "moment";
import { useState } from "react";
import { Link } from "react-router";
import { dashboardCoverUrl } from "@/lib/features/dashboard/action";
import type { DashboardListItem } from "@/lib/features/dashboard/types";
import { coverArtFor } from "./coverGradient";
import classes from "./dashboard.module.css";

type Props = {
  dashboard: DashboardListItem;
  /** Controls admin-only affordances (version chip, draft badge). */
  isDashboardAdmin: boolean;
  /** Position in the grid, for the entrance stagger. */
  index: number;
};

const DashboardCard: React.FC<Props> = ({ dashboard, isDashboardAdmin, index }) => {
  const art = coverArtFor(dashboard.slug, dashboard.name);
  const isPublished = dashboard.status === "published";
  // Fall back to the generated gradient when there's no cover, or when the
  // request 404s (which is also what an inaccessible cover returns).
  const [coverFailed, setCoverFailed] = useState(false);
  const showCover = Boolean(dashboard.cover_image_path) && !coverFailed;

  const updated = dashboard.updated_at ? moment(dashboard.updated_at) : null;

  return (
    <Box
      component={Link}
      to={`/admin/dashboard/${dashboard.slug}`}
      className={`${classes.card} ${classes.enter}`}
      // Cap the stagger so a large grid doesn't crawl in for a second and a half.
      style={{ "--stagger": `${Math.min(index, 11) * 45}ms` } as React.CSSProperties}
      aria-label={`Open ${dashboard.name}`}
    >
      <div className={classes.cover}>
        {showCover ? (
          <img
            className={classes.coverArt}
            src={dashboardCoverUrl(dashboard.id)}
            alt=""
            loading="lazy"
            decoding="async"
            onError={() => setCoverFailed(true)}
            style={{ width: "100%", height: "100%", objectFit: "cover" }}
          />
        ) : (
          <div className={classes.coverArt} style={{ background: art.background }} />
        )}
        <div className={classes.coverScrim} />
        {!showCover && (
          <div className={classes.monogram} aria-hidden="true">
            {art.initials}
          </div>
        )}

        <Group
          justify="space-between"
          align="flex-start"
          style={{ position: "absolute", inset: 0, padding: 10, zIndex: 3 }}
          wrap="nowrap"
        >
          {/*
            variant="filled" + autoContrast, not "light": a translucent badge
            disappears against the cover artwork. Opaque fill guarantees the
            label is legible whatever hue the gradient lands on.
          */}
          <Badge size="sm" radius="sm" variant="filled" autoContrast
            color={isPublished ? "teal.7" : "yellow.6"}>
            {isPublished ? "Published" : "Draft"}
          </Badge>

          <Group gap={6} wrap="nowrap">
            {/* Computed by the list endpoint's EXISTS — no extra request. */}
            {isDashboardAdmin && dashboard.has_public_link && (
              <Tooltip label="Has an active public share link" withArrow>
                <Badge size="sm" radius="sm" variant="filled" color="grape.7"
                  leftSection={<IconLink size={11} />}>
                  Shared
                </Badge>
              </Tooltip>
            )}
            {isDashboardAdmin && dashboard.current_version_number !== null && (
              <Tooltip label="Live version" withArrow>
                <Badge size="sm" radius="sm" variant="filled" color="dark.9"
                  leftSection={<IconLayoutGrid size={11} />}>
                  v{dashboard.current_version_number}
                </Badge>
              </Tooltip>
            )}
          </Group>
        </Group>
      </div>

      <div className={classes.cardBody}>
        <Stack gap={6}>
          <Text fw={600} size="sm" lineClamp={1} title={dashboard.name}>
            {dashboard.name}
          </Text>

          <Text size="xs" c="dimmed" className={classes.clamp2}>
            {dashboard.description?.trim() || "No description provided."}
          </Text>

          <Group justify="space-between" gap="xs" mt={4} wrap="nowrap">
            <Text size="xs" c="dimmed">
              {updated ? `Updated ${updated.fromNow()}` : "Not yet updated"}
            </Text>
            {!dashboard.current_version_id && (
              <Tooltip label="No version uploaded yet" withArrow>
                <IconWorld
                  size={13}
                  opacity={0.5}
                  aria-label="No version uploaded yet"
                />
              </Tooltip>
            )}
          </Group>
        </Stack>
      </div>
    </Box>
  );
};

export default DashboardCard;
