<script setup>
import { reactive, ref } from 'vue';
import { Head, router } from '@inertiajs/vue3';
import AdminLayout from '@/Layouts/AdminLayout.vue';
import AppCard from '@/Components/ui/AppCard.vue';
import AppModal from '@/Components/ui/AppModal.vue';
import AppTabs from '@/Components/ui/AppTabs.vue';

const props = defineProps({
    statuses: {
        type: Array,
        default: () => ['enabled', 'disabled', 'maintenance'],
    },
    globalServiceControls: {
        type: Array,
        default: () => [],
    },
    networkControls: {
        type: Array,
        default: () => [],
    },
    providerGroups: {
        type: Array,
        default: () => [],
    },
});

const pending = reactive({});
const bulkPending = reactive({});
const maintenanceModal = reactive({
    show: false,
    mode: 'single', // single | bulk
    title: 'Set Maintenance Message',
    description: '',
    message: '',
    status: 'maintenance',
    scope: null,
    scopes: [],
    pending: false,
});
const maintenanceTextarea = ref(null);
const activeTab = ref('overview');
const pageTabs = [
    { key: 'overview', label: 'Global' },
    { key: 'networks', label: 'Networks', count: props.networkControls?.length ?? 0 },
    { key: 'providers', label: 'Providers', count: props.providerGroups?.length ?? 0 },
];

const statusMeta = {
    enabled: {
        label: 'On',
        short: 'On',
        chip: 'bg-emerald-50 text-emerald-700 ring-emerald-200',
        active: 'border-emerald-600 bg-emerald-600 text-white shadow-sm',
    },
    disabled: {
        label: 'Off',
        short: 'Off',
        chip: 'bg-rose-50 text-rose-700 ring-rose-200',
        active: 'border-rose-600 bg-rose-600 text-white shadow-sm',
    },
    maintenance: {
        label: 'Maintenance',
        short: 'Maint.',
        chip: 'bg-amber-50 text-amber-700 ring-amber-200',
        active: 'border-amber-500 bg-amber-500 text-white shadow-sm',
    },
};

const statusLabel = (status, short = false) => {
    const meta = statusMeta[status];
    if (!meta) return status;
    return short ? meta.short : meta.label;
};

const actionLabel = (status, compact = false) => {
    if (status === 'enabled') return compact ? 'Turn On' : 'Turn On';
    if (status === 'disabled') return compact ? 'Turn Off' : 'Turn Off';
    if (status === 'maintenance') return compact ? 'Maint.' : 'Maintenance';
    return status;
};

const statusChipClass = (status) => statusMeta[status]?.chip || 'bg-slate-100 text-slate-700 ring-slate-200';

const statusBtnClass = (current, target) => {
    if (current === target) {
        return statusMeta[target]?.active || 'border-slate-900 bg-slate-900 text-white';
    }

    return 'border-transparent bg-white text-slate-600 hover:bg-slate-100 hover:text-slate-800';
};

const markPending = (scopeKeys, value) => {
    scopeKeys.forEach((scopeKey) => {
        if (!scopeKey) return;
        pending[scopeKey] = value;
    });
};

const closeMaintenanceModal = (force = false) => {
    if (maintenanceModal.pending && !force) return;
    maintenanceModal.show = false;
    maintenanceModal.mode = 'single';
    maintenanceModal.title = 'Set Maintenance Message';
    maintenanceModal.description = '';
    maintenanceModal.message = '';
    maintenanceModal.status = 'maintenance';
    maintenanceModal.scope = null;
    maintenanceModal.scopes = [];
};

const openMaintenanceModal = ({ title, description, scope = null, scopes = [], currentMessage = '' }) => {
    maintenanceModal.show = true;
    maintenanceModal.mode = scopes.length > 1 ? 'bulk' : 'single';
    maintenanceModal.title = title || 'Set Maintenance Message';
    maintenanceModal.description = description || 'Users will see this message when they try to buy this service.';
    maintenanceModal.message = currentMessage || '';
    maintenanceModal.status = 'maintenance';
    maintenanceModal.scope = scope;
    maintenanceModal.scopes = scopes;

    setTimeout(() => {
        maintenanceTextarea.value?.focus();
    }, 0);
};

