import clsx from "clsx";
import {
  ActionFunctionArgs,
  LoaderFunctionArgs,
  redirect,
  useLoaderData,
} from "react-router";
import { createAccountDMsReviewPageURL } from "#lib/urls";
import { fetchApproveDMs, fetchDMsForReview } from "#api/account/dms";
import { PageSkeleton, createAccountPageLoader } from "#components/pages";
import { DMCard } from "#components/cards";
import { FormRouter } from "#components/forms";
import { KemonoLink } from "#components/links";
import { IUnapprovedDM } from "#entities/dms";

import * as styles from "./review_dms.module.scss";

interface IProps {
  status: "pending" | "ignored";
  dms: IUnapprovedDM[];
}

export function DMsReviewPage() {
  const { status, dms } = useLoaderData() as IProps;
  const title = `Approve DMs`;
  const heading = `DM Review`;

  return (
    <PageSkeleton name="review-dms" title={title} heading={heading}>
      <p className={styles.link}>
        <KemonoLink
          url={String(
            createAccountDMsReviewPageURL(
              status === "pending" ? "ignored" : "pending"
            )
          )}
        >
          {status === "pending" ? <>Ignored DMs</> : <>Pending DMs</>}
        </KemonoLink>
      </p>

      {!dms || dms.length === 0 ? (
        <p className="no-dms">There are no DMs waiting for approval.</p>
      ) : (
        <>
          <FormRouter
            id="dm-approval"
            className={clsx("form", "form--wide", "dms")}
            method="POST"
          >
            {dms.map((dm) => (
              <div key={dm.hash} className={clsx("form__section", "dms__dm")}>
                <input
                  id={dm.hash}
                  className="dms__check"
                  type="checkbox"
                  name="approved_hashes"
                  value={dm.hash}
                />
                <div className="dms__content">
                  <DMCard
                    dm={dm}
                    className="dms__card"
                    isPrivate
                    artist={dm.artist}
                  />
                  <label className="dms__approve" htmlFor={dm.hash}>
                    Approve
                  </label>
                </div>
              </div>
            ))}

            {status === "ignored" && (
              <div
                id="consent"
                className="form__section form__section--checkbox"
              >
                <input
                  className="form__input"
                  type="checkbox"
                  id="delete_ignored"
                  name="delete_ignored"
                  value="true"
                />
                <label className="form__label" htmlFor="delete_ignored">
                  Delete ignored DMs
                  <br />
                  <small className="form__subtitle">
                    On next reimport you will have to look at them again and
                    they won't be automatically ignored
                  </small>
                </label>
              </div>
            )}

            <div className="form__section">
              <button
                type="submit"
                className="form__button form__button--submit"
              >
                Submit approved DMs.
              </button>
            </div>
          </FormRouter>
        </>
      )}
    </PageSkeleton>
  );
}

export const loader = createAccountPageLoader(async function loader({
  request,
}: LoaderFunctionArgs): Promise<IProps> {
  const searchParams = new URL(request.url).searchParams;

  let status: undefined | IProps["status"] = undefined;
  {
    const inputStatus = searchParams.get("status")?.trim() ?? "pending";

    if (inputStatus !== "pending" && inputStatus !== "ignored") {
      throw new Error(`Unknown status "${inputStatus}".`);
    }

    status = inputStatus;
  }

  const { dms } = await fetchDMsForReview(status);

  return {
    status,
    dms,
  };
});

export async function action({ request }: ActionFunctionArgs) {
  try {
    if (request.method !== "POST") {
      throw new Error(`Unknown method ${request.method}.`);
    }

    const formData = await request.formData();
    const approvedHashes = formData.getAll("approved_hashes") as string[];
    const deleteIgnored =
      (formData.get("delete_ignored") as string | null)?.trim() === "true";

    if (approvedHashes.length === 0) {
      throw new Error("At least one DM must be provided for approval.");
    }

    await fetchApproveDMs(approvedHashes, deleteIgnored);

    return redirect(String(createAccountDMsReviewPageURL()));
  } catch (error) {
    return error;
  }
}
