/**
 * Copyright (c) 2023-present Plane Software, Inc. and contributors
 * SPDX-License-Identifier: AGPL-3.0-only
 * See the LICENSE file for details.
 */

import { observer } from "mobx-react";
import type { ReactNode } from "react";
import { useSearchParams } from "next/navigation";
import useSWR from "swr";
import { ArrowRight, Check, MailCheck, X } from "lucide-react";
import { Button } from "@plane/propel/button";
// components
import { LogoSpinner } from "@/components/common/logo-spinner";
import { NodeDCStandaloneShell } from "@/components/nodedc/standalone-shell";
// constants
import { WORKSPACE_INVITATION } from "@/constants/fetch-keys";
// helpers
import { EPageTypes } from "@/helpers/authentication.helper";
// hooks
import { useUser } from "@/hooks/store/user";
import { useAppRouter } from "@/hooks/use-app-router";
// wrappers
import { AuthenticationWrapper } from "@/lib/wrappers/authentication-wrapper";
import { WorkspaceService } from "@/services/workspace.service";
// services

// service initialization
const workspaceService = new WorkspaceService();

function WorkspaceInvitationPage() {
  // router
  const router = useAppRouter();
  // query params
  const searchParams = useSearchParams();
  const invitation_id = searchParams.get("invitation_id");
  const slug = searchParams.get("slug");
  const token = searchParams.get("token");
  // store hooks
  const { data: currentUser } = useUser();

  const { data: invitationDetail, error } = useSWR(
    invitation_id && slug && WORKSPACE_INVITATION(invitation_id.toString()),
    invitation_id && slug
      ? () => workspaceService.getWorkspaceInvitation(slug.toString(), invitation_id.toString())
      : null
  );

  const handleAccept = async () => {
    if (!invitationDetail) return;
    try {
      await workspaceService.joinWorkspace(invitationDetail.workspace.slug, invitationDetail.id, {
        accepted: true,
        token: token,
      });
      router.push(invitationDetail.email === currentUser?.email ? `/${invitationDetail.workspace.slug}` : "/");
    } catch (err: unknown) {
      console.error(err);
    }
  };

  const handleReject = async () => {
    if (!invitationDetail || !token) return;
    try {
      await workspaceService.joinWorkspace(invitationDetail.workspace.slug, invitationDetail.id, {
        accepted: false,
        token: token,
      });
      router.push("/");
    } catch (err: unknown) {
      console.error(err);
    }
  };

  return (
    <AuthenticationWrapper pageType={EPageTypes.PUBLIC}>
      <NodeDCStandaloneShell showUserControls={!!currentUser}>
        {invitationDetail && !invitationDetail.responded_at ? (
          error ? (
            <InvitationShell
              title="Приглашение не найдено"
              description="Ссылка устарела или была отозвана администратором workspace."
              action={<HomeButton routerPush={() => router.push("/")} />}
            />
          ) : (
            <InvitationShell
              eyebrow="Workspace invite"
              title={`Вас пригласили в ${invitationDetail.workspace.name}`}
              description="Примите приглашение, чтобы получить доступ к workspace и связанным проектам Tasker."
              action={
                <div className="flex flex-wrap justify-center gap-3">
                  <Button
                    variant="primary"
                    size="lg"
                    onClick={handleAccept}
                    className="nodedc-empty-state-primary"
                    prependIcon={<Check className="size-4" />}
                  >
                    Принять
                  </Button>
                  <Button
                    variant="secondary"
                    size="lg"
                    onClick={handleReject}
                    className="nodedc-empty-state-secondary"
                    prependIcon={<X className="size-4" />}
                  >
                    Отклонить
                  </Button>
                </div>
              }
            />
          )
        ) : error || invitationDetail?.responded_at ? (
          invitationDetail?.accepted ? (
            <InvitationShell
              title={`Вы уже участник ${invitationDetail.workspace.name}`}
              description="Приглашение принято. Можно вернуться в Tasker и продолжить работу."
              action={<HomeButton routerPush={() => router.push("/")} />}
            />
          ) : (
            <InvitationShell
              title="Ссылка приглашения больше не активна"
              description={
                currentUser
                  ? "Вернитесь на главную страницу Tasker или запросите новое приглашение."
                  : "Войдите через NODE.DC и запросите новое приглашение, если доступ всё ещё нужен."
              }
              action={<HomeButton routerPush={() => router.push("/")} />}
            />
          )
        ) : (
          <div className="relative z-[1] flex h-full w-full items-center justify-center">
            <LogoSpinner />
          </div>
        )}
      </NodeDCStandaloneShell>
    </AuthenticationWrapper>
  );
}

export default observer(WorkspaceInvitationPage);

function InvitationShell({
  action,
  description,
  eyebrow = "NODE.DC Tasker",
  title,
}: {
  action: ReactNode;
  description: string;
  eyebrow?: string;
  title: string;
}) {
  return (
    <div className="nodedc-glass-surface relative z-[1] w-full max-w-[36rem] overflow-hidden rounded-[2.2rem] px-8 py-9 text-center">
      <div className="pointer-events-none absolute inset-x-8 top-0 h-px bg-gradient-to-r from-transparent via-[rgb(var(--nodedc-accent-rgb))]/55 to-transparent" />
      <div className="mx-auto flex size-24 items-center justify-center rounded-[2rem] bg-white/[0.035] text-[rgb(var(--nodedc-accent-rgb))]">
        <MailCheck className="size-11" />
      </div>
      <div className="mt-6 space-y-2">
        <div className="text-11 font-semibold tracking-[0.18em] text-[rgb(var(--nodedc-accent-rgb))] uppercase">
          {eyebrow}
        </div>
        <h1 className="text-24 font-semibold tracking-[-0.03em]">{title}</h1>
        <p className="mx-auto max-w-sm text-13 leading-6 text-secondary">{description}</p>
      </div>
      <div className="mt-7">{action}</div>
    </div>
  );
}

function HomeButton({ routerPush }: { routerPush: () => void }) {
  return (
    <Button
      variant="primary"
      size="lg"
      onClick={routerPush}
      className="nodedc-empty-state-primary"
      appendIcon={<ArrowRight className="size-4" />}
    >
      Вернуться на главную
    </Button>
  );
}