const submitSingleRule = (scope, status, options = {}) => {
    if (!scope?.scope_key) return;

    pending[scope.scope_key] = true;

    const payload = {
        ...scope,
        status,
    };

    if (Object.prototype.hasOwnProperty.call(options, 'message')) {
        payload.message = options.message;
    }

    router.put(
        route('admin.service-controls.rule.upsert'),
        payload,
        {
            preserveScroll: true,
            onSuccess: () => {
                if (options.onSuccess) options.onSuccess();
            },
            onError: () => {
                if (options.onError) options.onError();
            },
            onFinish: () => {
                pending[scope.scope_key] = false;
                if (options.onFinish) options.onFinish();
            },
        }
    );
};

const submitBulkRules = ({ scopes, status, message = null, bulkKey = null, onSuccess = null, onError = null, onFinish = null }) => {
    const validScopes = (scopes || []).filter((scope) => scope?.scope_key);
    if (!validScopes.length) return;

    const scopeKeys = validScopes.map((scope) => scope.scope_key);
    markPending(scopeKeys, true);

    if (bulkKey) {
        bulkPending[bulkKey] = true;
    }

    router.put(
        route('admin.service-controls.rules.bulk-upsert'),
        {
            scopes: validScopes.map(({ scope_key, ...rest }) => rest),
            status,
            message,
        },
        {
            preserveScroll: true,
            onSuccess: () => {
                if (onSuccess) onSuccess();
            },
            onError: () => {
                if (onError) onError();
            },
            onFinish: () => {
                markPending(scopeKeys, false);
                if (bulkKey) {
                    bulkPending[bulkKey] = false;
                }
                if (onFinish) onFinish();
            },
        }
    );
};

const setRuleStatus = (scope, status, label = null, currentMessage = '') => {
    if (!scope?.scope_key) return;

    if (status === 'maintenance') {
        openMaintenanceModal({
            title: `Maintenance Message`,
            description: `Set an optional message for ${label || 'this service'}. Users will see it when the service is under maintenance.`,
            scope,
            currentMessage,
        });
        return;
    }

    submitSingleRule(scope, status, { message: null });
};

const setNetworkBulkStatus = (network, status) => {
    const scopes = (network?.toggles || []).map((toggle) => toggle.scope).filter(Boolean);
    if (!scopes.length) return;

    if (status === 'maintenance') {
        openMaintenanceModal({
            title: `${network.name}: Maintenance Message`,
            description: 'This will set all toggles inside this network card to maintenance with the same message.',
            scopes,
            currentMessage: '',
        });
        return;
    }

    submitBulkRules({
        scopes,
        status,
        message: null,
        bulkKey: `network:${network.id}`,
    });
};

const submitMaintenanceModal = () => {
    if (maintenanceModal.pending) return;

    const trimmedMessage = maintenanceModal.message?.trim() || null;

    maintenanceModal.pending = true;

    const handleSuccess = () => {
        closeMaintenanceModal(true);
    };
    const handleFinish = () => {
        maintenanceModal.pending = false;
    };

    if (maintenanceModal.mode === 'bulk') {
        submitBulkRules({
            scopes: maintenanceModal.scopes,
            status: 'maintenance',
            message: trimmedMessage,
            bulkKey: null,
            onSuccess: handleSuccess,
            onFinish: handleFinish,
        });
        return;
    }

    submitSingleRule(maintenanceModal.scope, 'maintenance', {
        message: trimmedMessage,
        onSuccess: handleSuccess,
        onFinish: handleFinish,
    });
};

const hasPendingInNetwork = (network) =>
    !!bulkPending[`network:${network.id}`] ||
    (network?.toggles || []).some((toggle) => pending[toggle.scope?.scope_key]);
</script>

