'use client';
/**
 * This Source Code is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright (c) Infonomic Company Limited
 */
import { useCallback, useMemo } from 'react';
import { slugify } from '@byline/core';
import { useTranslation } from '@byline/i18n/react';
import { Input, Label } from '@byline/ui/react';
import cx from 'clsx';
import { useFieldValue, useFormContext, useSystemPath } from './form-context';
import styles from './path-widget.module.css';
/**
 * Coerce an arbitrary source-field value (string, Date, or other) into
 * a string suitable for slugification. Mirrors the lifecycle's coercion
 * so the live preview matches what the server will store.
 */
function coerceToString(value) {
    if (value == null)
        return '';
    if (value instanceof Date)
        return value.toISOString();
    return String(value);
}
/**
 * System-managed `path` widget.
 *
 * Edits the path stored in `byline_document_paths` for the current
 * (document, locale) row. Displays the current persisted/overridden
 * value as an editable input.
 * In create mode, when the user hasn't supplied an override, the input
 * shows the live-derived preview (slugified `useAsPath` source field) as
 * a placeholder so the user sees what will be saved. The "Regenerate"
 * action explicitly writes the current live preview into the override
 * slot so the user can re-anchor a path against the source field after
 * editing the title.
 *
 * Stable override handles: `.byline-form-path`, `.byline-form-path-header`,
 * `.byline-form-path-regenerate`.
 */
export const PathWidget = ({ useAsPath, collectionPath, defaultLocale, activeLocale, mode, slugifier, sourceLocked = false, disabled = false, }) => {
    const { setSystemPath } = useFormContext();
    const { t } = useTranslation('byline-admin');
    const systemPath = useSystemPath();
    const sourceValue = useFieldValue(useAsPath ?? '');
    // The installation slugifier, or the built-in default. Server-side path
    // derivation uses `ServerConfig.slugifier`; this must be the same function
    // (registered via `AdminConfig.slugifier`) or the preview will disagree
    // with what the server persists.
    const runSlugify = slugifier ?? slugify;
    // Phase 1: paths are written/edited only under the default content
    // locale. When editing a translation, the widget locks down — the
    // input is read-only, the Regenerate action is suppressed, and a
    // helpText line explains why.
    const isReadOnly = activeLocale !== defaultLocale;
    // Live preview — what the server would derive from the current source
    // field value if no override were set. Used as placeholder in create
    // mode and as the target of the "Regenerate" action.
    const livePreview = useMemo(() => {
        // A locked source (server-assigned counter / read-only field) can't be
        // previewed or regenerated from the form — suppress the derivation.
        if (!useAsPath || sourceLocked)
            return '';
        const asString = coerceToString(sourceValue);
        if (asString.length === 0)
            return '';
        return runSlugify(asString, { locale: defaultLocale, collectionPath });
    }, [useAsPath, sourceLocked, sourceValue, defaultLocale, collectionPath, runSlugify]);
    const inputValue = systemPath ?? '';
    const handleChange = useCallback((next) => {
        if (disabled)
            return;
        // Empty string clears the override — server falls back to derive
        // (create) or sticky (update).
        setSystemPath(next.length === 0 ? null : next);
    }, [disabled, setSystemPath]);
    const handleRegenerate = useCallback(() => {
        if (!disabled && livePreview.length > 0) {
            setSystemPath(livePreview);
        }
    }, [disabled, livePreview, setSystemPath]);
    // Validate live: if the typed value differs from its slugified form,
    // surface an inline hint without blocking input (mirrors the previous
    // field-hook advisory behaviour).
    const formatted = useMemo(() => {
        if (inputValue.length === 0)
            return '';
        return runSlugify(inputValue, { locale: defaultLocale, collectionPath });
    }, [inputValue, defaultLocale, collectionPath, runSlugify]);
    const validationHint = inputValue.length > 0 && formatted !== inputValue
        ? t('pathWidget.suggestedHint', { formatted })
        : undefined;
    // When read-only, replace the live validation hint with a fixed
    // explanatory line so editors understand why the field is locked.
    const readOnlyHint = isReadOnly
        ? t('pathWidget.readOnlyHint', { locale: defaultLocale })
        : undefined;
    const hint = readOnlyHint ?? validationHint;
    const placeholder = !isReadOnly && mode === 'create' && livePreview.length > 0
        ? t('pathWidget.willBeSavedAs', { preview: livePreview })
        : undefined;
    // Screen-reader description. The input's base purpose ("System-managed
    // URL path") plus whichever of the visible hints (placeholder preview
    // in create mode, "Suggested" validation hint, or read-only explainer)
    // currently applies. The visible helpText/placeholder cover sighted
    // users; this element makes the same information addressable via
    // aria-describedby for AT.
    const srDescription = [t('pathWidget.srDescription'), placeholder, hint].filter(Boolean).join(' ');
    const showRegenerate = !isReadOnly && useAsPath && livePreview.length > 0 && livePreview !== systemPath;
    return (<div className="byline-form-path">
      <div className={cx('byline-form-path-header', styles.header)}>
        <Label id="system-path-label" htmlFor="system-path" label={t('pathWidget.label')}/>
        {showRegenerate && (<button type="button" onClick={handleRegenerate} className={cx('byline-form-path-regenerate', styles.regenerate)} disabled={disabled} aria-label={t('pathWidget.regenerateAriaLabel', { field: useAsPath })}>
            {t('pathWidget.regenerateButton', { field: useAsPath })}
          </button>)}
      </div>
      <Input disabled={disabled} id="system-path" name="__systemPath__" value={inputValue} placeholder={placeholder} onChange={(e) => handleChange(e.target.value)} helpText={hint} readOnly={isReadOnly} aria-describedby="system-path-description"/>
      <span id="system-path-description" className={cx('byline-form-path-sr-only', styles['sr-only'])}>
        {srDescription}
      </span>
    </div>);
};
