import { isCcRecipient } from '@documenso/lib/utils/recipients';

import { RecipientActionAuthSelect } from '@documenso/ui/components/recipient/recipient-action-auth-select';
import { RecipientAutoCompleteInput } from '@documenso/ui/components/recipient/recipient-autocomplete-input';
import { RecipientRoleSelect } from '@documenso/ui/components/recipient/recipient-role-select';
import { cn } from '@documenso/ui/lib/utils';

import { Button } from '@documenso/ui/primitives/button';

import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';

import { Input } from '@documenso/ui/primitives/input';

import { DragDropContext, Draggable, Droppable, type SensorAPI } from '@hello-pangea/dnd';

import { Trans, useLingui } from '@lingui/react/macro';
import { EnvelopeType, type RecipientRole } from '@prisma/client';
import { motion } from 'framer-motion';
import { GripVerticalIcon, TrashIcon } from 'lucide-react';

import type { useEnvelopeEditorRecipients } from './use-envelope-editor-recipients';

export const EnvelopeEditorRecipientList = ({ state }: { state: ReturnType<typeof useEnvelopeEditorRecipients> }) => {
  const { t } = useLingui();
  const {
    envelope,
    editorConfig,
    organisation,
    form,
    isSubmitting,
    signers,
    activeRecipientCount,
    showAdvancedSettings,
    isSigningOrderSequential,
    onDragEnd,
    $sensorApi,
    canRecipientBeModified,
    handleSigningOrderChange,
    recipientSuggestions,
    handleRecipientAutoCompleteSelect,
    setRecipientSearchQuery,
    isLoading,
    handleRoleChange,
    onRemoveSigner,
  } = state;
  return (
    <DragDropContext
      onDragEnd={onDragEnd}
      sensors={[
        (api: SensorAPI) => {
          $sensorApi.current = api;
        },
      ]}
    >
      <Droppable droppableId="signers">
        {(provided) => (
          <div {...provided.droppableProps} ref={provided.innerRef} className="flex w-full flex-col gap-y-2">
            {signers.map((signer, index) => {
              const isDirectRecipient =
                envelope.type === EnvelopeType.TEMPLATE &&
                envelope.directLink !== null &&
                signer.id === envelope.directLink.directTemplateRecipientId;

              return (
                <Draggable
                  key={`${signer.nativeId}-${signer.signingOrder}`}
                  draggableId={signer['nativeId']}
                  index={index}
                  isDragDisabled={
                    !isSigningOrderSequential ||
                    isSubmitting ||
                    isCcRecipient(signer) ||
                    !canRecipientBeModified(signer.id) ||
                    !signer.signingOrder
                  }
                >
                  {(provided, snapshot) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      className={cn('py-1', {
                        'pointer-events-none rounded-md bg-widget-foreground pt-2': snapshot.isDragging,
                      })}
                    >
                      <motion.fieldset
                        data-native-id={signer.id}
                        disabled={isSubmitting || !canRecipientBeModified(signer.id)}
                        className={cn('pb-2', {
                          'border-b pb-4': showAdvancedSettings && index !== signers.length - 1,
                          'pt-2': showAdvancedSettings && index === 0,
                          'pr-3': isSigningOrderSequential,
                        })}
                      >
                        <div className="flex flex-wrap items-center gap-2 sm:flex-nowrap">
                          {isSigningOrderSequential && isCcRecipient(signer) && (
                            <div className="mt-auto h-10 w-[4.25rem] flex-shrink-0" />
                          )}

                          {isSigningOrderSequential && !isCcRecipient(signer) && (
                            <FormField
                              control={form.control}
                              name={`signers.${index}.signingOrder`}
                              render={({ field }) => (
                                <FormItem
                                  className={cn('mt-auto flex items-center gap-x-1 space-y-0', {
                                    'mb-6':
                                      form.formState.errors.signers?.[index] &&
                                      !form.formState.errors.signers[index]?.signingOrder,
                                  })}
                                >
                                  <GripVerticalIcon className="h-5 w-5 flex-shrink-0 opacity-40" />
                                  <FormControl>
                                    <Input
                                      type="number"
                                      max={activeRecipientCount}
                                      data-testid="signing-order-input"
                                      className={cn(
                                        'w-10 text-center',
                                        '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',
                                      )}
                                      {...field}
                                      onChange={(e) => {
                                        field.onChange(e);
                                        handleSigningOrderChange(index, e.target.value);
                                      }}
                                      onBlur={(e) => {
                                        field.onBlur();
                                        handleSigningOrderChange(index, e.target.value);
                                      }}
                                      disabled={
                                        snapshot.isDragging || isSubmitting || !canRecipientBeModified(signer.id)
                                      }
                                    />
                                  </FormControl>
                                  <FormMessage />
                                </FormItem>
                              )}
                            />
                          )}

                          <FormField
                            control={form.control}
                            name={`signers.${index}.email`}
                            render={({ field }) => (
                              <FormItem
                                className={cn('relative w-full min-w-0 sm:flex-1', {
                                  'mb-6':
                                    form.formState.errors.signers?.[index] &&
                                    !form.formState.errors.signers[index]?.email,
                                })}
                              >
                                {!showAdvancedSettings && index === 0 && (
                                  <FormLabel>
                                    <Trans>Email</Trans>
                                  </FormLabel>
                                )}

                                <FormControl>
                                  <RecipientAutoCompleteInput
                                    type="email"
                                    placeholder={t`Email`}
                                    value={field.value}
                                    disabled={
                                      snapshot.isDragging ||
                                      isSubmitting ||
                                      !canRecipientBeModified(signer.id) ||
                                      isDirectRecipient
                                    }
                                    options={recipientSuggestions}
                                    onSelect={(suggestion) => handleRecipientAutoCompleteSelect(index, suggestion)}
                                    onSearchQueryChange={(query) => {
                                      field.onChange(query);
                                      setRecipientSearchQuery(query);
                                    }}
                                    loading={isLoading}
                                    data-testid="signer-email-input"
                                    maxLength={254}
                                  />
                                </FormControl>

                                <FormMessage />
                              </FormItem>
                            )}
                          />

                          <FormField
                            control={form.control}
                            name={`signers.${index}.name`}
                            render={({ field }) => (
                              <FormItem
                                className={cn('w-full min-w-0 sm:flex-1', {
                                  'mb-6':
                                    form.formState.errors.signers?.[index] &&
                                    !form.formState.errors.signers[index]?.name,
                                })}
                              >
                                {!showAdvancedSettings && index === 0 && (
                                  <FormLabel>
                                    <Trans>Name</Trans>
                                  </FormLabel>
                                )}

                                <FormControl>
                                  <RecipientAutoCompleteInput
                                    type="text"
                                    placeholder={t`Recipient ${index + 1}`}
                                    {...field}
                                    disabled={
                                      snapshot.isDragging ||
                                      isSubmitting ||
                                      !canRecipientBeModified(signer.id) ||
                                      isDirectRecipient
                                    }
                                    options={recipientSuggestions}
                                    onSelect={(suggestion) => handleRecipientAutoCompleteSelect(index, suggestion)}
                                    onSearchQueryChange={(query) => {
                                      field.onChange(query);
                                      setRecipientSearchQuery(query);
                                    }}
                                    loading={isLoading}
                                    maxLength={255}
                                  />
                                </FormControl>

                                <FormMessage />
                              </FormItem>
                            )}
                          />

                          <FormField
                            control={form.control}
                            name={`signers.${index}.role`}
                            render={({ field }) => (
                              <FormItem
                                className={cn('mt-auto w-fit', {
                                  'mb-6':
                                    form.formState.errors.signers?.[index] &&
                                    !form.formState.errors.signers[index]?.role,
                                })}
                              >
                                <FormControl>
                                  <RecipientRoleSelect
                                    {...field}
                                    hideAssistantRole={!editorConfig.recipients?.allowAssistantRole}
                                    hideCCerRole={!editorConfig.recipients?.allowCCerRole}
                                    hideViewerRole={!editorConfig.recipients?.allowViewerRole}
                                    hideApproverRole={!editorConfig.recipients?.allowApproverRole}
                                    isAssistantEnabled={isSigningOrderSequential}
                                    onValueChange={(value) => {
                                      // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
                                      handleRoleChange(index, value as RecipientRole);
                                    }}
                                    disabled={snapshot.isDragging || isSubmitting || !canRecipientBeModified(signer.id)}
                                  />
                                </FormControl>

                                <FormMessage />
                              </FormItem>
                            )}
                          />

                          <Button
                            variant="ghost"
                            className={cn('mt-auto px-2', {
                              'mb-6': form.formState.errors.signers?.[index],
                            })}
                            data-testid="remove-signer-button"
                            disabled={
                              snapshot.isDragging ||
                              isSubmitting ||
                              !canRecipientBeModified(signer.id) ||
                              signers.length === 1 ||
                              isDirectRecipient
                            }
                            onClick={() => onRemoveSigner(index)}
                          >
                            <TrashIcon className="h-4 w-4" />
                          </Button>
                        </div>

                        {showAdvancedSettings && organisation.organisationClaim.flags.cfr21 && (
                          <FormField
                            control={form.control}
                            name={`signers.${index}.actionAuth`}
                            render={({ field }) => (
                              <FormItem
                                className={cn('mt-2 w-full', {
                                  'mb-6':
                                    form.formState.errors.signers?.[index] &&
                                    !form.formState.errors.signers[index]?.actionAuth,
                                  'pl-6': isSigningOrderSequential,
                                })}
                              >
                                <FormControl>
                                  <RecipientActionAuthSelect
                                    {...field}
                                    onValueChange={field.onChange}
                                    disabled={snapshot.isDragging || isSubmitting || !canRecipientBeModified(signer.id)}
                                  />
                                </FormControl>

                                <FormMessage />
                              </FormItem>
                            )}
                          />
                        )}
                      </motion.fieldset>
                    </div>
                  )}
                </Draggable>
              );
            })}

            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
};
