import type { EnvelopeEditorStep } from '@documenso/lib/client-only/providers/envelope-editor-provider';
import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider';
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
import { cn } from '@documenso/ui/lib/utils';
import { Button } from '@documenso/ui/primitives/button';
import { Separator } from '@documenso/ui/primitives/separator';
import type { MessageDescriptor } from '@lingui/core';
import { msg } from '@lingui/core/macro';
import { Trans, useLingui } from '@lingui/react/macro';
import { EnvelopeType } from '@prisma/client';
import { motion } from 'framer-motion';
import {
  ArrowLeftIcon,
  CopyPlusIcon,
  DownloadCloudIcon,
  FileOutputIcon,
  LinkIcon,
  type LucideIcon,
  SendIcon,
  SettingsIcon,
  Trash2Icon,
} from 'lucide-react';
import { Link, useNavigate } from 'react-router';

import { EnvelopeDeleteDialog } from '~/components/dialogs/envelope-delete-dialog';
import { EnvelopeDistributeDialog } from '~/components/dialogs/envelope-distribute-dialog';
import { EnvelopeDownloadDialog } from '~/components/dialogs/envelope-download-dialog';
import { EnvelopeDuplicateDialog } from '~/components/dialogs/envelope-duplicate-dialog';
import { EnvelopeRedistributeDialog } from '~/components/dialogs/envelope-redistribute-dialog';
import { EnvelopeSaveAsTemplateDialog } from '~/components/dialogs/envelope-save-as-template-dialog';
import { TemplateDirectLinkDialog } from '~/components/dialogs/template-direct-link-dialog';
import { EnvelopeEditorSettingsDialog } from '~/components/general/envelope-editor/envelope-editor-settings-dialog';

import { EnvelopeEditorPanel } from './envelope-editor-panel';

export type EnvelopeEditorStepData = {
  id: string;
  order?: number;
  title: MessageDescriptor;
  icon: LucideIcon;
  description: MessageDescriptor;
};

