import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider';
import { getEnvelopeItemPermissions, mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
import { Badge } from '@documenso/ui/primitives/badge';
import { Button } from '@documenso/ui/primitives/button';
import { Separator } from '@documenso/ui/primitives/separator';
import { Trans, useLingui } from '@lingui/react/macro';
import { DocumentStatus, EnvelopeType, TemplateType } from '@prisma/client';
import {
  AlertTriangleIcon,
  Building2Icon,
  Globe2Icon,
  LockIcon,
  RefreshCwIcon,
  SendIcon,
  SettingsIcon,
} from 'lucide-react';
import { useMemo } from 'react';
import { Link } from 'react-router';
import { match } from 'ts-pattern';

import { EnvelopeDistributeDialog } from '~/components/dialogs/envelope-distribute-dialog';
import { EnvelopeRedistributeDialog } from '~/components/dialogs/envelope-redistribute-dialog';
import { TemplateUseDialog } from '~/components/dialogs/template-use-dialog';
import { BrandingLogo } from '~/components/general/branding-logo';
import { DocumentAttachmentsPopover } from '~/components/general/document/document-attachments-popover';
import { EmbeddedEditorAttachmentPopover } from '~/components/general/document/embedded-editor-attachment-popover';
import { EnvelopeEditorSettingsDialog } from '~/components/general/envelope-editor/envelope-editor-settings-dialog';

import { TemplateDirectLinkBadge } from '../template/template-direct-link-badge';
import { EnvelopeItemTitleInput } from './envelope-editor-title-input';

export default function EnvelopeEditorHeader() {
  const { t } = useLingui();

  const {
    envelope,
    isDocument,
    isTemplate,
    isEmbedded,
    updateEnvelope,
    autosaveError,
    relativePath,
    editorConfig,
    flushAutosave,
  } = useCurrentEnvelopeEditor();

  const {
    embedded,
    general: { allowConfigureEnvelopeTitle },
    actions: { allowAttachments, allowDistributing },
  } = editorConfig;

  const envelopeItemPermissions = useMemo(
    () => getEnvelopeItemPermissions(envelope, envelope.recipients),
    [envelope, envelope.recipients],
  );

  const handleCreateEmbeddedEnvelope = async () => {
    const latestEnvelope = await flushAutosave();

    embedded?.onCreate?.(latestEnvelope);
  };

  const handleUpdateEmbeddedEnvelope = async () => {
    const latestEnvelope = await flushAutosave();

    embedded?.onUpdate?.(latestEnvelope);
  };

  return (
    <nav className="w-full shrink-0 border-border border-b bg-background px-3 py-2 sm:px-4 sm:py-3 lg:px-6">
      <div className="flex min-w-0 flex-col gap-2 lg:flex-row lg:items-center lg:justify-between lg:gap-4">
        <div className="flex min-w-0 flex-1 items-start gap-2 lg:items-center lg:gap-4">
          {editorConfig.embedded?.customBrandingLogo ? (
            <img
              src={`/api/branding/logo/team/${envelope.teamId}`}
              alt="Logo"
              className="h-6 w-auto max-w-28 shrink-0"
            />
          ) : (
            <Link to="/" className="shrink-0">
              <BrandingLogo className="h-6 w-auto max-w-28 shrink-0" />
            </Link>
          )}
          <Separator orientation="vertical" className="h-6 shrink-0" />

          <div className="flex min-w-0 flex-1 flex-wrap items-center gap-2">
            <EnvelopeItemTitleInput
              dataTestId="envelope-title-input"
              className="min-w-0"
              disabled={!envelopeItemPermissions.canTitleBeChanged || !allowConfigureEnvelopeTitle}
              value={envelope.title}
              onChange={(title) => {
                updateEnvelope({
                  data: {
                    title,
                  },
                });
              }}
              placeholder={t`Envelope Title`}
            />

            {envelope.type === EnvelopeType.TEMPLATE && (
              <>
                {envelope.templateType === TemplateType.PRIVATE && (
                  <Badge variant="secondary" className="shrink-0">
                    <LockIcon className="mr-2 h-4 w-4 text-blue-600 dark:text-blue-300" />
                    <Trans>Private Template</Trans>
                  </Badge>
                )}
                {envelope.templateType === TemplateType.ORGANISATION && (
                  <Badge variant="orange" className="shrink-0">
                    <Building2Icon className="mr-2 size-4" />
                    <Trans>Organisation Template</Trans>
                  </Badge>
                )}
                {envelope.templateType === TemplateType.PUBLIC && (
                  <Badge variant="default" className="shrink-0">
                    <Globe2Icon className="mr-2 h-4 w-4 text-green-500 dark:text-green-300" />
                    <Trans>Public Template</Trans>
                  </Badge>
                )}

                {envelope.directLink?.token && (
                  <TemplateDirectLinkBadge
                    className="shrink-0 py-1"
                    token={envelope.directLink.token}
                    enabled={envelope.directLink.enabled}
                  />
                )}
              </>
            )}

            {envelope.type === EnvelopeType.DOCUMENT &&
              match(envelope.status)
                .with(DocumentStatus.DRAFT, () => (
                  <Badge variant="warning" className="shrink-0">
                    <Trans>Draft</Trans>
                  </Badge>
                ))
                .with(DocumentStatus.PENDING, () => (
                  <Badge variant="secondary" className="shrink-0">
                    <Trans>Pending</Trans>
                  </Badge>
                ))
                .with(DocumentStatus.COMPLETED, () => (
                  <Badge variant="default" className="shrink-0">
                    <Trans>Completed</Trans>
                  </Badge>
                ))
                .with(DocumentStatus.REJECTED, () => (
                  <Badge variant="destructive" className="shrink-0">
                    <Trans>Rejected</Trans>
                  </Badge>
                ))
                .with(DocumentStatus.CANCELLED, () => (
                  <Badge variant="destructive" className="shrink-0">
                    <Trans>Cancelled</Trans>
                  </Badge>
                ))
                .exhaustive()}

            {autosaveError && (
              <>
                <Badge variant="destructive" className="shrink-0">
                  <AlertTriangleIcon className="mr-2 h-4 w-4" />
                  <Trans>Sync failed, changes not saved</Trans>
                </Badge>

                <button
                  onClick={() => {
                    window.location.reload();
                  }}
                >
                  <Badge variant="destructive" className="shrink-0">
                    <RefreshCwIcon className="mr-2 h-4 w-4" />
                    <Trans>Reload</Trans>
                  </Badge>
                </button>
              </>
            )}
          </div>
        </div>

        <div className="flex min-w-0 shrink-0 flex-wrap items-center justify-end gap-2">
          {allowAttachments &&
            (isEmbedded ? (
              <EmbeddedEditorAttachmentPopover buttonSize="sm" />
            ) : (
              <DocumentAttachmentsPopover envelopeId={envelope.id} buttonSize="sm" />
            ))}

          {editorConfig.settings && (
            <EnvelopeEditorSettingsDialog
              trigger={
                <Button variant="outline" size="sm" aria-label={t`Settings`}>
                  <SettingsIcon className="h-4 w-4" />
                </Button>
              }
            />
          )}

          {match({ isEmbedded, isDocument, isTemplate, allowDistributing })
            .with({ isEmbedded: false, isDocument: true, allowDistributing: true }, () => (
              <>
                <EnvelopeDistributeDialog
                  documentRootPath={relativePath.documentRootPath}
                  trigger={
                    <Button size="sm">
                      <SendIcon className="mr-2 h-4 w-4" />
                      <Trans>Send Document</Trans>
                    </Button>
                  }
                />

                <EnvelopeRedistributeDialog
                  envelope={envelope}
                  trigger={
                    <Button size="sm">
                      <SendIcon className="mr-2 h-4 w-4" />
                      <Trans>Resend Document</Trans>
                    </Button>
                  }
                />
              </>
            ))
            .with({ isEmbedded: false, isTemplate: true, allowDistributing: true }, () => (
              <TemplateUseDialog
                envelopeId={envelope.id}
                templateId={mapSecondaryIdToTemplateId(envelope.secondaryId)}
                templateSigningOrder={envelope.documentMeta?.signingOrder}
                recipients={envelope.recipients}
                documentRootPath={relativePath.documentRootPath}
                trigger={
                  <Button size="sm">
                    <Trans>Use Template</Trans>
                  </Button>
                }
              />
            ))

            .otherwise(() => null)}

          {embedded?.mode === 'create' && (
            <Button size="sm" onClick={handleCreateEmbeddedEnvelope}>
              {isDocument ? <Trans>Create Document</Trans> : <Trans>Create Template</Trans>}
            </Button>
          )}

          {embedded?.mode === 'edit' && (
            <Button size="sm" onClick={handleUpdateEmbeddedEnvelope}>
              {isDocument ? <Trans>Update Document</Trans> : <Trans>Update Template</Trans>}
            </Button>
          )}
        </div>
      </div>
    </nav>
  );
}
