"use client";

import { fetchAuditLog } from "@/lib/actions";
import { AuditLog, AuditLogAction } from "@/lib/audit";
import GhostMessage from "@/lib/components/ui/GhostMessage";
import LoadingSpinner from "@/lib/components/ui/LoadingSpinner";
import { GRAVATAR_DEFAULT } from "@/lib/constants";
import { sha256sum } from "@/lib/util";
import { Avatar, Card, Code, Flex, Grid, Heading, IconButton, Text } from "@radix-ui/themes";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { ArrowLeftIcon, ArrowRightIcon, AsteriskSquareIcon, GhostIcon, KeyRoundIcon, LogInIcon, UserCheckIcon, UserPlusIcon, UsersIcon, UsersRoundIcon, XIcon } from "lucide-react";
import { useEffect, useState } from "react";

dayjs.extend(relativeTime);

const LOG_ACTION_HUMAN_READABLE: { [key in AuditLogAction]?: string } = {
  requestAlias: "Requested an alias",
  createTempAlias: "Generated a temporary alias",
  createAlias: "Created an alias",
  approveAlias: "Approved an alias",
  deleteAlias: "Deleted an alias",
  login: "Logged in",
  changeOwnPassword: "Changed their own password",
  createUser: "Created a new user",
  createApiKey: "Created an API key",
  deleteApiKey: "Deleted an API key",
};

export default function Audit() {
  const [page, setPage] = useState(0);
  const [perPage, setPerPage] = useState(0);
  const [totalItems, setTotalItems] = useState(0);
  const [data, setData] = useState<(AuditLog & { index: number })[] | null>(null);

  useEffect(() => {
    console.log("Fetching page", page);
    fetchAuditLog(page).then((res) => {
      if (res.page != page) setPage(res.page);
      setData(res.items);
      setPerPage(res.perPage);
      setTotalItems(res.totalItems);
    });
  }, [page]);

  const logActionIcons: { [key in AuditLogAction]?: React.ReactNode } = {
    requestAlias: <UsersIcon />,
    createTempAlias: <UsersRoundIcon />,
    createAlias: <UsersIcon />,
    approveAlias: <UserCheckIcon />,
    deleteAlias: <XIcon />,
    login: <LogInIcon />,
    changeOwnPassword: <AsteriskSquareIcon />,
    createUser: <UserPlusIcon />,
    createApiKey: <KeyRoundIcon />,
    deleteApiKey: <KeyRoundIcon />,
  };

  function NavigationButtons() {
    return (
      <Flex gap="3" justify="end">
        <Card>
          <IconButton variant="ghost" onClick={() => page > 0 && setPage(page - 1)}>
            <ArrowLeftIcon />
          </IconButton>
        </Card>
        <Card><Text className="select-none">
          {
            data
              ? `${perPage * page + 1} - ${perPage * page + data.length} / ${totalItems}`
              : "Loading..."
          }
        </Text></Card>
        <Card>
          <IconButton variant="ghost" onClick={() => setPage(page + 1)}>
            <ArrowRightIcon />
          </IconButton>
        </Card>
      </Flex>
    );
  }

  return (
    <>
      <Flex justify="between" align="center" pb="4">
        <Heading>Audit Log</Heading>
        <NavigationButtons />
      </Flex>

      {
        data
          ? data.length
            ? <Grid gap="4">
              {
                data.map((item) => (
                  <Card key={item.index}>
                    <Flex gap="3" direction="column">
                      <Flex direction='row' gap='4' align='center'>
                        <Avatar
                          size="2"
                          src={`https://gravatar.com/avatar/${sha256sum(item.user)}?d=${GRAVATAR_DEFAULT}`}
                          radius='full'
                          fallback={item.user?.slice(0, 1) || "@"}
                        />
                        <Text size='3'>{item.user}</Text>
                      </Flex>

                      {
                        LOG_ACTION_HUMAN_READABLE[item.action]
                          ? <Flex gap="3" direction="row" ml="2" my="1" className="select-none">
                            {logActionIcons[item.action]}
                            <Text size="4" color="gray">{LOG_ACTION_HUMAN_READABLE[item.action]}</Text>
                          </Flex>
                          : <Text><Code color="gray" size="4">{item.action}</Code></Text>
                      }

                      {item.data && (
                        <Code color="gray" className="whitespace-pre">
                          {JSON.stringify(item.data, null, 4)}
                        </Code>
                      )}

                      <Text size="2" weight="light">{dayjs(item.ts).format('DD/MM/YYYY HH:mm:ss')} &bull; {dayjs(item.ts).fromNow()}</Text>
                    </Flex>
                  </Card>
                ))
              }
              <NavigationButtons />
            </Grid>
            : <Card>
              <GhostMessage icon={<GhostIcon />} header="Nothing here" message="There don't appear to be any log entries" />
            </Card>
          : <Card>
            <GhostMessage icon={<LoadingSpinner />} header="Loading" />
          </Card>
      }
    </>
  );
}