-- allium: 1
-- bDS Template Editor View
-- Scope: UI content area — template editing surface
-- Distilled from: TemplateEditor.tsx

-- Describes the layout and behaviour of the template editor.
-- See template.allium for entity model and Liquid subset.

use "./template.allium" as template
use "./i18n.allium" as i18n

-- ─── Template editor view ─────────────────────────────────────

value TemplateEditorView {
    template_id: String
    title: String                       -- editable text input
    slug: String                        -- editable text input, auto-generated from title
    kind: String                        -- select: post | list | not_found | partial
    enabled: Boolean                    -- checkbox
    content: String                     -- code editor content
    can_publish: Boolean                -- true while status = draft
    created_at: String                  -- locale-formatted date
    updated_at: String                  -- locale-formatted date
}

surface TemplateEditorSurface {
    context editor: TemplateEditorView

    exposes:
        editor.title
        editor.slug
        editor.kind
        editor.enabled
        editor.created_at
        editor.updated_at

    provides:
        TemplateSaveRequested(editor.template_id)
        TemplatePublishRequested(editor.template_id)
            when editor.can_publish
        TemplateValidateRequested(editor.template_id)
        TemplateDeleteRequested(editor.template_id)
        TemplateDeleteConfirmed(editor.template_id)
        TemplateForceDeleteConfirmed(editor.template_id)

    @guarantee HeaderLayout
        -- Header bar with template title tab.
        -- Actions (right side): Save button, Publish button (shown only when
        --   can_publish, i.e. status = draft), Validate button,
        --   Delete button (danger style).

    @guarantee MetadataRow
        -- Two rows of metadata fields above the editor.
        -- Row 1: Title (text input), Slug (text input, auto-generated from title).
        -- Row 2: Kind (select: post/list/not-found/partial), Enabled (checkbox).

    @guarantee EditorBody
        -- Code editor with HTML/Liquid syntax highlighting.
        -- Toolbar: "Content" label.
        -- Syntax errors shown inline in editor on validation.

    @guarantee FooterLayout
        -- Created date and Updated date, locale-formatted.
}

-- ─── Template editor actions ────────────────────────────────

rule TemplateSave {
    when: TemplateSaveRequested(template_id)
    let target = template/Template{id: template_id}
    let validation = ValidateLiquid(editor_content(template_id))
        -- editor_content: the current code editor buffer
    ensures:
        if validation = valid:
            UpdateTemplateRequested(target, editor_field_changes(template_id))
            -- Version bump + DB write + .liquid rewrite:
            -- template.allium UpdateTemplate,
            -- engine_side_effects.allium UpdateTemplateSideEffects
        else:
            TemplateValidationErrorsShown(template_id, validation)
            -- Save blocked; errors shown inline in the editor
}

rule TemplatePublish {
    when: TemplatePublishRequested(template_id)
    let target = template/Template{id: template_id}
    requires: target.status = draft
        -- can_publish gate on the button
    let validation = ValidateLiquid(editor_content(template_id))
    ensures:
        if validation = valid:
            UpdateTemplateRequested(target, editor_field_changes(template_id))
            PublishTemplateRequested(target)
            -- status -> published + .liquid file write:
            -- template.allium PublishTemplate
        else:
            TemplateValidationErrorsShown(template_id, validation)
}

rule TemplateValidate {
    when: TemplateValidateRequested(template_id)
    -- Validation only, never saves
    let validation = ValidateLiquid(editor_content(template_id))
    ensures:
        if validation = valid:
            TemplateValidationOkShown(template_id)
            -- toast / status indicator
        else:
            TemplateValidationErrorsShown(template_id, validation)
}

rule TemplateDelete {
    when: TemplateDeleteRequested(template_id)
    let target = template/Template{id: template_id}
    let references = target.referencing_posts.count + target.referencing_tags.count
    ensures:
        if references > 0:
            TemplateForceDeleteConfirmShown(template_id)
            -- system confirm dialog: "This template is used by N posts
            -- and M tags. Force delete?" (action_patterns.allium
            -- confirmation_assignments: template_delete_with_references)
        else:
            ConfirmDeleteModalOpened(template_id)
            -- custom modal (not a native dialog): template title, no
            -- reference list; Cancel + Delete (destructive red style)
            -- — action_patterns.allium
            -- confirmation_assignments: template_delete
}

rule TemplateDeleteExecute {
    when: TemplateDeleteConfirmed(template_id)
    let target = template/Template{id: template_id}
    ensures: DeleteTemplateRequested(target)
        -- DB record + .liquid file on disk
    ensures: closeTab(template_id)
        -- sidebar removes the item reactively
}

rule TemplateForceDelete {
    when: TemplateForceDeleteConfirmed(template_id)
    let target = template/Template{id: template_id}
    -- Clear references first so template.allium DeleteTemplate's
    -- zero-reference precondition holds:
    for p in target.referencing_posts:
        ensures: p.template_slug = null
    for t in target.referencing_tags:
        ensures: t.post_template_slug = null
    ensures: DeleteTemplateRequested(target)
        -- DB record + .liquid file on disk
    ensures: closeTab(template_id)
        -- sidebar removes the item reactively
}
