/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/stores/twilioWhatsappStore.js
| Data: 2026
|--------------------------------------------------------------------------
| Pinia store para gerenciamento de subcontas Twilio WhatsApp.
| Usado tanto pelo painel SaaS admin quanto pelo self-service do tenant.
|--------------------------------------------------------------------------
*/

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import * as service from '@/services/twilioWhatsappService'

export const useTwilioWhatsappStore = defineStore('twilioWhatsapp', () => {
    // ── Estado ─────────────────────────────────────────────────────────

    // Admin: lista de todos os canais
    const allChannels     = ref([])
    const loadingChannels = ref(false)

    // Tenant self-service: canal do tenant atual
    const myChannel     = ref(null)
    const loadingMyChannel = ref(false)

    // Operações em andamento
    const provisioning  = ref(false)
    const deprovisioning = ref(false)
    const suspending    = ref(false)
    const reactivating  = ref(false)
    const syncingUsage  = ref(false)
    const testingSend   = ref(false)

    // Logs de mensagens (self-service)
    const messageLogs     = ref([])
    const loadingLogs     = ref(false)

    // Dados de uso (admin)
    const usageReport     = ref([])
    const loadingUsage    = ref(false)

    // Números disponíveis para compra
    const availableNumbers = ref([])
    const loadingNumbers   = ref(false)

    // Erros
    const lastError = ref(null)

    // ── Computed ───────────────────────────────────────────────────────

    const hasActiveChannel = computed(() => !!myChannel.value?.twilio_subaccount_sid && myChannel.value?.is_active)

    const myChannelStatus = computed(() => {
        if (!myChannel.value) return 'not_provisioned'
        if (!myChannel.value.twilio_subaccount_sid) return 'not_provisioned'
        if (!myChannel.value.is_active) return 'suspended'
        return myChannel.value.connection_status ?? 'connected'
    })

    const totalMonthlyCostBrl = computed(() =>
        allChannels.value.reduce((sum, ch) => sum + parseFloat(ch.current_month_cost_brl ?? 0), 0)
    )

    const totalMonthlyRevenueBrl = computed(() =>
        allChannels.value.reduce((sum, ch) => sum + parseFloat(ch.current_month_revenue_brl ?? 0), 0)
    )

    const totalMonthlyMarginBrl = computed(() => totalMonthlyRevenueBrl.value - totalMonthlyCostBrl.value)

    const activeCount    = computed(() => allChannels.value.filter(ch => ch.is_active).length)
    const suspendedCount = computed(() => allChannels.value.filter(ch => !ch.is_active && ch.twilio_subaccount_sid).length)

    // ── Ações Admin ────────────────────────────────────────────────────

    async function loadAllChannels() {
        loadingChannels.value = true
        lastError.value = null
        try {
            allChannels.value = await service.getAllChannels()
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            loadingChannels.value = false
        }
    }

    async function provision(tenantId, options = {}) {
        provisioning.value = true
        lastError.value = null
        try {
            const result = await service.provisionTenant(tenantId, options)
            await loadAllChannels()
            return result
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            provisioning.value = false
        }
    }

    async function deprovision(channelId) {
        deprovisioning.value = true
        lastError.value = null
        try {
            const result = await service.deprovisionTenant(channelId)
            await loadAllChannels()
            return result
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            deprovisioning.value = false
        }
    }

    async function suspend(channelId) {
        suspending.value = true
        lastError.value = null
        try {
            const result = await service.suspendTenant(channelId)
            const ch = allChannels.value.find(c => c.channel_id === channelId)
            if (ch) {
                ch.is_active         = false
                ch.connection_status = 'disconnected'
            }
            return result
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            suspending.value = false
        }
    }

    async function reactivate(channelId) {
        reactivating.value = true
        lastError.value = null
        try {
            const result = await service.reactivateTenant(channelId)
            const ch = allChannels.value.find(c => c.channel_id === channelId)
            if (ch) {
                ch.is_active         = true
                ch.connection_status = 'connected'
            }
            return result
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            reactivating.value = false
        }
    }

    async function syncUsageAll(channelId = null) {
        syncingUsage.value = true
        lastError.value = null
        try {
            const result = await service.syncUsage(channelId)
            await loadAllChannels()
            return result
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            syncingUsage.value = false
        }
    }

    async function loadUsageReport(filters = {}) {
        loadingUsage.value = true
        lastError.value = null
        try {
            usageReport.value = await service.getUsageReport(filters)
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            loadingUsage.value = false
        }
    }

    async function updatePricing(channelId, pricing) {
        lastError.value = null
        try {
            const updated = await service.updatePricing(channelId, pricing)
            const ch = allChannels.value.find(c => c.channel_id === channelId)
            if (ch) {
                ch.cost_per_message_usd  = updated.cost_per_message_usd
                ch.price_per_message_brl = updated.price_per_message_brl
            }
            return updated
        } catch (e) {
            lastError.value = e.message
            throw e
        }
    }

    async function loadAvailableNumbers(country = 'BR', areaCode = null) {
        loadingNumbers.value = true
        lastError.value = null
        try {
            const result = await service.searchNumbers(country, areaCode)
            availableNumbers.value = result.numbers ?? []
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            loadingNumbers.value = false
        }
    }

    // ── Ações Tenant Self-service ──────────────────────────────────────

    async function loadMyChannel(tenantId) {
        loadingMyChannel.value = true
        lastError.value = null
        try {
            myChannel.value = await service.getChannel(tenantId)
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            loadingMyChannel.value = false
        }
    }

    async function provisionMyChannel(tenantId, options = {}) {
        provisioning.value = true
        lastError.value = null
        try {
            const result = await service.provisionTenant(tenantId, options)
            await loadMyChannel(tenantId)
            return result
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            provisioning.value = false
        }
    }

    async function testSendMessage(channelId, toNumber, message) {
        testingSend.value = true
        lastError.value = null
        try {
            return await service.testSend(channelId, toNumber, message)
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            testingSend.value = false
        }
    }

    async function loadMyLogs(tenantId, limit = 50) {
        loadingLogs.value = true
        lastError.value = null
        try {
            messageLogs.value = await service.getMessageLogs(tenantId, limit)
        } catch (e) {
            lastError.value = e.message
            throw e
        } finally {
            loadingLogs.value = false
        }
    }

    // ── Reset ──────────────────────────────────────────────────────────

    function $reset() {
        allChannels.value      = []
        myChannel.value        = null
        messageLogs.value      = []
        usageReport.value      = []
        availableNumbers.value = []
        lastError.value        = null
    }

    return {
        // Estado
        allChannels, loadingChannels,
        myChannel, loadingMyChannel,
        provisioning, deprovisioning, suspending, reactivating,
        syncingUsage, testingSend,
        messageLogs, loadingLogs,
        usageReport, loadingUsage,
        availableNumbers, loadingNumbers,
        lastError,

        // Computed
        hasActiveChannel, myChannelStatus,
        totalMonthlyCostBrl, totalMonthlyRevenueBrl, totalMonthlyMarginBrl,
        activeCount, suspendedCount,

        // Admin
        loadAllChannels, provision, deprovision, suspend, reactivate,
        syncUsageAll, loadUsageReport, updatePricing, loadAvailableNumbers,

        // Self-service
        loadMyChannel, provisionMyChannel, testSendMessage, loadMyLogs,

        $reset,
    }
})