<template>
    <Head title="Service Controls" />

    <AdminLayout>
        <template #header>
            <div>
                <h2 class="text-xl font-semibold text-gray-800">Service Controls</h2>
                <p class="mt-1 text-sm text-gray-500">
                    User-friendly toggles for turning services <span class="font-medium">On</span>, <span class="font-medium">Off</span>, or placing them in <span class="font-medium">Maintenance</span>.
                </p>
            </div>
        </template>

        <div class="mx-auto max-w-7xl space-y-5 px-4 py-6 sm:px-6 lg:px-8">
            <AppTabs v-model="activeTab" :tabs="pageTabs" aria-label="Service control sections" />

            <div v-if="activeTab === 'overview'" class="space-y-5">
                <AppCard title="Quick Guide" subtitle="Specific rules override general rules.">
                    <div class="grid gap-2 text-xs text-slate-600 sm:grid-cols-2">
                        <div class="rounded-lg border border-slate-200 bg-slate-50 px-3 py-2">
                            Priority: Plan -> Provider -> Network + Category -> Network + Service -> Network General -> Category/Service -> Global
                        </div>
                        <div class="rounded-lg border border-slate-200 bg-slate-50 px-3 py-2">
                            `Maintenance` keeps service visible but unavailable. `Off` blocks purchases completely.
                        </div>
                    </div>
                </AppCard>

                <AppCard title="Global Toggles" subtitle="Platform-wide default controls.">
                    <div class="space-y-2.5">
                        <div
                            v-for="row in globalServiceControls"
                            :key="row.scope.scope_key"
                            class="rounded-xl border border-slate-200 bg-white p-2.5 sm:p-3"
                        >
                            <div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                                <div class="min-w-0 flex items-center gap-2">
                                    <div class="truncate text-sm font-semibold text-slate-900">{{ row.label }}</div>
                                    <span class="inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-semibold ring-1 ring-inset" :class="statusChipClass(row.status)">
                                        {{ statusLabel(row.status) }}
                                    </span>
                                    <span v-if="pending[row.scope.scope_key]" class="text-[11px] text-slate-500">Saving...</span>
                                </div>

                                <div class="inline-flex w-full items-center gap-1 rounded-xl border border-slate-200 bg-slate-50 p-1 sm:w-auto">
                                    <button
                                        v-for="status in statuses"
                                        :key="status"
                                        type="button"
                                        class="flex-1 rounded-lg border px-2 py-1.5 text-[11px] font-semibold transition sm:min-w-[92px] sm:flex-none"
                                        :class="statusBtnClass(row.status, status)"
                                        :disabled="pending[row.scope.scope_key]"
                                        @click="setRuleStatus(row.scope, status, row.label, row.message)"
                                    >
                                        {{ actionLabel(status) }}
                                    </button>
                                </div>
                            </div>
                            <div
                                v-if="row.status === 'maintenance' && row.message"
                                class="mt-2 rounded-lg border border-amber-200 bg-amber-50 px-2.5 py-1.5 text-[11px] text-amber-800"
                            >
                                {{ row.message }}
                            </div>
                        </div>
                    </div>
                </AppCard>
            </div>

            <AppCard
                v-if="activeTab === 'networks'"
                title="Network Controls"
                subtitle="MTN/Airtel/Glo/9mobile controls (General, Airtime, Data, SME, Gifting, CG, Direct)."
            >
                <div class="space-y-3">
                    <div
                        v-for="network in networkControls"
                        :key="network.id"
                        class="rounded-2xl border border-slate-200 bg-white p-3"
                    >
                        <details class="group" :open="network.slug === 'mtn'">
                            <summary class="flex cursor-pointer list-none items-center justify-between rounded-xl bg-slate-50 px-3 py-2">
                                <div>
                                    <div class="text-sm font-semibold text-slate-900">{{ network.name }}</div>
                                    <div class="text-[11px] uppercase tracking-wide text-slate-500">{{ network.slug }}</div>
                                </div>
                                <div class="flex items-center gap-2">
                                    <button
                                        type="button"
                                        class="hidden rounded-lg border border-emerald-200 bg-white px-2 py-1 text-[11px] font-semibold text-emerald-700 hover:bg-emerald-50 sm:inline"
                                        :disabled="hasPendingInNetwork(network)"
                                        @click.stop.prevent="setNetworkBulkStatus(network, 'enabled')"
                                    >
                                        {{ bulkPending[`network:${network.id}`] ? 'Saving...' : 'Turn On All' }}
                                    </button>
                                    <button
                                        type="button"
                                        class="hidden rounded-lg border border-rose-200 bg-white px-2 py-1 text-[11px] font-semibold text-rose-700 hover:bg-rose-50 sm:inline"
                                        :disabled="hasPendingInNetwork(network)"
                                        @click.stop.prevent="setNetworkBulkStatus(network, 'disabled')"
                                    >
                                        Turn Off All
                                    </button>
                                    <span class="hidden text-[11px] text-slate-500 sm:inline">Show/Hide</span>
                                    <span class="text-xs text-slate-400 transition group-open:rotate-180">⌄</span>
                                </div>
                            </summary>

                            <div class="mt-2 grid grid-cols-2 gap-2 sm:hidden">
                                <button
                                    type="button"
                                    class="rounded-lg border border-emerald-200 bg-white px-2 py-1.5 text-[11px] font-semibold text-emerald-700 hover:bg-emerald-50"
                                    :disabled="hasPendingInNetwork(network)"
                                    @click.stop.prevent="setNetworkBulkStatus(network, 'enabled')"
                                >
                                    {{ bulkPending[`network:${network.id}`] ? 'Saving...' : 'Turn On All' }}
                                </button>
                                <button
                                    type="button"
                                    class="rounded-lg border border-rose-200 bg-white px-2 py-1.5 text-[11px] font-semibold text-rose-700 hover:bg-rose-50"
                                    :disabled="hasPendingInNetwork(network)"
                                    @click.stop.prevent="setNetworkBulkStatus(network, 'disabled')"
                                >
                                    Turn Off All
                                </button>
                            </div>

                            <div class="mt-3 grid gap-2 sm:grid-cols-2 xl:grid-cols-3">
                                <div
                                    v-for="toggle in network.toggles"
                                    :key="toggle.scope.scope_key"
                                    class="rounded-xl border border-slate-200 bg-white p-2.5"
                                >
                                    <div class="mb-2 flex items-center justify-between gap-2">
                                        <div class="text-[11px] font-semibold uppercase tracking-wide text-slate-700">{{ toggle.label }}</div>
                                        <span class="inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-semibold ring-1 ring-inset" :class="statusChipClass(toggle.status)">
                                            {{ statusLabel(toggle.status, true) }}
                                        </span>
                                    </div>

                                    <div class="inline-flex w-full items-center gap-1 rounded-lg border border-slate-200 bg-slate-50 p-1">
                                        <button
                                            v-for="status in statuses"
                                            :key="status"
                                            type="button"
                                            class="flex-1 rounded-md border px-2 py-1 text-[10px] font-semibold transition"
                                            :class="statusBtnClass(toggle.status, status)"
                                            :disabled="pending[toggle.scope.scope_key]"
                                            @click="setRuleStatus(toggle.scope, status, `${network.name} ${toggle.label}`, toggle.message)"
                                        >
                                            {{ actionLabel(status, true) }}
                                        </button>
                                    </div>

                                    <div v-if="pending[toggle.scope.scope_key]" class="mt-1.5 text-[10px] text-slate-500">Saving...</div>
                                    <div
                                        v-else-if="toggle.status === 'maintenance' && toggle.message"
                                        class="mt-1.5 rounded-md border border-amber-200 bg-amber-50 px-2 py-1 text-[10px] text-amber-800"
                                    >
                                        {{ toggle.message }}
                                    </div>
                                </div>
                            </div>
                        </details>
                    </div>
                </div>
            </AppCard>

            <div v-if="activeTab === 'providers'" class="grid gap-4 xl:grid-cols-3">
                <AppCard
                    v-for="group in providerGroups"
                    :key="group.group"
                    :title="group.label"
                    subtitle="Provider-level controls (KEDCO, DSTV, WAEC, etc.)"
                >
                    <div class="space-y-2.5">
                        <div
                            v-for="item in group.items"
                            :key="item.id"
                            class="rounded-xl border border-slate-200 bg-white p-2.5"
                        >
                            <div class="flex items-center justify-between gap-2">
                                <div class="min-w-0">
                                    <div class="truncate text-sm font-semibold text-slate-900">{{ item.name }}</div>
                                    <div class="truncate text-[10px] uppercase tracking-wide text-slate-500">{{ item.slug }}</div>
                                </div>
                                <span class="inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-semibold ring-1 ring-inset" :class="statusChipClass(item.status)">
                                    {{ statusLabel(item.status, true) }}
                                </span>
                            </div>

                            <div class="mt-2 inline-flex w-full items-center gap-1 rounded-lg border border-slate-200 bg-slate-50 p-1">
                                <button
                                    v-for="status in statuses"
                                    :key="status"
                                    type="button"
                                    class="flex-1 rounded-md border px-2 py-1 text-[10px] font-semibold transition"
                                    :class="statusBtnClass(item.status, status)"
                                    :disabled="pending[item.scope.scope_key]"
                                    @click="setRuleStatus(item.scope, status, item.name, item.message)"
                                >
                                    {{ actionLabel(status, true) }}
                                </button>
                            </div>

                            <div v-if="pending[item.scope.scope_key]" class="mt-1.5 text-[10px] text-slate-500">Saving...</div>
                            <div
                                v-else-if="item.status === 'maintenance' && item.message"
                                class="mt-1.5 rounded-md border border-amber-200 bg-amber-50 px-2 py-1 text-[10px] text-amber-800"
                            >
                                {{ item.message }}
                            </div>
                        </div>
                    </div>
                </AppCard>
            </div>
        </div>

        <AppModal :show="maintenanceModal.show" :title="maintenanceModal.title" @close="closeMaintenanceModal">
            <div class="max-h-[68vh] space-y-3 overflow-y-auto pr-1">
                <p class="text-sm text-slate-600">
                    {{ maintenanceModal.description }}
                </p>

                <div
                    class="rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900"
                >
                    Leave message empty to use the default system maintenance message.
                </div>

                <div>
                    <label for="maintenance-message" class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-700">
                        Maintenance Message (Optional)
                    </label>
                    <textarea
                        id="maintenance-message"
                        ref="maintenanceTextarea"
                        v-model="maintenanceModal.message"
                        rows="4"
                        maxlength="255"
                        class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm text-slate-900 shadow-sm outline-none ring-0 focus:border-slate-400 focus:ring-0"
                        placeholder="Example: MTN SME is temporarily under maintenance. Please try again in a few minutes."
                    />
                    <div class="mt-1 text-right text-[11px] text-slate-500">
                        {{ (maintenanceModal.message || '').length }}/255
                    </div>
                </div>

                <div class="flex items-center justify-end gap-2 pt-1">
                    <button
                        type="button"
                        class="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-xs font-semibold text-slate-700 hover:bg-slate-50"
                        :disabled="maintenanceModal.pending"
                        @click="closeMaintenanceModal"
                    >
                        Cancel
                    </button>
                    <button
                        type="button"
                        class="rounded-lg border border-amber-500 bg-amber-500 px-3 py-1.5 text-xs font-semibold text-white hover:bg-amber-600"
                        :disabled="maintenanceModal.pending"
                        @click="submitMaintenanceModal"
                    >
                        {{ maintenanceModal.pending ? 'Saving...' : 'Save Maintenance' }}
                    </button>
                </div>
            </div>
        </AppModal>
    </AdminLayout>
</template>
