<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/components/agenda/PausasChipsEditor.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, ref, watch } from 'vue';
import DatePicker from 'primevue/datepicker';
import { useToast } from 'primevue/usetoast';

const toast = useToast();

const props = defineProps({
    modelValue: { type: Array, default: () => [] } // [{id,label,inicio,fim}]
});
const emit = defineEmits(['update:modelValue']);

function isValidHHMM(v) {
    return /^\d{2}:\d{2}$/.test(String(v || '').trim());
}
function hhmmToMin(hhmm) {
    const [h, m] = String(hhmm).split(':').map(Number);
    return h * 60 + m;
}
function minToHHMM(min) {
    const h = Math.floor(min / 60) % 24;
    const m = min % 60;
    return String(h).padStart(2, '0') + ':' + String(m).padStart(2, '0');
}
function newId() {
    return Math.random().toString(16).slice(2) + Date.now().toString(16);
}
function hhmmToDate(hhmm) {
    if (!isValidHHMM(hhmm)) return null;
    const [h, m] = String(hhmm).split(':').map(Number);
    const d = new Date();
    d.setHours(h, m, 0, 0);
    return d;
}
function dateToHHMM(date) {
    if (!date || !(date instanceof Date)) return null;
    return String(date.getHours()).padStart(2, '0') + ':' + String(date.getMinutes()).padStart(2, '0');
}

const internal = ref([]);

watch(
    () => props.modelValue,
    (v) => {
        internal.value = (Array.isArray(v) ? v : []).map((p) => ({
            id: p.id || newId(),
            label: String(p.label || 'Pausa'),
            inicio: String(p.inicio || '').slice(0, 5),
            fim: String(p.fim || '').slice(0, 5)
        }));
    },
    { immediate: true, deep: true }
);

function pushUpdate(next) {
    // ordena por início
    const sorted = [...next].sort((a, b) => hhmmToMin(a.inicio) - hhmmToMin(b.inicio));
    internal.value = sorted;
    emit('update:modelValue', sorted);
}

// união de intervalos existentes
function normalizeIntervals(list) {
    const intervals = (list || []).map((p) => ({ s: hhmmToMin(p.inicio), e: hhmmToMin(p.fim) })).sort((a, b) => a.s - b.s);

    const merged = [];
    for (const it of intervals) {
        if (!merged.length) merged.push({ ...it });
        else {
            const last = merged[merged.length - 1];
            if (it.s <= last.e) last.e = Math.max(last.e, it.e);
            else merged.push({ ...it });
        }
    }
    return merged;
}

// retorna "sobras" de [s,e] depois de remover intervalos ocupados
function subtractIntervals(s, e, occupiedMerged) {
    let segments = [{ s, e }];
    for (const occ of occupiedMerged) {
        const next = [];
        for (const seg of segments) {
            // sem interseção
            if (seg.e <= occ.s || seg.s >= occ.e) {
                next.push(seg);
                continue;
            }
            // corta esquerda
            if (seg.s < occ.s) next.push({ s: seg.s, e: Math.min(occ.s, seg.e) });
            // corta direita
            if (seg.e > occ.e) next.push({ s: Math.max(occ.e, seg.s), e: seg.e });
        }
        segments = next;
        if (!segments.length) break;
    }
    // remove segmentos muito pequenos (0)
    return segments.filter((x) => x.e > x.s);
}

function addPauseSmart({ label, inicio, fim }) {
    if (!isValidHHMM(inicio) || !isValidHHMM(fim)) {
        toast.add({ severity: 'warn', summary: 'Atenção', detail: 'Horários devem estar em HH:MM.', life: 2200 });
        return;
    }
    if (fim <= inicio) {
        toast.add({ severity: 'warn', summary: 'Atenção', detail: 'O fim deve ser maior que o início.', life: 2200 });
        return;
    }

    const s = hhmmToMin(inicio);
    const e = hhmmToMin(fim);

    const occupied = normalizeIntervals(internal.value);
    const segments = subtractIntervals(s, e, occupied);

    if (!segments.length) {
        toast.add({ severity: 'info', summary: 'Nada a adicionar', detail: 'Esse período já está coberto por outra pausa.', life: 2400 });
        return;
    }

    const toAdd = segments.map((seg) => ({
        id: newId(),
        label: label || 'Pausa',
        inicio: minToHHMM(seg.s),
        fim: minToHHMM(seg.e)
    }));

    // se houve "recorte", avisa
    if (segments.length !== 1 || segments[0].s !== s || segments[0].e !== e) {
        toast.add({
            severity: 'info',
            summary: 'Ajuste automático',
            detail: 'Havia conflito com outra pausa; adicionei apenas o trecho que não sobrepõe.',
            life: 3200
        });
    }

    pushUpdate([...internal.value, ...toAdd]);
}

