import { useState, useMemo, memo } from "react";
import { Trans, Plural, useLingui } from "@lingui/react/macro";
import {
  Text,
  TextInput,
  Stack,
  Group,
  Box,
  Container,
  Divider,
  UnstyledButton,
  Select,
  Pagination,
  Code,
  Alert,
  ThemeIcon,
  Title,
} from "@mantine/core";
import {
  MagnifyingGlassIcon,
  CaretUpIcon,
  CaretDownIcon,
  CheckIcon,
  XIcon,
  ChecksIcon,
  PulseIcon,
} from "@phosphor-icons/react";
import { Activity, ActivitySearchParams } from "../types";
import { useActivities } from "../queries";
import Sheet from "@/components/sheet/sheet";
import { useSheet } from "@/hooks/use-sheet";

interface ActivityListItemProps {
  activity: Activity;
  onClick: () => void;
}

const ActivityListItem = memo(({ activity, onClick }: ActivityListItemProps) => {
  const { t, i18n } = useLingui();
  const playerName = typeof activity.player === "object" && activity.player
    ? `${activity.player.first_name} ${activity.player.last_name}`
    : t`System`;

  const formatDate = (dateStr: string) => {
    const date = new Date(dateStr);
    return date.toLocaleString(i18n.locale);
  };

  return (
    <UnstyledButton
      w="100%"
      p="md"
      onClick={onClick}
      style={{
        borderRadius: 0,
        transition: "background-color 0.15s ease",
      }}
      styles={{
        root: {
          '&:hover': {
            backgroundColor: 'var(--mantine-color-gray-0)',
          },
        },
      }}
    >
      <Group justify="space-between" align="flex-start" w="100%">
        <Stack gap={4} flex={1}>
          <Group gap="xs">
            <Text size="sm" fw={600}>
              {activity.name}
            </Text>
            {activity.success ? (
              <CheckIcon size={16} color="var(--mantine-color-green-6)" />
            ) : (
              <XIcon size={16} color="var(--mantine-color-red-6)" />
            )}
          </Group>
          <Group gap="md">
            <Text size="xs" c="dimmed">
              {playerName}
            </Text>
            <Text size="xs" c="dimmed">
              <Trans>{activity.duration}ms</Trans>
            </Text>
            <Text size="xs" c="dimmed">
              {formatDate(activity.created)}
            </Text>
          </Group>
          {activity.error && (
            <Text size="xs" c="red" lineClamp={1}>
              {activity.error}
            </Text>
          )}
        </Stack>
      </Group>
    </UnstyledButton>
  );
});

interface ActivityDetailsSheetProps {
  activity: Activity | null;
  isOpen: boolean;
  onClose: () => void;
}

const ActivityDetailsSheet = memo(({ activity, isOpen, onClose }: ActivityDetailsSheetProps) => {
  const { t, i18n } = useLingui();
  if (!activity) return null;

  const playerName = typeof activity.player === "object" && activity.player
    ? `${activity.player.first_name} ${activity.player.last_name}`
    : t`System`;

  const formatDate = (dateStr: string) => {
    const date = new Date(dateStr);
    return date.toLocaleString(i18n.locale);
  };

  return (
    <Sheet title={t`Activity Details`} opened={isOpen} onChange={onClose}>
      <Stack gap="md" p="md">
        <Stack gap="xs">
          <Text size="xs" fw={700} c="dimmed">
            <Trans>Function Name</Trans>
          </Text>
          <Text size="sm">{activity.name}</Text>
        </Stack>

        <Stack gap="xs">
          <Text size="xs" fw={700} c="dimmed">
            <Trans>Status</Trans>
          </Text>
          <Group gap="xs">
            {activity.success ? (
              <>
                <CheckIcon size={16} color="var(--mantine-color-green-6)" />
                <Text size="sm" c="green">
                  <Trans>Success</Trans>
                </Text>
              </>
            ) : (
              <>
                <XIcon size={16} color="var(--mantine-color-red-6)" />
                <Text size="sm" c="red">
                  <Trans>Failed</Trans>
                </Text>
              </>
            )}
          </Group>
        </Stack>

        <Stack gap="xs">
          <Text size="xs" fw={700} c="dimmed">
            <Trans>Player</Trans>
          </Text>
          <Text size="sm">{playerName}</Text>
        </Stack>

        <Stack gap="xs">
          <Text size="xs" fw={700} c="dimmed">
            <Trans>Duration</Trans>
          </Text>
          <Text size="sm"><Trans>{activity.duration}ms</Trans></Text>
        </Stack>

        <Stack gap="xs">
          <Text size="xs" fw={700} c="dimmed">
            <Trans>Created</Trans>
          </Text>
          <Text size="sm">{formatDate(activity.created)}</Text>
        </Stack>

        {activity.user_agent && (
          <Stack gap="xs">
            <Text size="xs" fw={700} c="dimmed">
              <Trans>User Agent</Trans>
            </Text>
            <Text size="xs" style={{ wordBreak: "break-word" }}>
              {activity.user_agent}
            </Text>
          </Stack>
        )}

        {activity.error && (
          <Stack gap="xs">
            <Text size="xs" fw={700} c="dimmed">
              <Trans>Error Message</Trans>
            </Text>
            <Alert color="red" variant="light">
              <Text size="sm" style={{ wordBreak: "break-word" }}>
                {activity.error}
              </Text>
            </Alert>
          </Stack>
        )}

        {activity.arguments && (
          <Stack gap="xs">
            <Text size="xs" fw={700} c="dimmed">
              <Trans>Arguments</Trans>
            </Text>
            <Code block style={{ fontSize: "11px" }}>
              {JSON.stringify(activity.arguments, null, 2)}
            </Code>
          </Stack>
        )}
      </Stack>
    </Sheet>
  );
});

