<template>
    <div class="afb">
        <template v-for="(group, gIdx) in modelValue.groups" :key="gIdx">
            <div v-if="gIdx > 0" class="afb-or-divider"><span>OR</span></div>

            <div class="afb-group">
                <div v-for="(cond, cIdx) in group.conditions" :key="cIdx" class="afb-row">
                    <div class="afb-field-wrap">
                        <button type="button" class="afb-field-btn" @click="toggleMenu(gIdx, cIdx)">
                            {{ fieldLabel(cond.field) || 'Select field…' }}
                        </button>
                        <AdvancedFilterFieldMenu
                            v-if="openMenuKey === key(gIdx, cIdx)"
                            :menu="menu"
                            :campaigns="campaigns"
                            :automations="automations"
                            @select="(payload) => applyFieldSelection(gIdx, cIdx, payload)"
                        />
                    </div>

                    <template v-if="cond.field">
                        <select v-model="cond.operator" class="afb-operator">
                            <option v-for="op in operatorsFor(cond.field)" :key="op" :value="op">{{ operatorLabel(op) }}</option>
                        </select>

                        <!-- string / date -->
                        <input
                            v-if="needsSimpleValue(cond) && (defFor(cond.field)?.type === 'string')"
                            v-model="cond.value"
                            type="text"
                            class="afb-value-input"
                            placeholder="Value"
                        >
                        <input
                            v-else-if="needsSimpleValue(cond) && defFor(cond.field)?.type === 'date' && cond.operator !== 'between'"
                            v-model="cond.value"
                            type="date"
                            class="afb-value-input"
                        >
                        <div v-else-if="needsSimpleValue(cond) && defFor(cond.field)?.type === 'date' && cond.operator === 'between'" class="afb-date-range">
                            <input type="date" class="afb-value-input" :value="cond.value?.[0]" @input="setBetween(cond, 0, $event.target.value)">
                            <span>–</span>
                            <input type="date" class="afb-value-input" :value="cond.value?.[1]" @input="setBetween(cond, 1, $event.target.value)">
                        </div>

                        <!-- activity: within/not within N days -->
                        <div v-else-if="defFor(cond.field)?.type === 'activity' && cond.operator !== 'never'" class="afb-days-input">
                            <input v-model.number="cond.value" type="number" min="0" class="afb-value-input afb-value-input--num">
                            <span>days</span>
                        </div>

                        <!-- enum: single -->
                        <select v-else-if="defFor(cond.field)?.type === 'enum' && ['is', 'is_not'].includes(cond.operator)" v-model="cond.value" class="afb-value-input">
                            <option value="" disabled>Select…</option>
                            <option v-for="opt in defFor(cond.field)?.allowed" :key="opt" :value="opt">{{ opt }}</option>
                        </select>

                        <!-- enum: multi -->
                        <div v-else-if="defFor(cond.field)?.type === 'enum'" class="afb-checklist">
                            <label v-for="opt in defFor(cond.field)?.allowed" :key="opt" class="afb-check">
                                <input type="checkbox" :checked="(cond.value || []).includes(opt)" @change="toggleArrayValue(cond, opt)">
                                {{ opt }}
                            </label>
                        </div>

                        <!-- relation: tags/lists -->
                        <div v-else-if="defFor(cond.field)?.type === 'relation'" class="afb-checklist afb-checklist--scroll">
                            <label v-for="opt in relationOptions(cond.field)" :key="opt.id" class="afb-check">
                                <input type="checkbox" :checked="(cond.value || []).includes(opt.id)" @change="toggleArrayValue(cond, opt.id)">
                                {{ opt.title }}
                            </label>
                            <div v-if="relationOptions(cond.field).length === 0" class="afb-empty-hint">None yet.</div>
                        </div>
                    </template>

                    <button type="button" class="afb-remove" aria-label="Remove condition" @click="removeCondition(gIdx, cIdx)">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="14" height="14"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
                    </button>
                </div>

                <button type="button" class="afb-add-btn" @click="addCondition(gIdx)">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="12" height="12"><path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"/></svg>
                    Add
                </button>
            </div>
        </template>

        <div class="afb-or-row">
            <button type="button" class="afb-or-btn" @click="addGroup">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="12" height="12"><path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"/></svg>
                OR
            </button>
        </div>

        <div class="afb-footer">
            <button type="button" class="afb-clear-btn" @click="clear">Clear Filters</button>
            <button type="button" class="afb-filter-btn" :disabled="!isValid" @click="applyFilter">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="13" height="13"><path fill-rule="evenodd" d="M2.628 1.601C5.028 1.206 7.49 1 10 1s4.973.206 7.372.601a.75.75 0 01.628.74v2.288a2.25 2.25 0 01-.659 1.59l-4.682 4.683a2.25 2.25 0 00-.659 1.59v3.037c0 .684-.31 1.33-.844 1.757l-1.937 1.55A.75.75 0 018 18.25v-5.757a2.25 2.25 0 00-.659-1.591L2.659 6.22A2.25 2.25 0 012 4.629V2.34a.75.75 0 01.628-.74z" clip-rule="evenodd"/></svg>
                Filter
            </button>
        </div>
    </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
