<template>
    <div>
        <h2 class="bm-admin__title">Fields</h2>

        <div v-if="autoFields.length === 0 && customFields.length === 0" class="bm-rail-empty">
            Add elements to the canvas to manage fields.
        </div>

        <ol v-else class="bm-fields-list">
            <li
                v-for="(row, idx) in mergedRows"
                :key="row.key"
                class="bm-fields-row"
            >
                <span class="bm-fields-row__source" :title="row.source">
                    {{ row.source === 'custom' ? '+' : '◆' }}
                </span>
                <input
                    v-if="row.source === 'auto'"
                    type="text"
                    class="bm-fields-row__rename"
                    :value="displayName(row)"
                    :placeholder="row.auto"
                    @change="setRename(row.auto, $event.target.value)"
                />
                <span v-else class="bm-fields-row__name">{{ row.name }}</span>
                <span class="bm-fields-row__type">{{ row.type }}</span>
                <label class="bm-fields-row__required">
                    <input
                        type="checkbox"
                        :checked="isRequired(row)"
                        @change="setRequired(row, $event.target.checked)"
                    />
                    required
                </label>
                <button
                    type="button"
                    class="bm-fields-row__btn"
                    :disabled="idx === 0"
                    @click="moveUp(idx)"
                >↑</button>
                <button
                    type="button"
                    class="bm-fields-row__btn"
                    :disabled="idx === mergedRows.length - 1"
                    @click="moveDown(idx)"
                >↓</button>
                <button
                    v-if="row.source === 'custom'"
                    type="button"
                    class="bm-fields-row__btn bm-fields-row__btn--danger"
                    @click="removeCustom(row.name)"
                >✕</button>
            </li>
        </ol>

        <div class="bm-rail-actions">
            <button type="button" class="bm-rail-action" @click="addCustomField">
                + Add custom field
            </button>
        </div>

        <div v-if="repeaters.length > 0" class="bm-fields-repeaters">
            <h3 class="bm-rail-subtitle">Repeaters</h3>
            <ul>
                <li v-for="rep in repeaters" :key="rep.name" class="bm-fields-repeater">
                    <strong>{{ rep.name }}</strong>
                    <span class="bm-fields-repeater__meta">
                        {{ (rep.instance_ids || []).length }} instances grouped
                    </span>
                    <button type="button" class="bm-fields-row__btn bm-fields-row__btn--danger" @click="removeRepeater(rep.name)">
                        ungroup
                    </button>
                </li>
            </ul>
        </div>
    </div>
</template>

<script>
export default {
    name: 'FieldsPanel',
    props: {
        // Active canvas instances
        instances: { type: Array, required: true },
        // Loaded element manifests (used to derive auto field names)
        elementManifests: { type: Array, required: true },
        // Current fields_panel state
        panel: { type: Object, required: true },
    },
    computed: {
        manifestByType() {
            const out = {};
            for (const m of this.elementManifests) out[m.type] = m;
            return out;
        },
        autoFields() {
            const taken = {};
            const out = [];
            for (const inst of this.instances) {
                const manifest = this.manifestByType[inst.element_type];
                if (!manifest) continue;
                const base = inst.field_name || inst.element_type || 'field';
                for (const input of (manifest.inputs || [])) {
                    let candidate = `${base}_${input.name}`;
                    let n = 2;
                    while (taken[candidate]) candidate = `${base}_${input.name}_${n++}`;
                    taken[candidate] = true;
                    out.push({
                        source: 'auto',
                        auto: candidate,
                        name: this.panel.renames?.[candidate] || candidate,
                        type: input.type,
                        required: input.required || false,
                    });
                }
            }
            return out;
        },
        customFields() {
            return (this.panel.custom || []).map((c) => ({
                source: 'custom',
                name: c.name,
                type: c.type || 'text',
                required: c.required || false,
            }));
        },
        repeaters() {
            return this.panel.repeaters || [];
        },
        mergedRows() {
            const auto = this.autoFields.map((f) => ({ ...f, key: `auto:${f.auto}` }));
            const custom = this.customFields.map((f) => ({ ...f, key: `custom:${f.name}` }));
            const combined = [...auto, ...custom];

            const order = this.panel.order || [];
            if (order.length === 0) return combined;

            const byName = new Map(combined.map((r) => [r.name, r]));
            const out = [];
            for (const name of order) {
                if (byName.has(name)) {
                    out.push(byName.get(name));
                    byName.delete(name);
                }
            }
            for (const remaining of byName.values()) out.push(remaining);
            return out;
        },
    },
    methods: {
        displayName(row) {
            return row.name;
        },
        isRequired(row) {
            const overrides = this.panel.required || {};
            if (Object.prototype.hasOwnProperty.call(overrides, row.name)) {
                return !!overrides[row.name];
            }
            return !!row.required;
        },
        setRename(autoName, userName) {
            const renames = { ...(this.panel.renames || {}) };
            if (!userName || userName === autoName) {
                delete renames[autoName];
            } else {
                renames[autoName] = userName;
            }
            this.emitPanel({ renames });
        },
        setRequired(row, value) {
            const required = { ...(this.panel.required || {}) };
            required[row.name] = value;
            this.emitPanel({ required });
        },
        moveUp(idx) {
            if (idx <= 0) return;
            const order = this.mergedRows.map((r) => r.name);
            [order[idx - 1], order[idx]] = [order[idx], order[idx - 1]];
            this.emitPanel({ order });
        },
        moveDown(idx) {
            if (idx >= this.mergedRows.length - 1) return;
            const order = this.mergedRows.map((r) => r.name);
            [order[idx], order[idx + 1]] = [order[idx + 1], order[idx]];
            this.emitPanel({ order });
        },
        addCustomField() {
            const name = window.prompt('Field name (e.g. section_toggle)');
            if (!name) return;
            const type = window.prompt('Field type (text / textarea / checkbox / link / image / select)', 'text') || 'text';
            const custom = [
                ...(this.panel.custom || []),
                { name, label: name, type, required: false },
            ];
            this.emitPanel({ custom });
        },
        removeCustom(name) {
            const custom = (this.panel.custom || []).filter((c) => c.name !== name);
            this.emitPanel({ custom });
        },
        removeRepeater(name) {
            const repeaters = (this.panel.repeaters || []).filter((r) => r.name !== name);
            this.emitPanel({ repeaters });
        },
        emitPanel(partial) {
            this.$emit('input', { ...this.panel, ...partial });
        },
    },
};
</script>