export const EnvelopeEditorNavigation = ({
  envelopeEditorSteps,
  currentStepData,
  searchParamsStep,
}: {
  envelopeEditorSteps: EnvelopeEditorStepData[];
  currentStepData: EnvelopeEditorStepData;
  searchParamsStep: EnvelopeEditorStep;
}) => {
  const { t } = useLingui();
  const navigate = useNavigate();
  const { envelope, editorConfig, isDocument, isTemplate, relativePath, navigateToStep, syncEnvelope } =
    useCurrentEnvelopeEditor();
  const {
    general: { minimizeLeftSidebar },
    actions: {
      allowDistributing,
      allowDirectLink,
      allowDuplication,
      allowSaveAsTemplate,
      allowDownloadPDF,
      allowDeletion,
    },
  } = editorConfig;

  return (
    <EnvelopeEditorPanel
      title={isDocument ? <Trans>Document Editor</Trans> : <Trans>Template Editor</Trans>}
      compact={minimizeLeftSidebar}
      side="left"
      testId="envelope-editor-navigation"
    >
      <div className="flex min-h-full flex-col py-4">
        {/* Left section step selector. */}
        {minimizeLeftSidebar ? (
          <div className="flex justify-center px-4">
            <div className="relative flex h-10 w-10 items-center justify-center">
              <svg className="size-10 -rotate-90" viewBox="0 0 40 40" aria-hidden>
                {/* Track circle */}
                <circle
                  cx="20"
                  cy="20"
                  r="16"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="3"
                  className="text-muted"
                />
                {/* Progress arc */}
                <motion.circle
                  cx="20"
                  cy="20"
                  r="16"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="3"
                  strokeLinecap="round"
                  className="text-primary"
                  strokeDasharray={2 * Math.PI * 16}
                  initial={false}
                  animate={{
                    strokeDashoffset:
                      2 * Math.PI * 16 * (1 - (currentStepData.order ?? 0) / envelopeEditorSteps.length),
                  }}
                  transition={{ type: 'spring', stiffness: 300, damping: 30 }}
                />
              </svg>
              <span className="absolute inset-0 flex items-center justify-center font-semibold text-[10px] text-foreground">
                <Trans context="The step counter">
                  {currentStepData.order}/{envelopeEditorSteps.length}
                </Trans>
              </span>
            </div>
          </div>
        ) : (
          <div className="px-4">
            <h3 className="flex items-end justify-between font-semibold text-foreground text-sm">
              {isDocument ? <Trans>Document Editor</Trans> : <Trans>Template Editor</Trans>}

              <span className="ml-2 rounded border bg-muted/50 px-2 py-0.5 text-muted-foreground text-xs">
                <Trans context="The step counter">
                  Step {currentStepData.order}/{envelopeEditorSteps.length}
                </Trans>
              </span>
            </h3>

            <div className="relative my-4 h-[4px] rounded-md bg-muted">
              <motion.div
                layout="size"
                layoutId="document-flow-container-step"
                className="absolute inset-y-0 left-0 bg-primary"
                style={{
                  width: `${(100 / envelopeEditorSteps.length) * (currentStepData.order ?? 0)}%`,
                }}
              />
            </div>
          </div>
        )}

        <div
          className={cn('space-y-3', {
            'px-4': !minimizeLeftSidebar,
            'mt-4 flex flex-col items-center': minimizeLeftSidebar,
          })}
        >
          {envelopeEditorSteps.map((step) => {
            const Icon = step.icon;
            const isActive = searchParamsStep === step.id;

            return (
              <button
                key={step.id}
                data-testid={`envelope-editor-step-${step.id}`}
                type="button"
                aria-label={t(step.title)}
                className={cn(
                  `cursor-pointer rounded-lg text-left transition-colors ${
                    isActive
                      ? 'border border-primary/40 bg-accent'
                      : 'border border-gray-200 hover:bg-gray-50 dark:border-gray-400/20 dark:hover:bg-gray-400/10'
                  }`,
                  {
                    'p-3': !minimizeLeftSidebar,
                  },
                )}
                onClick={() => void navigateToStep(step.id as EnvelopeEditorStep)}
              >
                <div className="flex items-center space-x-3">
                  <div
                    className={`rounded border p-2 ${
                      isActive
                        ? 'border-primary/40 bg-accent'
                        : 'border-gray-100 bg-gray-100 dark:border-gray-400/20 dark:bg-gray-400/10'
                    }`}
                  >
                    <Icon className={`h-4 w-4 ${isActive ? 'text-accent-foreground' : 'text-gray-600'}`} />
                  </div>

                  {!minimizeLeftSidebar && (
                    <div>
                      <div
                        className={`font-medium text-sm ${
                          isActive ? 'text-accent-foreground' : 'text-foreground dark:text-muted-foreground'
                        }`}
                      >
                        {t(step.title)}
                      </div>
                      <div className="text-muted-foreground text-xs">{t(step.description)}</div>
                    </div>
                  )}
                </div>
              </button>
            );
          })}
        </div>

        <Separator
          className={cn('my-6', {
            'mx-auto mb-4 w-4/5': minimizeLeftSidebar,
          })}
        />

        {/* Quick Actions. */}
        <div
          className={cn('space-y-3 px-4 [&_.lucide]:text-muted-foreground', {
            'px-2': minimizeLeftSidebar,
          })}
        >
          {!minimizeLeftSidebar && (
            <h4 className="font-semibold text-foreground text-sm">
              <Trans>Quick Actions</Trans>
            </h4>
          )}

          {editorConfig.settings && (
            <EnvelopeEditorSettingsDialog
              trigger={
                <Button variant="ghost" size="sm" className="w-full justify-start" title={t(msg`Settings`)}>
                  <SettingsIcon className="h-4 w-4" />

                  {!minimizeLeftSidebar && (
                    <span className="ml-2">
                      {isDocument ? <Trans>Document Settings</Trans> : <Trans>Template Settings</Trans>}
                    </span>
                  )}
                </Button>
              }
            />
          )}

          {isDocument && allowDistributing && (
            <>
              <EnvelopeDistributeDialog
                documentRootPath={relativePath.documentRootPath}
                trigger={
                  <Button variant="ghost" size="sm" className="w-full justify-start" title={t(msg`Send Envelope`)}>
                    <SendIcon className="h-4 w-4" />

                    {!minimizeLeftSidebar && (
                      <span className="ml-2">
                        <Trans>Send Document</Trans>
                      </span>
                    )}
                  </Button>
                }
              />

              <EnvelopeRedistributeDialog
                envelope={envelope}
                trigger={
                  <Button variant="ghost" size="sm" className="w-full justify-start" title={t(msg`Resend Envelope`)}>
                    <SendIcon className="h-4 w-4" />

                    {!minimizeLeftSidebar && (
                      <span className="ml-2">
                        <Trans>Resend Document</Trans>
                      </span>
                    )}
                  </Button>
                }
              />
            </>
          )}

          {isTemplate && allowDirectLink && (
            <TemplateDirectLinkDialog
              templateId={mapSecondaryIdToTemplateId(envelope.secondaryId)}
              directLink={envelope.directLink}
              recipients={envelope.recipients}
              onCreateSuccess={async () => await syncEnvelope()}
              onDeleteSuccess={async () => await syncEnvelope()}
              trigger={
                <Button variant="ghost" size="sm" className="w-full justify-start" title={t(msg`Direct Link`)}>
                  <LinkIcon className="h-4 w-4" />

                  {!minimizeLeftSidebar && (
                    <span className="ml-2">
                      <Trans>Direct Link</Trans>
                    </span>
                  )}
                </Button>
              }
            />
          )}

          {allowDuplication && (
            <EnvelopeDuplicateDialog
              envelopeId={envelope.id}
              envelopeType={envelope.type}
              trigger={
                <Button variant="ghost" size="sm" className="w-full justify-start" title={t(msg`Duplicate Envelope`)}>
                  <CopyPlusIcon className="h-4 w-4" />

                  {!minimizeLeftSidebar && (
                    <span className="ml-2">
                      {isDocument ? <Trans>Duplicate Document</Trans> : <Trans>Duplicate Template</Trans>}
                    </span>
                  )}
                </Button>
              }
            />
          )}

          {allowSaveAsTemplate && isDocument && (
            <EnvelopeSaveAsTemplateDialog
              envelopeId={envelope.id}
              trigger={
                <Button variant="ghost" size="sm" className="w-full justify-start" title={t(msg`Save as Template`)}>
                  <FileOutputIcon className="h-4 w-4" />

                  {!minimizeLeftSidebar && (
                    <span className="ml-2">
                      <Trans>Save as Template</Trans>
                    </span>
                  )}
                </Button>
              }
            />
          )}

          {allowDownloadPDF && (
            <EnvelopeDownloadDialog
              envelopeId={envelope.id}
              envelopeStatus={envelope.status}
              isLegacy={envelope.internalVersion === 1}
              envelopeItems={envelope.envelopeItems}
              trigger={
                <Button variant="ghost" size="sm" className="w-full justify-start" title={t(msg`Download PDF`)}>
                  <DownloadCloudIcon className="h-4 w-4" />

                  {!minimizeLeftSidebar && (
                    <span className="ml-2">
                      <Trans>Download PDF</Trans>
                    </span>
                  )}
                </Button>
              }
            />
          )}

          {/* Check envelope ID since it can be in embedded create mode. */}
          {allowDeletion && envelope.id && (
            <EnvelopeDeleteDialog
              id={envelope.id}
              type={envelope.type}
              status={envelope.status}
              title={envelope.title}
              canManageDocument={true}
              trigger={
                <Button
                  type="button"
                  aria-label={t(msg`Delete Envelope`)}
                  variant="ghost"
                  size="sm"
                  className="w-full justify-start"
                  title={t(msg`Delete Envelope`)}
                >
                  <Trash2Icon className="h-4 w-4" />

                  {!minimizeLeftSidebar && (
                    <span className="ml-2">
                      {isDocument ? <Trans>Delete Document</Trans> : <Trans>Delete Template</Trans>}
                    </span>
                  )}
                </Button>
              }
              onDelete={async () => {
                await navigate(
                  envelope.type === EnvelopeType.DOCUMENT
                    ? relativePath.documentRootPath
                    : relativePath.templateRootPath,
                );
              }}
            />
          )}
        </div>

        {/* Footer of left sidebar. */}
        {!editorConfig.embedded && (
          <div
            className={cn('mt-auto px-4', {
              'px-2': minimizeLeftSidebar,
            })}
          >
            <Button
              variant="ghost"
              className={cn('w-full justify-start', {
                'flex items-center justify-center': minimizeLeftSidebar,
              })}
              asChild
            >
              <Link to={relativePath.basePath}>
                <ArrowLeftIcon className="h-4 w-4 flex-shrink-0" />

                {!minimizeLeftSidebar && (
                  <span className="ml-2">
                    {isDocument ? <Trans>Return to documents</Trans> : <Trans>Return to templates</Trans>}
                  </span>
                )}
              </Link>
            </Button>
          </div>
        )}
      </div>
    </EnvelopeEditorPanel>
  );
};