import AdvancedFilterFieldMenu from '@/Components/AdvancedFilterFieldMenu.vue';

const props = defineProps({
    modelValue: { type: Object, required: true },
    menu: { type: Array, default: () => [] },
    lists: { type: Array, default: () => [] },
    tags: { type: Array, default: () => [] },
    campaigns: { type: Array, default: () => [] },
    automations: { type: Array, default: () => [] },
});

const emit = defineEmits(['update:modelValue', 'apply']);

const openMenuKey = ref(null);
const key = (g, c) => `${g}:${c}`;

function applyFilter() {
    emit('apply');
}

// Close the field-picker popover on outside click, same pattern as CwSelect.
function handleClickOutside(e) {
    if (openMenuKey.value !== null && !e.target.closest('.afb-field-wrap')) {
        openMenuKey.value = null;
    }
}

onMounted(() => document.addEventListener('click', handleClickOutside));
onBeforeUnmount(() => document.removeEventListener('click', handleClickOutside));

const fieldsByKey = computed(() => {
    const map = {};
    for (const cat of props.menu) {
        for (const f of cat.fields) map[f.key] = f;
        for (const grp of cat.groups) for (const f of grp.fields) map[f.key] = f;
    }
    return map;
});

function defFor(fieldKey) {
    return fieldsByKey.value[fieldKey] || null;
}

function fieldLabel(fieldKey) {
    return defFor(fieldKey)?.label || '';
}

function operatorsFor(fieldKey) {
    return defFor(fieldKey)?.operators || [];
}

function operatorLabel(op) {
    return op.replace(/_/g, ' ');
}

function needsSimpleValue(cond) {
    return !['is_empty', 'is_not_empty', 'never'].includes(cond.operator);
}

function relationOptions(fieldKey) {
    return fieldKey === 'segment.tags' ? props.tags : props.lists;
}

function toggleMenu(g, c) {
    openMenuKey.value = openMenuKey.value === key(g, c) ? null : key(g, c);
}

function applyFieldSelection(g, c, payload) {
    const cond = props.modelValue.groups[g].conditions[c];
    Object.assign(cond, { field: payload.field, operator: payload.operator, value: payload.value });
    delete cond.campaign_id;
    delete cond.automation_id;
    if (payload.campaign_id) cond.campaign_id = payload.campaign_id;
    if (payload.automation_id) cond.automation_id = payload.automation_id;
    openMenuKey.value = null;
    emitUpdate();
}

function toggleArrayValue(cond, value) {
    const current = Array.isArray(cond.value) ? [...cond.value] : [];
    const idx = current.indexOf(value);
    if (idx === -1) current.push(value); else current.splice(idx, 1);
    cond.value = current;
    emitUpdate();
}

function setBetween(cond, idx, value) {
    const current = Array.isArray(cond.value) ? [...cond.value] : [null, null];
    current[idx] = value;
    cond.value = current;
    emitUpdate();
}

function addCondition(gIdx) {
    props.modelValue.groups[gIdx].conditions.push({ field: null, operator: null, value: null });
    emitUpdate();
}

function removeCondition(gIdx, cIdx) {
    props.modelValue.groups[gIdx].conditions.splice(cIdx, 1);
    if (props.modelValue.groups[gIdx].conditions.length === 0 && props.modelValue.groups.length > 1) {
        props.modelValue.groups.splice(gIdx, 1);
    }
    emitUpdate();
}

function addGroup() {
    props.modelValue.groups.push({ conditions: [{ field: null, operator: null, value: null }] });
    emitUpdate();
}

function clear() {
    props.modelValue.groups.splice(0, props.modelValue.groups.length, { conditions: [{ field: null, operator: null, value: null }] });
    emitUpdate();
}

function emitUpdate() {
    emit('update:modelValue', props.modelValue);
}

