"use client";

import { Report } from "revolt-api";
import { Textarea } from "../../ui/textarea";
import { Button } from "../../ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "../../ui/dropdown-menu";
import { useState } from "react";
import { useToast } from "../../ui/use-toast";
import {
  assignReportToCase,
  rejectReport,
  reopenReport,
  resolveReport,
  sendAlert,
  updateReportNotes,
} from "@/lib/actions";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "../../ui/alert-dialog";
import { ReportCard } from "../../cards/ReportCard";
import { Popover } from "@radix-ui/react-popover";
import { PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { CaseDocument, ReportDocument, fetchOpenCases } from "@/lib/db";
import { CaseCard } from "@/components/cards/CaseCard";

const template: Record<string, (ref: string) => string> = {
  resolved: (ref) =>
    `Your report (${ref}) has been actioned and appropriate action has been taken.`,
  invalid: (ref) => `Your report (${ref}) has been marked as invalid.`,
  false: (ref) =>
    `Your report (${ref}) has been marked as false or spam. False reports may lead to additional action against your account.`,
  duplicate: (ref) => `Your report (${ref}) has been marked as a duplicate.`,
  "not enough evidence": (ref) =>
    `Your report (${ref}) has not been actioned at this time due to a lack of supporting evidence, if you have additional information to support your report, please either report individual relevant messages or send an email to contact@revolt.chat.`,
  clarify: (ref) =>
    `Your report (${ref}) needs clarification, please provide additional information.`,
  acknowledged: (ref) =>
    `Your report (${ref}) has been acknowledged, we will be monitoring the situation.`,
  default: (ref) =>
    `Report (${ref})\n\nNo template found for rejection reason, please specify.`,
};

export function ReportActions({
  report,
  reference,
}: {
  report: ReportDocument;
  reference: string;
}) {
  const { toast } = useToast();
  const [reportDraft, setDraft] = useState(report);
  const [availableCases, setAvailableCases] = useState<CaseDocument[]>([]);

  function rejectHandler(reason: string) {
    return async () => {
      try {
        const $set = await rejectReport(report._id, reason);
        setDraft((report) => ({ ...report, ...$set }));
        toast({
          title: "Rejected report",
        });
      } catch (err) {
        toast({
          title: "Failed to reject report",
          description: String(err),
          variant: "destructive",
        });
      }
    };
  }

  return (
    <>
      <ReportCard report={reportDraft} />

      <Textarea
        rows={8}
        placeholder="Enter notes here... (save on unfocus)"
        className="!min-h-0 !h-[76px]"
        defaultValue={report.notes}
        onBlur={async (e) => {
          const notes = e.currentTarget.value;
          if (notes === reportDraft.notes ?? "") return;

          try {
            await updateReportNotes(report._id, notes);
            setDraft((report) => ({ ...report, notes }));
            toast({
              title: "Updated report notes",
            });
          } catch (err) {
            toast({
              title: "Failed to update report notes",
              description: String(err),
              variant: "destructive",
            });
          }
        }}
      />

      {reportDraft.case_id ? (
        <Button
          variant="destructive"
          onClick={async () => {
            try {
              const $set = await assignReportToCase(report._id);
              setDraft((report) => ({ ...report, ...$set }));
              toast({
                title: "Removed report from case",
              });
            } catch (err) {
              toast({
                title: "Failed to resolve report",
                description: String(err),
                variant: "destructive",
              });
            }
          }}
        >
          Remove from case
        </Button>
      ) : (
        <Popover>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              onClick={() => {
                fetchOpenCases().then(setAvailableCases);
              }}
            >
              Add to case
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-80">
            <div className="grid gap-4">
              <div className="space-y-2">
                <h4 className="font-medium leading-none">Open Cases</h4>
                {availableCases.map((entry) => (
                  <a
                    key={entry._id}
                    onClick={async () => {
                      try {
                        const $set = await assignReportToCase(
                          report._id,
                          entry._id
                        );
                        setDraft((report) => ({ ...report, ...$set }));
                        toast({
                          title: "Assigned report to case",
                        });
                      } catch (err) {
                        toast({
                          title: "Failed to resolve report",
                          description: String(err),
                          variant: "destructive",
                        });
                      }
                    }}
                  >
                    <CaseCard entry={entry} />
                  </a>
                ))}
              </div>
            </div>
          </PopoverContent>
        </Popover>
      )}

      <div className="flex gap-2">
        {reportDraft.status === "Created" ? (
          <>
            <Button
              className="flex-1 bg-green-400 hover:bg-green-300"
              onClick={async () => {
                try {
                  const $set = await resolveReport(report._id);
                  setDraft((report) => ({ ...report, ...$set }));
                  toast({
                    title: "Resolved report",
                  });
                } catch (err) {
                  toast({
                    title: "Failed to resolve report",
                    description: String(err),
                    variant: "destructive",
                  });
                }
              }}
            >
              Resolve
            </Button>
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button className="flex-1 bg-red-400 hover:bg-red-300">
                  Reject
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent>
                <DropdownMenuItem
                  onClick={() => {
                    const reason = prompt("Enter a custom reason:");
                    // TODO: modal
                    reason && rejectHandler(reason)();
                  }}
                >
                  Custom Reason
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuLabel>Presets</DropdownMenuLabel>
                <DropdownMenuItem onClick={rejectHandler("invalid")}>
                  Invalid
                </DropdownMenuItem>
                <DropdownMenuItem onClick={rejectHandler("false")}>
                  False or Spam
                </DropdownMenuItem>
                <DropdownMenuItem onClick={rejectHandler("duplicate")}>
                  Duplicate
                </DropdownMenuItem>
                <DropdownMenuItem
                  onClick={rejectHandler("not enough evidence")}
                >
                  Not Enough Evidence
                </DropdownMenuItem>
                <DropdownMenuItem onClick={rejectHandler("clarify")}>
                  Request Clarification
                </DropdownMenuItem>
                <DropdownMenuItem onClick={rejectHandler("acknowledged")}>
                  Acknowledge Only
                </DropdownMenuItem>
                <DropdownMenuItem onClick={rejectHandler("ignore")}>
                  Ignore
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </>
        ) : (
          <>
            <Button
              className="flex-1"
              onClick={async () => {
                try {
                  const $set = await reopenReport(report._id);
                  setDraft((report) => ({ ...report, ...$set }));
                  toast({
                    title: "Opened report again",
                  });
                } catch (err) {
                  toast({
                    title: "Failed to re-open report",
                    description: String(err),
                    variant: "destructive",
                  });
                }
              }}
            >
              Re-open
            </Button>

            <AlertDialog>
              <AlertDialogTrigger asChild>
                <Button className="flex-1">Send resolution notification</Button>
              </AlertDialogTrigger>
              <AlertDialogContent>
                <AlertDialogHeader>
                  <AlertDialogTitle>Send Notification</AlertDialogTitle>
                  <AlertDialogDescription className="flex flex-col gap-2">
                    <span>
                      This will send a message from the Platform Moderation
                      account.
                    </span>
                    <Textarea
                      id="notification-content"
                      defaultValue={(
                        template[
                          reportDraft.status === "Rejected"
                            ? reportDraft.rejection_reason
                            : "resolved"
                        ] ?? template["default"]
                      )(reference)}
                    />
                  </AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                  <AlertDialogCancel>Cancel</AlertDialogCancel>
                  <AlertDialogAction
                    onClick={() => {
                      const msg = (
                        document.getElementById(
                          "notification-content"
                        ) as HTMLTextAreaElement
                      ).value;
                      if (!msg) return;

                      sendAlert(report.author_id, msg)
                        .then(() => toast({ title: "Sent Alert" }))
                        .catch((err) =>
                          toast({
                            title: "Failed to send alert!",
                            description: String(err),
                            variant: "destructive",
                          })
                        );
                    }}
                  >
                    Send
                  </AlertDialogAction>
                </AlertDialogFooter>
              </AlertDialogContent>
            </AlertDialog>
          </>
        )}
      </div>
    </>
  );
}
