import { useEffect, useMemo, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { Button } from "@govoplan/core-webui";
import { Dialog } from "@govoplan/core-webui";
import { DismissibleAlert } from "@govoplan/core-webui";
import {
  buildUndefinedPlaceholders,
  extractTemplatePlaceholders,
  removePlaceholderFromText,
  replacePlaceholderInText,
  type TemplateNamespace,
  type UndefinedPlaceholder } from
"../utils/templatePlaceholders";
import {
  TemplateFieldChipList,
  UndefinedPlaceholderDecisionDialog,
  UndefinedPlaceholderList,
  type TemplateFieldOption } from
"./TemplatePlaceholderControls";

export default function TemplateExpressionEditorDialog({
  open,
  title,
  value,
  localFields,
  globalFields,
  placeholder,
  description,
  saveLabel = "i18n:govoplan-campaign.save.efc007a3",
  validate,
  onCancel,
  onSave,
  onAddField,
  canAddField = () => true














}: {open: boolean;title: string;value: string;localFields: TemplateFieldOption[];globalFields: TemplateFieldOption[];placeholder?: string;description?: string;saveLabel?: string;validate?: (value: string) => string;onCancel: () => void;onSave: (value: string) => void;onAddField: (name: string) => void;canAddField?: (name: string) => boolean;}) {
  const [draftValue, setDraftValue] = useState(value);
  const [undefinedDialog, setUndefinedDialog] = useState<UndefinedPlaceholder | null>(null);
  const inputRef = useRef<HTMLInputElement | null>(null);

  useEffect(() => {
    if (!open) return;
    setDraftValue(value);
    setUndefinedDialog(null);
  }, [open, value]);

  const usedPlaceholders = useMemo(() => extractTemplatePlaceholders(draftValue), [draftValue]);
  const localNames = useMemo(() => new Set(localFields.map((field) => field.name)), [localFields]);
  const globalNames = useMemo(() => new Set(globalFields.map((field) => field.name)), [globalFields]);
  const availableNames = useMemo(() => new Set([...localNames, ...globalNames]), [globalNames, localNames]);
  const undefinedPlaceholders = useMemo(
    () => buildUndefinedPlaceholders(usedPlaceholders, availableNames, { local: localNames, global: globalNames }),
    [availableNames, globalNames, localNames, usedPlaceholders]
  );
  const validationMessage = validate?.(draftValue) ?? "";

  function insertPlaceholder(namespace: TemplateNamespace, name: string) {
    const input = inputRef.current;
    const token = `{{${namespace}:${name}}}`;
    const defaultPosition = draftValue.toLocaleLowerCase().endsWith(".zip") ? draftValue.length - 4 : draftValue.length;
    const start = input?.selectionStart ?? defaultPosition;
    const end = input?.selectionEnd ?? start;
    setDraftValue(`${draftValue.slice(0, start)}${token}${draftValue.slice(end)}`);
    window.requestAnimationFrame(() => {
      input?.focus();
      const cursor = start + token.length;
      input?.setSelectionRange(cursor, cursor);
    });
  }

  function requestSave() {
    if (validationMessage) return;
    if (undefinedPlaceholders.length > 0) {
      setUndefinedDialog(undefinedPlaceholders[0]);
      return;
    }
    onSave(draftValue.trim());
  }

  function removeUndefined(field: UndefinedPlaceholder) {
    setDraftValue((current) => removePlaceholderFromText(current, field.raw));
    setUndefinedDialog(null);
  }

  function addUndefined(field: UndefinedPlaceholder) {
    if (!field.name || field.reason === "invalid-namespace") return;
    onAddField(field.name);
    setUndefinedDialog(null);
  }

  function replaceUndefined(field: UndefinedPlaceholder, namespace: TemplateNamespace, name: string) {
    setDraftValue((current) => replacePlaceholderInText(current, field.raw, `{{${namespace}:${name}}}`));
    setUndefinedDialog(null);
  }

  if (!open || typeof document === "undefined") return null;

  return createPortal(
    <>
      <Dialog
        open={open && !undefinedDialog}
        title={title}
        closeLabel="i18n:govoplan-campaign.cancel_filename_changes.b558598e"
        className="template-expression-dialog"
        headerClassName="template-expression-dialog-header"
        bodyClassName="template-expression-dialog-body"
        footerClassName="template-expression-dialog-footer"
        onClose={onCancel}
        footer={
        <>
            <Button onClick={onCancel}>i18n:govoplan-campaign.cancel.77dfd213</Button>
            <Button variant="primary" onClick={requestSave} disabled={Boolean(validationMessage)}>{saveLabel}</Button>
          </>
        }>
        
        {description && <p className="muted template-expression-description">{description}</p>}
        <label className="template-expression-value-field">
          <span>i18n:govoplan-campaign.archive_filename.47becf3d</span>
          <input
            ref={inputRef}
            value={draftValue}
            placeholder={placeholder}
            aria-invalid={Boolean(validationMessage) || undefined}
            onChange={(event) => setDraftValue(event.target.value)}
            onKeyDown={(event) => {
              if (event.key === "Enter") {
                event.preventDefault();
                requestSave();
              }
            }} />
          
        </label>
        {validationMessage && <DismissibleAlert tone="danger" resetKey={validationMessage}>{validationMessage}</DismissibleAlert>}

        <h3 className="section-mini-heading">i18n:govoplan-campaign.recipient_fields.fdbcd95b</h3>
        <p className="muted small-note">i18n:govoplan-campaign.select_a_field_to_insert_it_at_the_current_curso.1d1b51be <code>i18n:govoplan-campaign.to_2.8c1db0c7</code> or <code>i18n:govoplan-campaign.to_2_email.5ad61c1a</code> i18n:govoplan-campaign.for_another_single_value.ce57d76a</p>
        <TemplateFieldChipList
          namespace="local"
          fields={localFields}
          usedPlaceholders={usedPlaceholders}
          empty="i18n:govoplan-campaign.no_recipient_fields_are_available.5b7943ad"
          onInsert={insertPlaceholder} />
        

        <h3 className="section-mini-heading">i18n:govoplan-campaign.campaign_fields.969e7d80</h3>
        <TemplateFieldChipList
          namespace="global"
          fields={globalFields}
          usedPlaceholders={usedPlaceholders}
          empty="i18n:govoplan-campaign.no_campaign_fields_or_global_values_are_availabl.b2e4089d"
          onInsert={insertPlaceholder} />
        

        <h3 className="section-mini-heading">i18n:govoplan-campaign.used_but_undefined.3b829043</h3>
        <UndefinedPlaceholderList items={undefinedPlaceholders} onSelect={setUndefinedDialog} />
      </Dialog>

      <UndefinedPlaceholderDecisionDialog
        field={undefinedDialog}
        contextLabel="i18n:govoplan-campaign.archive_filename.de958cbd"
        removeLabel="i18n:govoplan-campaign.remove_from_filename.560f7f42"
        onCancel={() => setUndefinedDialog(null)}
        onRemove={removeUndefined}
        onReplace={replaceUndefined}
        onAddField={addUndefined}
        localFields={localFields}
        globalFields={globalFields}
        addDisabled={Boolean(undefinedDialog?.name) && !canAddField(undefinedDialog?.name ?? "")} />
      
    </>,
    document.body
  );
}