// Whether every condition in every group is complete enough to submit -
// lets the parent avoid firing a count/save request against a filter the
// user is still mid-way through building.
const isValid = computed(() => {
    const groups = props.modelValue.groups || [];
    if (groups.length === 0) return false;

    return groups.every(group => {
        const conditions = group.conditions || [];
        if (conditions.length === 0) return false;

        return conditions.every(cond => {
            if (!cond.field || !cond.operator) return false;
            if (!needsSimpleValue(cond)) return true;

            const def = defFor(cond.field);
            if (!def) return false;

            if (def.type === 'campaign_activity') return !!cond.campaign_id;
            if (def.type === 'automation_activity') return !!cond.automation_id;
            if (def.type === 'date' && cond.operator === 'between') return Array.isArray(cond.value) && cond.value[0] && cond.value[1];
            if (def.type === 'enum' && ['is_any_of', 'is_none_of'].includes(cond.operator)) return Array.isArray(cond.value) && cond.value.length > 0;
            if (def.type === 'relation') return Array.isArray(cond.value) && cond.value.length > 0;

            return cond.value !== null && cond.value !== '' && cond.value !== undefined;
        });
    });
});

defineExpose({ isValid });
</script>

<style scoped>
.afb, .afb *, .afb *::before, .afb *::after { box-sizing: border-box; }
.afb { display: flex; flex-direction: column; gap: 10px; max-width: 100%; padding: 18px 20px 20px; }

.afb-or-divider {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 4px 0;
}
.afb-or-divider span {
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
    background: var(--bg-hover);
    padding: 2px 10px;
    border-radius: 999px;
    border: 1px solid var(--border-color);
}

.afb-group {
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: var(--bg-hover);
    max-width: 100%;
    transition: border-color 0.15s;
}
.afb-group:hover { border-color: var(--text-muted); }

.afb-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    max-width: 100%;
}

.afb-field-wrap { position: relative; flex: 0 1 auto; }

.afb-field-btn {
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--bg-surface);
    font-size: 12.5px;
    color: var(--text-primary);
    cursor: pointer;
    width: 160px;
    max-width: 100%;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.afb-field-btn:hover { border-color: var(--text-muted); }
.afb-field-btn:focus-visible { outline: none; border-color: var(--info); box-shadow: 0 0 0 3px rgba(66, 133, 244, 0.12); }

.afb-operator {
    height: 34px;
    padding: 0 8px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    font-size: 12.5px;
    color: var(--text-primary);
    background: var(--bg-surface);
    text-transform: capitalize;
    flex: 0 1 130px;
    min-width: 0;
    max-width: 100%;
}

.afb-value-input {
    height: 34px;
    padding: 0 8px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    font-size: 12.5px;
    color: var(--text-primary);
    background: var(--bg-surface);
    flex: 1 1 160px;
    min-width: 0;
    max-width: 100%;
}
.afb-value-input--num { flex: 0 1 70px; width: 70px; }

.afb-date-range, .afb-days-input {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
}

.afb-checklist {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    padding: 6px 8px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--bg-surface);
    flex: 1 1 220px;
    max-width: 100%;
}
.afb-checklist--scroll { max-height: 100px; overflow-y: auto; }
.afb-check { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-secondary); text-transform: capitalize; white-space: nowrap; }
.afb-empty-hint { font-size: 12px; color: var(--text-muted); }

.afb-remove {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 6px;
}
.afb-remove:hover { background: var(--danger-light); color: var(--danger); }

.afb-add-btn {
    align-self: flex-start;
    display: flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: 1px dashed var(--border-color);
    border-radius: 6px;
    padding: 5px 10px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    cursor: pointer;
}
.afb-add-btn:hover { border-color: var(--text-muted); color: var(--text-primary); }

.afb-or-row {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2px 0;
}

.afb-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 8px;
    padding-top: 14px;
    border-top: 1px solid var(--border-color);
    flex-wrap: wrap;
}

.afb-or-btn {
    display: flex;
    align-items: center;
    gap: 4px;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    padding: 6px 16px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary);
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.afb-or-btn:hover { border-color: var(--text-muted); color: var(--text-primary); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); }

.afb-clear-btn {
    background: none;
    border: none;
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
}
.afb-clear-btn:hover { color: var(--danger); }

.afb-filter-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--info);
    border: 1px solid var(--info);
    border-radius: 6px;
    padding: 8px 18px;
    font-size: 12.5px;
    font-weight: 600;
    color: #fff;
    cursor: pointer;
    transition: background 0.15s, box-shadow 0.15s;
}
.afb-filter-btn:hover:not(:disabled) { background: #3b82f6; box-shadow: 0 2px 8px rgba(37, 99, 235, 0.35); }
.afb-filter-btn:disabled { background: var(--border-color); border-color: var(--border-color); color: var(--text-muted); cursor: not-allowed; }
</style>
