"use client";

import {
  Badge,
  Box,
  Button,
  Group,
  SegmentedControl,
  Select,
  SimpleGrid,
  Stack,
  Text,
  TextInput,
  ThemeIcon,
  Title,
  Tooltip,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import {
  IconBook,
  IconLayoutGrid,
  IconPlus,
  IconSearch,
  IconSearchOff,
  IconSparkles,
} from "@tabler/icons-react";
import React, { useMemo, useState } from "react";
import { useRevalidator } from "react-router";
import type {
  DashboardListItem,
  DashboardSort,
  DashboardStatusFilter,
} from "@/lib/features/dashboard/types";
import CreateDashboardWizard from "./_components/CreateDashboardWizard";
import DashboardCard from "./_components/DashboardCard";
import DashboardSkeletonCard from "./_components/DashboardSkeletonCard";
import classes from "./_components/dashboard.module.css";

type Props = {
  dashboards: DashboardListItem[];
  /** Holds dashboard create-or-update privilege — presentation gating only. */
  isDashboardAdmin: boolean;
  /** False when the viewer has no dashboard:read at all (fallback landing). */
  canRead: boolean;
  loading?: boolean;
};

const GRID = { base: 1, xs: 2, md: 3, xl: 4 };

const DashboardClientPage: React.FC<Props> = ({
  dashboards,
  isDashboardAdmin,
  canRead,
  loading = false,
}) => {
  const [search, setSearch] = useState("");
  const [status, setStatus] = useState<DashboardStatusFilter>("all");
  const [sort, setSort] = useState<DashboardSort>("recent");
  const [createOpen, createHandlers] = useDisclosure(false);
  const revalidator = useRevalidator();

  const visible = useMemo(() => {
    const term = search.trim().toLowerCase();
    let rows = dashboards.filter((d) => {
      if (status !== "all" && d.status !== status) return false;
      if (!term) return true;
      return (
        d.name.toLowerCase().includes(term) ||
        (d.description ?? "").toLowerCase().includes(term)
      );
    });
    rows = [...rows].sort((a, b) =>
      sort === "name"
        ? a.name.localeCompare(b.name)
        : new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime(),
    );
    return rows;
  }, [dashboards, search, status, sort]);

  const hasAny = dashboards.length > 0;
  const filtersActive = search.trim().length > 0 || status !== "all";

  const emptyState = (
    icon: React.ReactNode,
    title: string,
    body: string,
    action?: React.ReactNode,
  ) => (
    <div className={classes.emptyPanel}>
      <div className={classes.emptyGlow} />
      <Stack align="center" gap="xs" className={classes.emptyInner}>
        <ThemeIcon size={54} radius="xl" variant="light" color="gray">
          {icon}
        </ThemeIcon>
        <Title order={4} mt={4}>
          {title}
        </Title>
        <Text size="sm" c="dimmed" maw={460}>
          {body}
        </Text>
        {action && <Box mt="sm">{action}</Box>}
      </Stack>
    </div>
  );

  /**
   * Static file from public/ — no route, no auth, no API call. Managers hand
   * this to whoever is authoring the bundle.
   */
  const devGuideButton = (
    <Tooltip label="How to build a compliant dashboard bundle (PDF)" withArrow>
      <Button
        component="a"
        href="/docs/dashboard-bundle-guide.pdf"
        target="_blank"
        rel="noopener noreferrer"
        download
        variant="default"
        radius="md"
        size="sm"
        leftSection={<IconBook size={15} />}
      >
        Dev guide
      </Button>
    </Tooltip>
  );

  const createButton = (
    <Button
      leftSection={<IconPlus size={15} />}
      onClick={createHandlers.open}
      radius="md"
    >
      Create Dashboard
    </Button>
  );

  return (
    <Stack gap="lg" py="md">
      {/* ------------------------------------------------------------- hero */}
      <div className={classes.hero}>
        <Stack gap="md" className={classes.heroInner}>
          <Group justify="space-between" align="flex-start" wrap="wrap" gap="md">
            <Stack gap={4}>
              <Group gap="xs">
                <Title order={2}>Dashboards</Title>
                {hasAny && (
                  <Badge variant="light" color="gray" radius="sm" size="sm">
                    {dashboards.length}
                  </Badge>
                )}
              </Group>
              <Text size="sm" c="dimmed" maw={560}>
                {isDashboardAdmin
                  ? "Upload, publish and share self-contained static dashboards."
                  : "Dashboards that have been shared with you."}
              </Text>
            </Stack>

            {/* Visible only to dashboard admins; the server enforces regardless. */}
            {isDashboardAdmin && (
              <Group gap="xs">
                {devGuideButton}
                {createButton}
              </Group>
            )}
          </Group>

          {hasAny && (
            <Group gap="sm" wrap="wrap">
              <TextInput
                placeholder="Search dashboards…"
                leftSection={<IconSearch size={14} />}
                value={search}
                onChange={(e) => setSearch(e.currentTarget.value)}
                radius="md"
                w={{ base: "100%", sm: 260 }}
                aria-label="Search dashboards"
              />

              {/* Draft/published split only means something to a manager. */}
              {isDashboardAdmin && (
                <SegmentedControl
                  size="xs"
                  radius="md"
                  value={status}
                  onChange={(v) => setStatus(v as DashboardStatusFilter)}
                  data={[
                    { label: "All", value: "all" },
                    { label: "Published", value: "published" },
                    { label: "Drafts", value: "draft" },
                  ]}
                />
              )}

              <Select
                size="xs"
                radius="md"
                w={165}
                value={sort}
                onChange={(v) => setSort((v as DashboardSort) ?? "recent")}
                allowDeselect={false}
                data={[
                  { label: "Recently updated", value: "recent" },
                  { label: "Name (A–Z)", value: "name" },
                ]}
                aria-label="Sort dashboards"
              />
            </Group>
          )}
        </Stack>
      </div>

      {/* ------------------------------------------------------------- grid */}
      {loading ? (
        <SimpleGrid cols={GRID} spacing="lg">
          {Array.from({ length: 8 }, (_, i) => (
            <DashboardSkeletonCard key={i} index={i} />
          ))}
        </SimpleGrid>
      ) : !hasAny ? (
        isDashboardAdmin ? (
          emptyState(
            <IconSparkles size={26} />,
            "Create your first dashboard",
            "Upload a self-contained static bundle — HTML, CSS and JS — and it will be hosted here, versioned, and shareable with the people you choose.",
            createButton,
          )
        ) : (
          /*
           * The important one: /admin/dashboard is the fallback landing route
           * for users with no other module access, so arriving here with zero
           * grants is normal — it is NOT an error and NOT a 403.
           */
          emptyState(
            <IconLayoutGrid size={26} />,
            "No dashboards shared with you yet",
            canRead
              ? "When someone shares a dashboard with you, it will appear here. Nothing to see for now."
              : "You don't have any dashboards yet. Once a dashboard is shared with you, it will show up on this page.",
          )
        )
      ) : visible.length === 0 ? (
        emptyState(
          <IconSearchOff size={26} />,
          "No matches",
          "No dashboards match your search and filters. Try a different term or clear the filters.",
          filtersActive ? (
            <Button
              variant="default"
              radius="md"
              onClick={() => {
                setSearch("");
                setStatus("all");
              }}
            >
              Clear filters
            </Button>
          ) : undefined,
        )
      ) : (
        <SimpleGrid cols={GRID} spacing="lg">
          {visible.map((d, i) => (
            <DashboardCard
              key={d.id}
              dashboard={d}
              isDashboardAdmin={isDashboardAdmin}
              index={i}
            />
          ))}
        </SimpleGrid>
      )}

      <CreateDashboardWizard
        opened={createOpen}
        onClose={createHandlers.close}
        onCreated={() => revalidator.revalidate()}
      />

    </Stack>
  );
};

export default DashboardClientPage;
