import { AuditLogEntry, fetchChannelById, fetchReportById, fetchServerById, fetchUserById, fetchUsersById } from "@/lib/db";
import { Card, CardContent, CardDescription, CardHeader } from "../ui/card";
import { UserCard } from "./UserCard";
import { User } from "revolt-api";
import Link from "next/link";
import { Permission } from "@/lib/accessPermissions";
import { ServerCard } from "./ServerCard";
import { ChannelCard } from "./ChannelCard";
import { ReportCard } from "./ReportCard";
import { decodeTime } from "ulid";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";

dayjs.extend(relativeTime);

export async function AuditLogEntryCard({ log }: { log: AuditLogEntry }) {
  const perm = log.permission as Permission;

  const ContextCard = async () => {
    const fallback = log.context ? (
    <Card>
        <CardHeader className="p-3">
          <pre>
            <code>{JSON.stringify(log.context, null, 4)}</code>
          </pre>
        </CardHeader>
      </Card>
    ) : null;

    try {
      // Users
      if (perm.startsWith("users/action")
       || perm.startsWith("users/create")
       || perm == "users/fetch/by-id"
       || perm == "users/fetch/notices"
       || perm == "users/fetch/memberships"
       || perm == "users/fetch/relations"
       || perm == "users/fetch/strikes"
       || perm == "reports/fetch/related/by-user"
       || perm == "reports/fetch/related/against-user"
       || perm == "reports/update/bulk-close/by-user"
      ) {
        let users: User[] = await fetchUsersById(Array.isArray(log.context) ? log.context : [log.context]);
        if (!users.length) return fallback;

        return (
          <>
            {users.map((user: User) => (
              <Link href={`/panel/inspect/user/${log.context}`} key={user._id}>
                <UserCard subtitle={user._id} user={user as User} />
              </Link>
            ))}
          </>
        );
      }

      // Accounts
      if (perm == "accounts/fetch/by-id"
       || perm.startsWith("accounts/deletion")
       || perm == "accounts/disable"
       || perm == "accounts/restore"
       || perm == "accounts/update"
       || perm == "sessions/fetch/by-account-id"
      ) {
        const user = await fetchUserById(log.context);

        if (!user) return fallback;
        return (
          <Link href={`/panel/inspect/account/${log.context}`}>
            <UserCard subtitle={user._id} user={user as User} />
          </Link>
        );
      }

      // Servers
      if (perm == "servers/fetch/by-id"
       || perm.startsWith("servers/update")
       || perm == "channels/fetch/by-server"
      ) {
        const server = await fetchServerById(log.context);

        if (!server) return fallback;
        return (
          <Link href={`/panel/inspect/server/${server._id}`}>
            <ServerCard server={server} subtitle={server._id} />
          </Link>
        )
      }

      // Channels
      if (perm == "channels/fetch/by-id"
       || perm.startsWith("channels/update")
      ) {
        const channel = await fetchChannelById(log.context);

        if (!channel) return fallback;
        return (
          <Link href={`/panel/inspect/channel/${channel._id}`}>
            <ChannelCard channel={channel} subtitle={channel._id} />
          </Link>
        );
      }

      // Reports
      if (perm == "reports/fetch/by-id"
       || perm == "reports/fetch/snapshots/by-report"
       || perm == "reports/update/notes"
       || perm == "reports/update/reject"
       || perm == "reports/update/reopen"
       || perm == "reports/update/resolve") {
        const report = await fetchReportById(log.context);

        if (!report) return fallback;
        return (
          <Link href={`/panel/reports/${report._id}`}>
            <ReportCard report={report} />
          </Link>
        )
      }

      return fallback;
    } catch(e) {
      return fallback;
    }
  }

  return (
    <Card>
      <CardHeader>
        <CardDescription>
          {log.moderator} &middot; {log._id} &middot; {dayjs(decodeTime(log._id)).fromNow()}
        </CardDescription>
        <code className="p-1">{log.permission}</code>

        <ContextCard />

        {log.args != null && (
          <Card>
            <CardHeader className="p-3">
              <pre>
                <code>{JSON.stringify(log.args, null, 2)}</code>
              </pre>
            </CardHeader>
          </Card>
        )}
      </CardHeader>
    </Card>
  );
}