function removePause(id) {
    pushUpdate(internal.value.filter((p) => p.id !== id));
}

// ======================================================
// UI: presets + custom dialog
// ======================================================
const presets = [
    { label: 'Almoço', inicio: '12:00', fim: '13:00' },
    { label: 'Almoço', inicio: '13:00', fim: '14:00' },
    { label: 'Janta', inicio: '18:00', fim: '19:00' }
];

const dlg = ref(false);
const form = ref({ label: 'Pausa', inicio: null, fim: null });

const formInicioHHMM = computed(() => dateToHHMM(form.value.inicio));
const formFimHHMM = computed(() => dateToHHMM(form.value.fim));
const formValid = computed(() => isValidHHMM(formInicioHHMM.value) && isValidHHMM(formFimHHMM.value) && formFimHHMM.value > formInicioHHMM.value);

function openCustom() {
    form.value = { label: 'Pausa', inicio: hhmmToDate('12:00'), fim: hhmmToDate('13:00') };
    dlg.value = true;
}
function saveCustom() {
    addPauseSmart({ label: form.value.label, inicio: formInicioHHMM.value, fim: formFimHHMM.value });
    dlg.value = false;
}
</script>

<template>
    <div class="space-y-2">
        <!-- actions -->
        <div class="flex flex-wrap gap-2 items-center">
            <Button v-for="(p, idx) in presets" :key="'pre_' + idx" size="small" severity="secondary" outlined icon="pi pi-plus" :label="`${p.label} (${p.inicio}–${p.fim})`" @click="addPauseSmart(p)" />
            <Button size="small" icon="pi pi-sliders-h" label="Customizar" @click="openCustom" />
        </div>

        <Divider class="my-2" />

        <!-- chips/badges -->
        <div v-if="!internal.length" class="text-600 text-sm">Nenhuma pausa adicionada.</div>

        <div v-else class="flex flex-wrap gap-2">
            <div v-for="p in internal" :key="p.id" class="inline-flex items-center gap-2 rounded-full border border-[var(--surface-border)] bg-[var(--surface-card)] px-3 py-1">
                <Tag :value="p.label" severity="secondary" />
                <span class="text-600 text-sm">{{ p.inicio }}–{{ p.fim }}</span>
                <Button icon="pi pi-times" text rounded severity="danger" @click="removePause(p.id)" />
            </div>
        </div>

        <!-- custom dialog -->
        <Dialog v-model:visible="dlg" modal :draggable="false" header="Adicionar pausa" :style="{ width: '420px' }">
            <div class="flex flex-col gap-4">
                <div>
                    <label class="text-xs text-[var(--text-color-secondary)] mb-1 block">Nome</label>
                    <InputText v-model="form.label" class="w-full" placeholder="Ex.: Almoço" />
                </div>

                <div class="flex gap-3">
                    <div class="flex-1 flex flex-col gap-1">
                        <label class="text-xs text-[var(--text-color-secondary)]">Início</label>
                        <DatePicker v-model="form.inicio" showIcon fluid iconDisplay="input" timeOnly hourFormat="24" :stepMinute="15" :manualInput="false">
                            <template #inputicon="slotProps">
                                <i class="pi pi-clock" @click="slotProps.clickCallback" />
                            </template>
                        </DatePicker>
                    </div>
                    <div class="flex-1 flex flex-col gap-1">
                        <label class="text-xs text-[var(--text-color-secondary)]">Fim</label>
                        <DatePicker v-model="form.fim" showIcon fluid iconDisplay="input" timeOnly hourFormat="24" :stepMinute="15" :manualInput="false">
                            <template #inputicon="slotProps">
                                <i class="pi pi-clock" @click="slotProps.clickCallback" />
                            </template>
                        </DatePicker>
                    </div>
                </div>

                <div v-if="formInicioHHMM && formFimHHMM && formFimHHMM <= formInicioHHMM" class="text-sm text-red-500">O fim precisa ser maior que o início.</div>

                <div class="text-[var(--text-color-secondary)] text-xs">Se houver conflito com outra pausa, o sistema adiciona apenas o trecho que não sobrepõe.</div>
            </div>

            <template #footer>
                <Button label="Cancelar" icon="pi pi-times" severity="secondary" outlined @click="dlg = false" />
                <Button label="Adicionar" icon="pi pi-check" :disabled="!formValid" @click="saveCustom" />
            </template>
        </Dialog>
    </div>
</template>
