/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/features/agenda/composables/useAgendaStatusChange.js
|
| Composable Tipo A que orquestra o fluxo de status change da agenda
| usando agendaBilling.service. Reusável em Melissa / Rail / Clínica.
|
| Uso:
|   const { applyStatusChange, dialogOpen, dialogProps, onDialogConfirm,
|           onDialogCancel } = useAgendaStatusChange({ toast });
|
|   // No handler:
|   await applyStatusChange({ eventoId, row, novoStatus });
|
|   // No template:
|   <AgendaStatusChangeConfirmDialog
|     v-model="dialogOpen"
|     :evento="dialogProps.evento"
|     :novoStatus="dialogProps.novoStatus"
|     :regraExcecao="dialogProps.regraExcecao"
|     :billingContract="dialogProps.billingContract"
|     :billingContractStyle="dialogProps.billingContractStyle"
|     :pendingRecord="dialogProps.pendingRecord"
|     :sessionPrice="dialogProps.sessionPrice"
|     @confirm="onDialogConfirm"
|     @update:modelValue="(v) => !v && onDialogCancel()"
|   />
|--------------------------------------------------------------------------
*/

import { ref } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { useTenantStore } from '@/stores/tenantStore';
import {
    loadStatusChangeContext,
    needsStatusConfirmDialog,
    applyStatusDecisions
} from '@/features/agenda/services/agendaBilling.service';

/**
 * @param {object} [opts]
 * @param {object} [opts.toast]   instância de useToast (PrimeVue). Opcional.
 * @returns composable com state reativo + applyStatusChange
 */
export function useAgendaStatusChange({ toast = null } = {}) {
    const tenantStore = useTenantStore();

    // Dialog state — bindar no template
    const dialogOpen = ref(false);
    const dialogProps = ref({});
    let _resolveDialog = null;

    function _openDialog(propsObj) {
        return new Promise((resolve) => {
            dialogProps.value = propsObj;
            dialogOpen.value = true;
            _resolveDialog = resolve;
        });
    }

    function onDialogConfirm(decision) {
        if (_resolveDialog) _resolveDialog(decision);
        _resolveDialog = null;
        dialogOpen.value = false;
    }

    function onDialogCancel() {
        if (_resolveDialog) _resolveDialog(null);
        _resolveDialog = null;
        dialogOpen.value = false;
    }

    /**
     * Coordena: load context → mostra dialog se preciso → aplica decisões.
     *
     * @param {object} args
     * @param {string} args.eventoId   uuid (null pra ocorrências virtuais ainda)
     * @param {object} args.row        row do agenda_eventos (pode ser parcial)
     * @param {string} args.novoStatus 'realizado' | 'faltou' | 'cancelado' | 'agendado'
     *
     * @returns {Promise<{ applied: boolean, decision: object|null, ctx: object }>}
     *          applied=true se passou pelo applyStatusDecisions.
     *          decision=null se user cancelou o dialog.
     */
    async function applyStatusChange({ eventoId, row, novoStatus }) {
        const ownerId = (await supabase.auth.getUser()).data?.user?.id || null;
        const tenantId = tenantStore.activeTenantId || tenantStore.tenantId || tenantStore.tenant?.id || null;

        // 1) Carrega contexto
        const ctx = await loadStatusChangeContext({
            supabase,
            row,
            eventoId,
            status: novoStatus,
            ownerId,
            tenantId
        });

        // 2) Dialog se preciso
        let decision = null;
        if (needsStatusConfirmDialog(novoStatus, ctx)) {
            decision = await _openDialog({
                evento: row,
                novoStatus,
                regraExcecao: ctx.regraExcecao,
                billingContract: ctx.billingContract,
                billingContractStyle: ctx.billingContract?.charging_style || null,
                pendingRecord: ctx.pendingRecord,
                sessionPrice: row?.price ?? null
            });
            if (!decision) {
                // user cancelou
                return { applied: false, decision: null, ctx };
            }
        } else {
            // Sem dialog — default decision vazia (só aplicar status change básico)
            decision = {};
        }

        // 3) Aplica decisões
        await applyStatusDecisions({
            supabase,
            toast,
            eventoId,
            row,
            novoStatus,
            ctx,
            decision,
            ownerId,
            tenantId
        });

        return { applied: true, decision, ctx };
    }

    return {
        // dialog state — pra template
        dialogOpen,
        dialogProps,
        onDialogConfirm,
        onDialogCancel,
        // main action
        applyStatusChange
    };
}
