{#
    "Edit Element" layout template

    The following variables should be defined by the sub-template:

    - element: the source element or one of its drafts/revisions
    - hasRevisions: whether the element has revisions, which will determine whether the revision notes field should be displayed.
    - canDeleteDraft (optional): whether the current user is allowed to delete the draft (if it is one).
      If the current user created the draft, then it will be deletable regardless.
    - canUpdateSource (optional): whether the current user is allowed to update the source element
      (e.g. by publishing a draft or reverting the element to a prior revision)
    - canDuplicateSource: whether the current user is allowed to duplicate the source element
    - canAddAnother: whether the current user is allowed to create another source element after saving the current one
    - canDeleteSource: whether the current user is allowed to delete the source element
    - canDeleteForSite: whether the current user is allowed to delete the source element for the current site
    - redirectUrl: the URL that the user should be redirected to after saving the source element
    - addAnotherRedirectUrl: the URL that the user should be redirected to after opting to save and add another
    - saveSourceAction: the controller action that should be used to save the source element
    - duplicateSourceAction: the controller action that should be used to duplicate the source element
    - deleteSourceAction: the controller action that should be used to delete the source element
    - deleteForSiteAction: the controller action that should be used to delete the source element for the current site
    - saveDraftAction: the controller action that should be used to save a draft
    - deleteDraftAction: the controller action that should be used to delete a draft
    - publishDraftAction: the controller action that should be used to apply a draft onto the source element
    - revertSourceAction: the controller action that should be used to revert the source element to a revision
    - showStatusToggles: whether the “Enabled” / “Enabled” for <Site>” fields should be added to the details pane
#}

{% extends '_layouts/cp' %}
{% import '_includes/forms' as forms %}

{% set generalConfig = craft.app.config.general %}

{% set saveSourceAction = saveSourceAction ?? null %}
{% set duplicateSourceAction = duplicateSourceAction ?? null %}
{% set deleteSourceAction = deleteSourceAction ?? null %}
{% set deleteForSiteAction = deleteForSiteAction ?? null %}
{% set revertSourceAction = revertSourceAction ?? null %}
{% set saveDraftAction = saveDraftAction ?? null %}
{% set publishDraftAction = publishDraftAction ?? applyDraftAction ?? null %}
{% set deleteDraftAction = deleteDraftAction ?? null %}

{% set isDraft = element.getIsDraft() %}
{% set isProvisionalDraft = element.isProvisionalDraft %}
{% set isUnpublishedDraft = element.getIsUnpublishedDraft() %}
{% set isRevision = element.getIsRevision() %}
{% set isCurrent = not isDraft and not isRevision %}
{% set isLikeCurrent = isCurrent or isProvisionalDraft or isUnpublishedDraft %}

{% set allSites = craft.app.isMultiSite
    ? element.getSupportedSites()|map(s => s is array ? s : {siteId: s})
    : [{siteId: element.siteId}] %}
{% set allEditableSiteIds = craft.app.sites.getEditableSiteIds() %}
{% set propSiteIds = allSites|filter(s => s.propagate ?? true)|column('siteId') %}
{% set propEditableSiteIds = propSiteIds|intersect(allEditableSiteIds) %}
{% set isMultiSiteElement = craft.app.isMultiSite and allSites|length > 1 %}
{% set addlEditableSites = allSites|filter(s => not (s.propagate ?? true) and s.siteId in allEditableSiteIds) %}
{% set canEditMultipleSites = isMultiSiteElement and (propEditableSiteIds|length > 1 or addlEditableSites|length) %}

{# See if this is a new site that isn’t supported by the source element yet #}
{% if isUnpublishedDraft %}
    {% set isNewlySupportedSite = true %}
{% elseif isDraft %}
    {% set isNewlySupportedSite = not element.find()
        .id(element.getCanonicalId())
        .siteId(element.siteId)
        .anyStatus()
        .exists() %}
{% else %}
    {% set isNewlySupportedSite = false %}
{% endif %}

{% set previewTargets = saveDraftAction ? element.getPreviewTargets() : [] %}
{% set enablePreview = previewTargets and not craft.app.request.isMobileBrowser(true) %}

{% if previewTargets %}
    {% if isDraft and not isProvisionalDraft %}
        {% do craft.app.session.authorize('previewDraft:' ~ element.draftId) %}
    {% elseif isRevision %}
        {% do craft.app.session.authorize('previewRevision:' ~ element.revisionId) %}
    {% else %}
        {% do craft.app.session.authorize('previewElement:' ~ element.getCanonicalId()) %}
    {% endif %}
{% endif %}

{% set canDeleteDraft = (
    isDraft and
    not isProvisionalDraft and
    ((canDeleteDraft ?? false) or element.creatorId == currentUser.id) and
    deleteDraftAction
) %}
{% set canUpdateSource = canUpdateSource ?? false %}
{% set canDuplicateSource = canDuplicateSource ?? false %}
{% set canAddAnother = canAddAnother ?? false %}
{% set canDeleteSource = canDeleteSource ?? false %}
{% set canDeleteForSite = (canDeleteForSite ?? false) and deleteForSiteAction and
    isMultiSiteElement and propSiteIds|length > 1 and
    ((isLikeCurrent and canDeleteSource) or (isDraft and canDeleteDraft and isNewlySupportedSite)) %}
{% set canEdit = canEdit ?? (canUpdateSource or canDuplicateSource or canAddAnother or saveDraftAction) %}

{% set redirectUrl = redirectUrl ?? generalConfig.getPostCpLoginRedirect() %}
{% set addAnotherRedirectUrl = addAnotherRedirectUrl ?? null %}
{% set hashedCpEditUrl = '{cpEditUrl}'|hash %}

{% if not isRevision %}
    {% set fullPageForm = true %}
{% endif %}

{# If this is an unpublished draft, then we should only show status toggles if the
   user actually has permission to publish changes #}
{% set showStatusToggles = (showStatusToggles ?? true) and
    element.hasStatuses() and
    (not isUnpublishedDraft or canUpdateSource) %}

{% if (not isDraft or isProvisionalDraft) and not canUpdateSource %}
    {% set saveShortcut = false %}
{% elseif isCurrent and canUpdateSource %}
    {% set saveShortcutRedirect = '{cpEditUrl}' %}
{% endif %}

{% set form = element.getFieldLayout().createForm(element, isRevision or not canEdit, {
    registerDeltas: true,
}) %}

{% if tabs is not defined %}
    {% set tabs = form.getTabMenu() %}
{% endif %}

{% set settingsHtml = (block('settings') ?? '')|trim %}

{# Set action button text #}
{% set actionButtonLabel = 'Actions'|t('app') %}

{% set formActions = [] %}

{% if isLikeCurrent %}
    {% if canUpdateSource and saveSourceAction %}
        {% set formActions = formActions|push({
            label: isUnpublishedDraft ? 'Create and continue editing'|t('app') : 'Save and continue editing'|t('app'),
            redirect: hashedCpEditUrl,
            shortcut: true,
            retainScroll: true,
            eventData: {
                autosave: false,
            },
        }) %}
        {% if canAddAnother and addAnotherRedirectUrl %}
            {% set formActions = formActions|push({
                label: isUnpublishedDraft ? 'Create and add another'|t('app') : 'Save and add another'|t('app'),
                action: isUnpublishedDraft ? publishDraftAction : null,
                redirect: addAnotherRedirectUrl|hash,
                shortcut: true,
                shift: true,
                eventData: {
                    autosave: false,
                },
            }) %}
        {% endif %}
        {% if isUnpublishedDraft %}
            {% set formActions = formActions|push({
                label: 'Save draft'|t('app'),
                action: saveDraftAction,
                redirect: (redirectUrl ~ '#')|hash,
                eventData: {
                    autosave: false,
                },
            }) %}
        {% elseif canDuplicateSource and duplicateSourceAction %}
            {% set formActions = formActions|push({
                label: 'Save as a new {type}'|t('app', {
                    type: element.lowerDisplayName(),
                }),
                action: duplicateSourceAction,
                redirect: hashedCpEditUrl,
            }) %}
        {% endif %}
    {% endif %}
    {% if canDeleteForSite %}
        {% set formActions = formActions|push({
            destructive: true,
            label: isUnpublishedDraft ? 'Delete draft for this site'|t('app') : 'Delete {type} for this site'|t('app', {
                type: element.lowerDisplayName()
            }),
            action: deleteForSiteAction,
            redirect: (redirectUrl ~ '#')|hash,
            confirm: isUnpublishedDraft ? 'Are you sure you want to delete the draft for this site?'|t('app') : 'Are you sure you want to delete the {type} for this site?'|t('app', {
                type: element.lowerDisplayName(),
            }),
        }) %}
    {% endif %}
    {% if (
        (isUnpublishedDraft and canDeleteDraft and deleteDraftAction) or
        (not isUnpublishedDraft and not isProvisionalDraft and canDeleteSource and deleteSourceAction)
    ) %}
        {% set formActions = formActions|push({
            destructive: true,
            label: isUnpublishedDraft ? 'Delete draft'|t('app') : 'Delete {type}'|t('app', {
                type: element.lowerDisplayName()
            }),
            action: isUnpublishedDraft ? deleteDraftAction : deleteSourceAction,
            redirect: (redirectUrl ~ '#')|hash,
            confirm: isUnpublishedDraft ? 'Are you sure you want to delete this draft?'|t('app') : 'Are you sure you want to delete this {type}?'|t('app', {
                type: element.lowerDisplayName(),
            }),
        }) %}
    {% endif %}
{% elseif isDraft %}
    {% if saveDraftAction %}
        {% set formActions = formActions|push({
            label: 'Save and continue editing'|t('app'),
            redirect: hashedCpEditUrl,
            action: saveDraftAction,
            shortcut: true,
            retainScroll: true,
        }) %}
    {% endif %}
    {% if canDeleteDraft %}
        {% if canDeleteForSite %}
            {% set formActions = formActions|push({
                destructive: true,
                label: 'Delete draft for this site'|t('app'),
                action: deleteForSiteAction,
                redirect: (redirectUrl ~ '#')|hash,
                confirm: 'Are you sure you want to delete the draft for this site?'|t('app'),
            }) %}
        {% endif %}
        {% set formActions = formActions|push({
            destructive: true,
            label: 'Delete draft'|t('app'),
            action: deleteDraftAction,
            redirect: hashedCpEditUrl,
            confirm: 'Are you sure you want to delete this draft?'|t('app'),
        }) %}
    {% endif %}
{% endif %}

{% hook 'cp.elements.edit' %}

{% block header %}
    <div class="flex flex-nowrap">
        {{ block('pageTitle') }}
        {{ block('contextMenu') }}
    </div>
    <div class="flex" id="action-buttons">
        {{ block('actionButton') }}
    </div>
{% endblock %}

{% block contextMenu %}
    {% set canHaveDrafts = not isUnpublishedDraft and saveDraftAction %}
    {% if isMultiSiteElement or canHaveDrafts or element.find().revisionOf(element).exists() %}
        {% include "_includes/revisionmenu" with {
            supportedSiteIds: propSiteIds,
        } %}
    {% endif %}
    {% if not isRevision %}
        <div id="revision-spinner" class="spinner hidden" title="{{ 'Saving'|t('app') }}" aria-label="{{ 'Saving'|t('app') }}"></div>
        <div id="revision-status" class="invisible"></div>
        <div id="revision-status-message" aria-live="polite"></div>
    {% endif %}
{% endblock %}

{% block actionButton %}
    {% if previewTargets %}
        <div id="preview-btn-container" class="btngroup">
            {% if enablePreview %}
                <button type="button" id="preview-btn" class="btn">{{ "Preview"|t('app') }}</button>
            {% endif %}
        </div>
    {% endif %}

    {% if isLikeCurrent %}
        {% if not isUnpublishedDraft and saveDraftAction %}
            <div id="save-draft-btn-container">
                {{ tag('button', {
                    type: canUpdateSource and saveSourceAction ? 'button' : 'submit',
                    class: [
                        'btn',
                        'formsubmit',
                        not (canUpdateSource and saveSourceAction) ? 'submit',
                    ]|filter,
                    text: 'Create a draft'|t('app'),
                    data: {
                        action: saveDraftAction,
                        redirect: hashedCpEditUrl,
                        param: 'dropProvisional',
                        value: 1,
                    },
                }) }}
                {% if not (canUpdateSource and saveSourceAction) %}
                    {% if formActions is not empty %}
                        <button type="button" class="btn menubtn" data-icon="settings" aria-label="{{ actionButtonLabel }}"></button>
                        {% include '_layouts/components/form-action-menu' %}
                    {% endif %}
                {% endif %}
            </div>
        {% endif %}
        {% if canUpdateSource and saveSourceAction %}
            <div id="save-btn-container" class="btngroup submit">
                <button type="submit" class="btn submit">
                    {{ isUnpublishedDraft ? 'Create {type}'|t('app', {
                        type: element.lowerDisplayName(),
                    }) : 'Save'|t('app') }}
                </button>
                {% if formActions is not empty %}
                    <button type="button" class="btn submit menubtn" aria-label="{{ actionButtonLabel }}"></button>
                    {% include '_layouts/components/form-action-menu' %}
                {% endif %}
            </div>
        {% elseif isUnpublishedDraft %}
            <div id="save-btn-container" class="btngroup submit">
                <button type="submit" class="btn submit formsubmit" data-action="{{ saveDraftAction }}" data-redirect="{{ (redirectUrl ~ '#')|hash }}">{{ 'Save draft'|t('app') }}</button>
                {% if formActions is not empty %}
                    <button type="button" class="btn submit menubtn" aria-label="{{ actionButtonLabel }}"></button>
                    {% include '_layouts/components/form-action-menu' %}
                {% endif %}
            </div>
        {% endif %}
    {% elseif isDraft %}
        {% if canUpdateSource and publishDraftAction %}
            <div id="publish-draft-btn-container">
                {{ tag('button', {
                    type: 'button',
                    class: ['btn', 'secondary', 'formsubmit'],
                    text: 'Apply draft'|t('app'),
                    title: forms.shortcutText('S', false, true),
                    data: {
                        action: publishDraftAction,
                        redirect: hashedCpEditUrl,
                    },
                }) }}
            </div>
        {% endif %}
        <div id="save-btn-container" class="btngroup submit">
            <button type="submit" class="btn submit">{{ 'Save draft'|t('app') }}</button>
            {% if canDeleteDraft and formActions is not empty %}
                <button type="button" class="btn submit menubtn" aria-label="{{ actionButtonLabel }}"></button>
                {% include '_layouts/components/form-action-menu' %}
            {% endif %}
        </div>
    {% elseif isRevision and canUpdateSource and revertSourceAction %}
        <form method="post" accept-charset="UTF-8">
            {{ csrfInput() }}
            {{ actionInput(revertSourceAction) }}
            {{ redirectInput('{cpEditUrl}') }}
            {{ hiddenInput('revisionId', element.revisionId) }}
            <div class="secondary-buttons">
                <button type="button" class="btn secondary formsubmit">{{ 'Revert content from this revision'|t('app') }}</button>
            </div>
        </form>
    {% endif %}
{% endblock %}

{% block main %}
    {% if not isRevision %}
        {# action and redirect params #}
        {% if isProvisionalDraft or isUnpublishedDraft %}
            {% if canUpdateSource and publishDraftAction %}
                {{ actionInput(publishDraftAction, {id: 'action'}) }}
            {% endif %}
        {% elseif isCurrent %}
            {% if canUpdateSource and saveSourceAction %}
                {{ actionInput(saveSourceAction, {id: 'action'}) }}
            {% endif %}
        {% elseif isDraft and saveDraftAction %}
            {{ actionInput(saveDraftAction, {id: 'action'}) }}
        {% endif %}
        {{ redirectInput(redirectUrl) }}

        {# siteId param #}
        {% if craft.app.isMultiSite %}
            {{ hiddenInput('siteId', element.siteId) }}
        {% endif %}

        {# propagateAll param #}
        {% if isUnpublishedDraft and craft.app.request.getQueryParam('fresh') %}
            {{ hiddenInput('isFresh', '1') }}
        {% endif %}
    {% endif %}
    {{ parent() }}
{% endblock %}

{% block content %}
    {% if not isRevision %}
        {{ hiddenInput('sourceId', element.getCanonicalId()) }}
    {% else %}
        {{ hiddenInput('revisionId', entry.revisionId) }}
    {% endif %}

    <div id="fields">
        {{ form.render()|raw }}
    </div>
{% endblock %}

{% block details %}
    {% if notices ?? false %}
        <div class="meta read-only warning">
            {% for notice in notices %}
                <p>{{ notice }}</p>
                {% if not loop.last %}<hr>{% endif %}
            {% endfor %}
        </div>
    {% endif %}

    {% if settingsHtml %}
        <div id="settings" class="meta">
            {{ settingsHtml|raw }}
        </div>
    {% endif %}

    {% if showStatusToggles and isMultiSiteElement %}
        <div class="meta">
            {{ forms.lightswitchField({
                status: element.getAttributeStatus('enabled'),
                label: 'Enabled for {site}'|t('app', { site: element.site.name|t('site')|e }) ~
                    (canEditMultipleSites ? tag('button', {
                        type: 'button',
                        id: 'expand-status-btn',
                        class: ['btn'],
                        data: {
                            icon: 'ellipsis',
                        },
                    })),
                id: "enabledForSite-#{element.siteId}",
                name: "enabledForSite[#{element.siteId}]",
                on: element.enabled and element.getEnabledForSite(),
                disabled: isRevision,
            }) }}
        </div>
    {% endif %}

    <div id="meta-details" class="meta read-only">
        {% block meta %}
            {% set metaElement = isProvisionalDraft ? element.getCanonical(true) : element %}
            {% if element.hasStatuses() %}
                {% if isUnpublishedDraft %}
                    {% set statusColor = 'white' %}
                    {% set statusLabel = 'Draft'|t('app') %}
                {% else %}
                    {% set status = element.getStatus() %}
                    {% set statusDef = element.statuses()[status] ?? null %}
                    {% set statusColor = statusDef.color ?? status %}
                    {% set statusLabel = statusDef.label ?? statusDef ?? status|ucfirst %}
                {% endif %}
                <div class="data">
                    <h5 class="heading">{{ 'Status'|t('app') }}</h5>
                    <div id="status-value" class="value">
                        {% if isUnpublishedDraft %}
                            <span data-icon="draft"></span>
                        {% else %}
                            <span class="status {{ statusColor }}"></span>
                        {% endif %}
                        <span>{{ statusLabel }}</span>
                    </div>
                </div>
            {% endif %}
            <div class="data">
                <h5 class="heading">{{ "Created at"|t('app') }}</h5>
                <div id="date-created-value" class="value">{{ metaElement.dateCreated|datetime('short') }}</div>
            </div>
            <div class="data">
                <h5 class="heading">{{ "Updated at"|t('app') }}</h5>
                <div id="date-updated-value" class="value">{{ metaElement.dateUpdated|datetime('short') }}</div>
            </div>
            {% if isRevision %}
                {% set revisionNotes = element.revisionNotes %}
            {% elseif isLikeCurrent and metaElement.currentRevision %}
                {% set revisionNotes = metaElement.currentRevision.revisionNotes %}
            {% else %}
                {% set revisionNotes = null %}
            {% endif %}
            {% if revisionNotes %}
                <div class="data">
                    <h5 class="heading">{{ "Notes"|t('app') }}</h5>
                    <div class="value">{{ revisionNotes }}</div>
                </div>
            {% endif %}
        {% endblock %}
    </div>

    {% if (isLikeCurrent and (hasRevisions ?? false)) or isDraft %}
        {{ forms.textarea({
            id: 'notes',
            class: ['nicetext'],
            name: 'notes',
            placeholder: 'Notes about your changes'|t('app'),
            value: isCurrent ? (notes ?? null) : element.draftNotes,
            inputAttributes: {
                aria: {
                    label: 'Notes about your changes'|t('app'),
                },
            },
        }) }}
    {% endif %}
{% endblock %}

{% block settings %}
    {% if showStatusToggles and not isMultiSiteElement %}
        {{ forms.lightswitchField({
            status: element.getAttributeStatus('enabled'),
            label: 'Enabled'|t('app'),
            id: 'enabled',
            name: 'enabled',
            on: element.enabled,
            disabled: isRevision,
        }) }}
    {% endif %}
{% endblock %}

{# Only fetch the element’s per-site statuses if it’s enabled globally. Otherwise they don’t have any effect #}
{% if canEditMultipleSites and element.enabled and element.id %}
    {% set siteStatusesQuery = element.find()
        .select(['elements_sites.siteId', 'elements_sites.enabled'])
        .id(element.id)
        .siteId(propEditableSiteIds)
        .anyStatus()
        .asArray() %}
    {% if isProvisionalDraft %}
        {% do siteStatusesQuery.provisionalDrafts() %}
    {% elseif isDraft %}
        {% do siteStatusesQuery.drafts() %}
    {% elseif isRevision %}
        {% do siteStatusesQuery.revisions() %}
    {% endif %}
    {% set siteStatuses = siteStatusesQuery
        .pairs()|map(s => s ? true : false) %}
{% elseif canEditMultipleSites %}
    {% set siteStatusValues = {} %}
    {# If the element isn't saved yet, assume other sites will share its current status #}
    {% set defaultStatus = element.id ? false : (element.enabled and element.enabledForSite) %}
    {% for siteId in propEditableSiteIds %}
        {% set siteStatusValues = siteStatusValues|merge([defaultStatus]) %}
    {% endfor %}
    {% set siteStatuses = combine(propEditableSiteIds, siteStatusValues) %}
{% else %}
    {% set siteStatuses = {
        ("#{element.siteId}"): element.enabled ? true : false
    } %}
{% endif %}

{% set settings = {
    elementType: className(element),
    sourceId: element.getCanonicalId(),
    siteId: element.siteId,
    isUnpublishedDraft: isUnpublishedDraft,
    enabled: element.enabled ? true : false,
    enabledForSite: element.enabled and element.getEnabledForSite(),
    isLive: isCurrent and element.enabled and element.getEnabledForSite() and element.getRoute(),
    isProvisionalDraft: isProvisionalDraft,
    siteStatuses: siteStatuses,
    addlSites: addlEditableSites|values,
    cpEditUrl: element.cpEditUrl,
    draftId: element.draftId,
    revisionId: element.revisionId,
    draftName: isDraft ? element.draftName : null,
    canEditMultipleSites: canEditMultipleSites,
    canUpdateSource: canUpdateSource,
    saveDraftAction: saveDraftAction,
    deleteDraftAction: deleteDraftAction,
    publishDraftAction: publishDraftAction,
    hashedCpEditUrl: hashedCpEditUrl,
    hashedAddAnotherRedirectUrl: addAnotherRedirectUrl ? addAnotherRedirectUrl|hash : null,
    enablePreview: enablePreview,
    previewTargets: previewTargets,
    previewToken: previewTargets ? craft.app.security.generateRandomString() : null,
    siteToken: not element.getSite().enabled ? element.siteId|hash,
} %}
{% js %}
    window.draftEditor = new Craft.DraftEditor({{ settings|json_encode|raw }});
{% endjs %}