const ActivitiesResults = ({ searchParams, page, setPage, onActivityClick }: any) => {
  const { data: result } = useActivities(searchParams);
  return (
    <>
      <Stack gap={0}>
        {result.items.map((activity: Activity, index: number) => (
          <Box key={activity.id}>
            <ActivityListItem
              activity={activity}
              onClick={() => onActivityClick(activity)}
            />
            {index < result.items.length - 1 && <Divider />}
          </Box>
        ))}
      </Stack>

      {result.items.length === 0 && (
        <Stack align="center" gap="md" py="xl">
          <ThemeIcon size="xl" variant="light" radius="md">
            <PulseIcon size={32} />
          </ThemeIcon>
          <Title order={3} c="dimmed">
            <Trans>No Activities Found</Trans>
          </Title>
        </Stack>
      )}

      {result.totalPages > 1 && (
        <Group justify="center" py="md">
          <Pagination
            total={result.totalPages}
            value={page}
            onChange={setPage}
            size="sm"
          />
        </Group>
      )}
    </>
  );
};

export const ActivitiesTable = () => {
  const { t } = useLingui();
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [successFilter, setSuccessFilter] = useState<string | null>(null);
  const [sortBy, setSortBy] = useState("-created");
  const [selectedActivity, setSelectedActivity] = useState<Activity | null>(null);

  const {
    isOpen: detailsOpened,
    open: openDetails,
    close: closeDetails,
  } = useSheet();

  const searchParams: ActivitySearchParams = useMemo(
    () => ({
      page,
      perPage: 100,
      name: search || undefined,
      success: successFilter === "success" ? true : successFilter === "failure" ? false : undefined,
      sortBy,
    }),
    [page, search, successFilter, sortBy]
  );

  const { data: result } = useActivities(searchParams);

  const handleSort = (field: string) => {
    setSortBy((prev) => {
      if (prev === field) return `-${field}`;
      if (prev === `-${field}`) return field;
      return `-${field}`;
    });
  };

  const getSortIcon = (field: string) => {
    if (sortBy === field) return <CaretUpIcon size={14} />;
    if (sortBy === `-${field}`) return <CaretDownIcon size={14} />;
    return null;
  };

  const handleActivityClick = (activity: Activity) => {
    setSelectedActivity(activity);
    openDetails();
  };

  const handleCloseDetails = () => {
    setSelectedActivity(null);
    closeDetails();
  };

  return (
    <Container size="100%" px={0}>
      <Stack gap="xs">
        <Stack gap="xs" px="md">
          <TextInput
            placeholder={t`serverFn name`}
            value={search}
            onChange={(e) => {
              setSearch(e.currentTarget.value);
              setPage(1);
            }}
            leftSection={<MagnifyingGlassIcon size={16} />}
            size="md"
          />

          <Group>
            <Select
              placeholder={t`Status`}
              value={successFilter}
              onChange={(value) => {
                setSuccessFilter(value);
                setPage(1);
              }}
              data={[
                { value: "all", label: t`All` },
                { value: "success", label: t`Success` },
                { value: "failure", label: t`Failure` },
              ]}
              clearable
              size="sm"
              style={{ flex: 1 }}
            />
          </Group>
        </Stack>

        <Group px="md" justify="space-between" align="center">
          <Text size="10px" lh={0} c="dimmed">
            <Plural value={result.totalItems} one="# total activity" other="# total activities" />
          </Text>
          <Group gap="xs">
            <Text size="xs" c="dimmed">
              <Trans>Sort:</Trans>
            </Text>
            <UnstyledButton
              onClick={() => handleSort("created")}
              style={{ display: "flex", alignItems: "center", gap: 4 }}
            >
              <Text
                size="xs"
                fw={sortBy.includes("created") ? 600 : 400}
                c={sortBy.includes("created") ? "var(--mantine-color-text)" : "dimmed"}
              >
                <Trans>Date</Trans>
              </Text>
              {getSortIcon("created")}
            </UnstyledButton>
            <Text size="xs" c="dimmed">
              •
            </Text>
            <UnstyledButton
              onClick={() => handleSort("duration")}
              style={{ display: "flex", alignItems: "center", gap: 4 }}
            >
              <Text
                size="xs"
                fw={sortBy.includes("duration") ? 600 : 400}
                c={sortBy.includes("duration") ? "var(--mantine-color-text)" : "dimmed"}
              >
                <Trans>Duration</Trans>
              </Text>
              {getSortIcon("duration")}
            </UnstyledButton>
          </Group>
        </Group>

        <ActivitiesResults
          searchParams={searchParams}
          page={page}
          setPage={setPage}
          onActivityClick={handleActivityClick}
        />
      </Stack>

      <ActivityDetailsSheet
        activity={selectedActivity}
        isOpen={detailsOpened}
        onClose={handleCloseDetails}
      />
    </Container>
  );
};
