<script setup>
import { computed, onMounted, ref, watch } from 'vue';
import { Head, useForm } from '@inertiajs/vue3';
import MobileAppLayout from '@/Layouts/MobileAppLayout.vue';
import AppCard from '@/Components/ui/AppCard.vue';
import StatusBadge from '@/Components/ui/StatusBadge.vue';

const props = defineProps({
    settings: {
        type: Object,
        default: () => ({}),
    },
    requests: {
        type: Object,
        default: () => ({ data: [] }),
    },
    bankLookup: {
        type: Object,
        default: () => ({ available: false, message: '' }),
    },
});

const form = useForm({
    network_slug: 'mtn',
    sender_phone: '',
    payout_destination: 'wallet',
    bank_name: '',
    bank_code: '',
    bank_account_number: '',
    bank_account_name: '',
    airtime_amount: '',
    note: '',
});

const bankListState = ref({
    status: 'idle', // idle | loading | loaded | error
    message: '',
    banks: [],
});

const accountResolveState = ref({
    status: 'idle', // idle | loading | verified | error
    message: '',
    account_name: '',
});

const lastResolvedKey = ref('');
const copiedReceivingNumber = ref('');
let accountResolveTimer = null;

const networkOptions = [
    { label: 'MTN', value: 'mtn' },
    { label: 'Airtel', value: 'airtel' },
    { label: 'Glo', value: 'glo' },
    { label: '9mobile', value: '9mobile' },
];

const isEnabled = computed(() => !!props.settings?.enabled);

const normalizedRates = computed(() => ({
    mtn: Number(props.settings?.rates?.mtn || 0),
    airtel: Number(props.settings?.rates?.airtel || 0),
    glo: Number(props.settings?.rates?.glo || 0),
    '9mobile': Number(props.settings?.rates?.['9mobile'] || 0),
}));

const receivingNumbers = computed(() => ({
    mtn: String(props.settings?.receiving_numbers?.mtn || '').trim(),
    airtel: String(props.settings?.receiving_numbers?.airtel || '').trim(),
    glo: String(props.settings?.receiving_numbers?.glo || '').trim(),
    '9mobile': String(props.settings?.receiving_numbers?.['9mobile'] || '').trim(),
}));

const selectedReceivingNumber = computed(() => {
    const slug = String(form.network_slug || '').toLowerCase();
    return receivingNumbers.value[slug] || '';
});

const selectedNetworkLabel = computed(() => {
    const selected = networkOptions.find((item) => item.value === form.network_slug);
    return selected?.label || 'Network';
});

const copyReceivingNumber = async () => {
    const value = selectedReceivingNumber.value;
    if (!value) return;

    try {
        if (navigator?.clipboard?.writeText) {
            await navigator.clipboard.writeText(value);
        } else {
            const area = document.createElement('textarea');
            area.value = value;
            area.setAttribute('readonly', '');
            area.style.position = 'absolute';
            area.style.left = '-9999px';
            document.body.appendChild(area);
            area.select();
            document.execCommand('copy');
            document.body.removeChild(area);
        }
    } catch {
        return;
    }

    copiedReceivingNumber.value = value;
    window.setTimeout(() => {
        if (copiedReceivingNumber.value === value) {
            copiedReceivingNumber.value = '';
        }
    }, 1200);
};

const selectedRate = computed(() => {
    const slug = String(form.network_slug || '').toLowerCase();
    return normalizedRates.value[slug] ?? 0;
});

const estimatedPayout = computed(() => {
    const amount = Number(form.airtime_amount || 0);
    if (amount <= 0) return 0;

    return (amount * selectedRate.value) / 100;
});

const displayDestination = (value) => {
    const normalized = String(value || '').toLowerCase();
    if (normalized === 'bank') return 'account';

    return normalized || 'wallet';
};

const submit = () => {
    form.post(route('app.airtime-to-cash.store'), {
        preserveScroll: true,
        onSuccess: () => {
            form.reset('sender_phone', 'airtime_amount', 'note', 'bank_name', 'bank_code', 'bank_account_number', 'bank_account_name');
            accountResolveState.value = {
                status: 'idle',
                message: '',
                account_name: '',
            };
            lastResolvedKey.value = '';
        },
    });
};

const cancelRequest = (id) => {
    useForm({}).post(route('app.airtime-to-cash.cancel', id), {
        preserveScroll: true,
    });
};

const canUseBankLookup = computed(() => !!props.bankLookup?.available);

const loadBanks = async ({ force = false } = {}) => {
    if (!canUseBankLookup.value) {
        bankListState.value = {
            status: 'error',
            message: props.bankLookup?.message || 'Account lookup is unavailable right now.',
            banks: [],
        };
        return;
    }

    if (!force && (bankListState.value.status === 'loaded' || bankListState.value.status === 'loading')) {
        return;
    }

    bankListState.value = {
        status: 'loading',
        message: '',
        banks: bankListState.value.banks || [],
    };

    try {
        const response = await fetch(route('app.airtime-to-cash.banks'), {
            headers: {
                Accept: 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
            },
        });
        const payload = await response.json();

        if (!response.ok || !payload?.success) {
            bankListState.value = {
                status: 'error',
                message: payload?.message || 'Unable to load account providers now.',
                banks: [],
            };
            return;
        }

        bankListState.value = {
            status: 'loaded',
            message: payload?.message || 'Account providers loaded.',
            banks: Array.isArray(payload?.banks) ? payload.banks : [],
        };
        syncSelectedBankName();
    } catch (error) {
        bankListState.value = {
            status: 'error',
            message: 'Unable to load account providers now.',
            banks: [],
        };
    }
};

const syncSelectedBankName = () => {
    const selected = (bankListState.value.banks || []).find((item) => String(item.code) === String(form.bank_code || ''));
    if (selected) {
        form.bank_name = String(selected.name || '');
        return;
    }

    form.bank_name = '';
};

const resolveAccountName = async () => {
    const bankCode = String(form.bank_code || '').trim();
    const accountNumber = String(form.bank_account_number || '').replace(/\D+/g, '');
    if (!bankCode || accountNumber.length < 10) {
        accountResolveState.value = {
            status: 'idle',
            message: '',
            account_name: '',
        };
        return;
    }

    const key = `${bankCode}:${accountNumber}`;
    if (lastResolvedKey.value === key && accountResolveState.value.status === 'verified') {
        return;
    }

    accountResolveState.value = {
        status: 'loading',
        message: '',
        account_name: '',
    };

    try {
        const response = await fetch(route('app.airtime-to-cash.resolve-account', {
            bank_code: bankCode,
            account_number: accountNumber,
        }), {
            headers: {
                Accept: 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
            },
        });
        const payload = await response.json();

        if (!response.ok || !payload?.success) {
            accountResolveState.value = {
                status: 'error',
                message: payload?.message || 'Could not verify account details.',
                account_name: '',
            };
            return;
        }

        const accountName = String(payload?.account_name || '').trim();
        form.bank_account_name = accountName;
        accountResolveState.value = {
            status: 'verified',
            message: payload?.message || 'Account verified.',
            account_name: accountName,
        };
        lastResolvedKey.value = key;
    } catch (error) {
        accountResolveState.value = {
            status: 'error',
            message: 'Could not verify account details right now.',
            account_name: '',
        };
    }
};

watch(
    () => form.payout_destination,
    (destination) => {
        if (destination === 'bank') {
            loadBanks();
            return;
        }

        form.bank_name = '';
        form.bank_code = '';
        form.bank_account_number = '';
        form.bank_account_name = '';
        accountResolveState.value = {
            status: 'idle',
            message: '',
            account_name: '',
        };
        lastResolvedKey.value = '';
    }
);

watch(
    () => form.bank_code,
    () => {
        syncSelectedBankName();
        accountResolveState.value = {
            status: 'idle',
            message: '',
            account_name: '',
        };
        lastResolvedKey.value = '';
    }
);

watch(
    () => form.bank_account_number,
    () => {
        const bankCode = String(form.bank_code || '').trim();
        const accountNumber = String(form.bank_account_number || '').replace(/\D+/g, '');

        if (accountResolveTimer) {
            clearTimeout(accountResolveTimer);
            accountResolveTimer = null;
        }

        if (form.payout_destination !== 'bank' || !bankCode || accountNumber.length < 10) {
            accountResolveState.value = {
                status: 'idle',
                message: '',
                account_name: '',
            };
            lastResolvedKey.value = '';
            return;
        }

        accountResolveTimer = setTimeout(() => {
            resolveAccountName();
        }, 500);
    }
);

onMounted(() => {
    if (form.payout_destination === 'bank') {
        loadBanks();
    }
});
</script>

<template>
    <Head title="Airtime To Cash" />

    <MobileAppLayout title="Airtime To Cash" subtitle="Convert airtime to wallet balance after admin confirmation">
        <div class="space-y-4">
            <AppCard title="Current Rates" subtitle="Payout is based on the selected network.">
                <div class="grid grid-cols-2 gap-2">
                    <button
                        v-for="item in networkOptions"
                        :key="item.value"
                        type="button"
                        class="relative rounded-xl border p-2.5 text-left transition"
                        :class="form.network_slug === item.value
                            ? 'border-slate-900 bg-slate-900 text-white'
                            : 'border-slate-200 bg-slate-50 text-slate-900 hover:border-slate-300'"
                        @click="form.network_slug = item.value"
                    >
                        <span
                            v-if="form.network_slug === item.value"
                            class="absolute right-2 top-2 inline-flex h-5 w-5 items-center justify-center rounded-full bg-white/20 text-[11px] font-bold text-white"
                        >
                            ✓
                        </span>
                        <div class="text-[11px] uppercase tracking-wide" :class="form.network_slug === item.value ? 'text-slate-200' : 'text-slate-500'">{{ item.label }}</div>
                        <div class="mt-1 text-sm font-semibold">{{ normalizedRates[item.value] }}%</div>
                    </button>
                </div>
                <div class="mt-3 rounded-xl border border-slate-200 bg-slate-50 p-3">
                    <div class="flex items-center justify-between gap-2">
                        <div class="min-w-0">
                            <div class="text-[11px] font-semibold text-slate-700">
                                Send {{ selectedNetworkLabel }} airtime to:
                            </div>
                            <div class="mt-0.5 truncate text-sm font-semibold text-slate-900">
                                {{ selectedReceivingNumber || 'Not set by admin yet' }}
                            </div>
                        </div>
                        <button
                            type="button"
                            class="shrink-0 rounded-md border border-slate-300 bg-white px-2.5 py-1.5 text-xs font-semibold text-slate-700 disabled:cursor-not-allowed disabled:opacity-50"
                            :disabled="!selectedReceivingNumber"
                            @click="copyReceivingNumber"
                        >
                            {{ copiedReceivingNumber === selectedReceivingNumber ? 'Copied' : 'Copy' }}
                        </button>
                    </div>
                </div>
                <p v-if="form.errors.network_slug" class="mt-2 text-xs text-rose-600">{{ form.errors.network_slug }}</p>
            </AppCard>

            <AppCard title="Submit Request" subtitle="Send airtime to the provided line, then submit here.">
                <div class="space-y-3">
                    <div v-if="!isEnabled" class="rounded-xl border border-rose-200 bg-rose-50 px-3 py-2 text-xs text-rose-800">
                        Airtime-to-cash is currently unavailable.
                    </div>
                    <div v-else-if="!selectedReceivingNumber" class="rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800">
                        Receiving number for {{ selectedNetworkLabel }} is not configured yet. Contact support.
                    </div>

                    <div class="grid grid-cols-2 gap-2">
                        <div>
                            <label class="mb-1 block text-xs font-semibold text-slate-600">Airtime Amount (NGN)</label>
                            <input
                                v-model="form.airtime_amount"
                                type="number"
                                min="1"
                                step="0.01"
                                class="w-full rounded-xl border-slate-300 text-sm shadow-sm"
                                :disabled="!isEnabled || form.processing"
                                :placeholder="String(settings?.min_amount || 100)"
                            />
                            <p v-if="form.errors.airtime_amount" class="mt-1 text-xs text-rose-600">{{ form.errors.airtime_amount }}</p>
                        </div>

                        <div>
                            <label class="mb-1 block text-xs font-semibold text-slate-600">Payout Destination</label>
                            <div class="grid grid-cols-2 gap-2">
                                <button
                                    type="button"
                                    class="relative rounded-xl border px-2 py-2 text-xs font-semibold transition"
                                    :class="form.payout_destination === 'wallet' ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-300 bg-white text-slate-700'"
                                    @click="form.payout_destination = 'wallet'"
                                >
                                    <span
                                        v-if="form.payout_destination === 'wallet'"
                                        class="absolute right-2 top-1.5 inline-flex h-4 w-4 items-center justify-center rounded-full bg-white/20 text-[10px] font-bold text-white"
                                    >
                                        ✓
                                    </span>
                                    Wallet
                                </button>
                                <button
                                    type="button"
                                    class="relative rounded-xl border px-2 py-2 text-xs font-semibold transition"
                                    :class="form.payout_destination === 'bank' ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-300 bg-white text-slate-700'"
                                    @click="form.payout_destination = 'bank'"
                                >
                                    <span
                                        v-if="form.payout_destination === 'bank'"
                                        class="absolute right-2 top-1.5 inline-flex h-4 w-4 items-center justify-center rounded-full bg-white/20 text-[10px] font-bold text-white"
                                    >
                                        ✓
                                    </span>
                                    Account
                                </button>
                            </div>
                            <p v-if="form.errors.payout_destination" class="mt-1 text-xs text-rose-600">{{ form.errors.payout_destination }}</p>
                        </div>
                    </div>

                    <div>
                        <label class="mb-1 block text-xs font-semibold text-slate-600">Sender Phone Number</label>
                        <input v-model="form.sender_phone" type="text" class="w-full rounded-xl border-slate-300 text-sm shadow-sm" :disabled="!isEnabled || form.processing" placeholder="08012345678" />
                        <p v-if="form.errors.sender_phone" class="mt-1 text-xs text-rose-600">{{ form.errors.sender_phone }}</p>
                    </div>

                    <div v-if="form.payout_destination === 'bank'" class="space-y-2 rounded-xl border border-amber-200 bg-amber-50 p-3">
                        <div class="text-xs text-amber-900">
                            Use only your own account details. Do not use another person's account details with a different name.
                        </div>

                        <div>
                            <div class="mb-1 flex items-center justify-between">
                                <label class="block text-xs font-semibold text-slate-600">Account Provider</label>
                                <button
                                    type="button"
                                    class="rounded-md border border-slate-300 bg-white px-2 py-1 text-[11px] font-semibold text-slate-700 disabled:opacity-50"
                                    :disabled="!isEnabled || form.processing || bankListState.status === 'loading'"
                                    @click="loadBanks({ force: true })"
                                >
                                    {{ bankListState.status === 'loading' ? 'Loading...' : 'Refresh' }}
                                </button>
                            </div>
                            <select
                                v-model="form.bank_code"
                                class="w-full rounded-xl border-slate-300 text-sm shadow-sm"
                                :disabled="!isEnabled || form.processing || !canUseBankLookup || bankListState.status === 'loading'"
                            >
                                <option value="">Select provider</option>
                                <option v-for="bank in bankListState.banks" :key="`bank-${bank.code}`" :value="bank.code">
                                    {{ bank.name }} ({{ bank.code }})
                                </option>
                            </select>
                            <p v-if="bankListState.status === 'error'" class="mt-1 text-xs text-rose-600">{{ bankListState.message }}</p>
                            <p v-else-if="!canUseBankLookup" class="mt-1 text-xs text-amber-700">{{ bankLookup?.message || 'Account lookup unavailable.' }}</p>
                            <p v-if="form.errors.bank_name" class="mt-1 text-xs text-rose-600">{{ form.errors.bank_name }}</p>
                            <p v-if="form.errors.bank_code" class="mt-1 text-xs text-rose-600">{{ form.errors.bank_code }}</p>
                        </div>
                        <div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
                            <div>
                                <label class="mb-1 block text-xs font-semibold text-slate-600">Account Number</label>
                                <input
                                    v-model="form.bank_account_number"
                                    type="text"
                                    class="w-full rounded-xl border-slate-300 text-sm shadow-sm"
                                    :disabled="!isEnabled || form.processing"
                                    placeholder="0123456789"
                                />
                                <p v-if="form.errors.bank_account_number" class="mt-1 text-xs text-rose-600">{{ form.errors.bank_account_number }}</p>
                            </div>
                            <div>
                                <label class="mb-1 block text-xs font-semibold text-slate-600">Account Name</label>
                                <input v-model="form.bank_account_name" type="text" class="w-full rounded-xl border-slate-300 text-sm shadow-sm" :disabled="!isEnabled || form.processing" placeholder="Account Name" />
                                <p v-if="form.errors.bank_account_name" class="mt-1 text-xs text-rose-600">{{ form.errors.bank_account_name }}</p>
                            </div>
                        </div>
                        <div
                            v-if="accountResolveState.status === 'loading' || accountResolveState.status === 'verified' || accountResolveState.status === 'error'"
                            class="rounded-xl border p-2 text-xs"
                            :class="accountResolveState.status === 'verified'
                                ? 'border-emerald-200 bg-emerald-50 text-emerald-900'
                                : accountResolveState.status === 'error'
                                    ? 'border-rose-200 bg-rose-50 text-rose-800'
                                    : 'border-slate-200 bg-slate-50 text-slate-600'"
                        >
                            <span v-if="accountResolveState.status === 'loading'">Verifying account name...</span>
                            <span v-else-if="accountResolveState.status === 'verified'">
                                Account verified: {{ accountResolveState.account_name }}
                            </span>
                            <span v-else>{{ accountResolveState.message }}</span>
                        </div>
                    </div>

                    <div>
                        <label class="mb-1 block text-xs font-semibold text-slate-600">Note (optional)</label>
                        <textarea v-model="form.note" rows="2" class="w-full rounded-xl border-slate-300 text-sm shadow-sm" :disabled="!isEnabled || form.processing" placeholder="Any extra proof details" />
                        <p v-if="form.errors.note" class="mt-1 text-xs text-rose-600">{{ form.errors.note }}</p>
                    </div>

                    <div class="rounded-xl border border-slate-200 bg-slate-50 p-3 text-xs text-slate-700">
                        <div class="flex items-center justify-between"><span>Allowed range</span><span>NGN {{ settings?.min_amount || 0 }} - NGN {{ settings?.max_amount || 0 }}</span></div>
                        <div class="mt-1 flex items-center justify-between"><span>Estimated payout</span><span class="font-semibold text-slate-900">NGN {{ estimatedPayout.toFixed(2) }}</span></div>
                    </div>

                    <button
                        type="button"
                        class="inline-flex w-full items-center justify-center rounded-xl bg-slate-900 px-4 py-2.5 text-sm font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50"
                        :disabled="!isEnabled || !selectedReceivingNumber || form.processing"
                        @click="submit"
                    >
                        {{ form.processing ? 'Submitting...' : 'Submit Request' }}
                    </button>
                </div>
            </AppCard>

            <AppCard title="My Requests" subtitle="Track approval progress and credited payouts.">
                <div class="space-y-2">
                    <div
                        v-for="item in requests.data"
                        :key="item.id"
                        class="rounded-2xl border border-slate-200 bg-white p-3"
                    >
                        <div class="flex items-start justify-between gap-2">
                            <div class="min-w-0">
                                <div class="text-sm font-semibold text-slate-900 uppercase">{{ item.network_slug }} - {{ item.sender_phone }}</div>
                                <div class="mt-0.5 text-xs text-slate-500">Ref: <span class="font-mono">{{ item.reference }}</span></div>
                            </div>
                            <StatusBadge :status="item.status" />
                        </div>

                        <div class="mt-2 grid grid-cols-2 gap-2 text-xs">
                            <div class="rounded-xl bg-slate-50 p-2">
                                <div class="text-slate-500">Airtime</div>
                                <div class="font-semibold text-slate-900">NGN {{ item.airtime_amount }}</div>
                            </div>
                            <div class="rounded-xl bg-slate-50 p-2">
                                <div class="text-slate-500">Payout</div>
                                <div class="font-semibold text-slate-900">NGN {{ item.payout_amount }}</div>
                            </div>
                            <div class="rounded-xl bg-slate-50 p-2">
                                <div class="text-slate-500">Destination</div>
                                <div class="font-semibold text-slate-900 uppercase">{{ displayDestination(item.payout_destination) }}</div>
                            </div>
                            <div class="rounded-xl bg-slate-50 p-2">
                                <div class="text-slate-500">Payout Status</div>
                                <div class="font-semibold text-slate-900">{{ item.payout_status || 'not_required' }}</div>
                            </div>
                        </div>

                        <div v-if="item.payout_reference || item.payout_failure_reason" class="mt-2 rounded-xl border border-slate-200 bg-slate-50 p-2 text-[11px] text-slate-600">
                            <div v-if="item.payout_reference"><span class="font-medium text-slate-700">Payout Ref:</span> {{ item.payout_reference }}</div>
                            <div v-if="item.payout_failure_reason"><span class="font-medium text-rose-700">Reason:</span> {{ item.payout_failure_reason }}</div>
                        </div>

                        <div class="mt-2 flex items-center justify-between text-[11px] text-slate-500">
                            <span>{{ item.created_at }}</span>
                            <button
                                v-if="item.status === 'pending'"
                                type="button"
                                class="rounded-md border border-rose-300 bg-rose-50 px-2 py-1 text-rose-700"
                                @click="cancelRequest(item.id)"
                            >
                                Cancel
                            </button>
                        </div>
                    </div>

                    <div v-if="(requests.data || []).length === 0" class="rounded-2xl border border-dashed border-slate-300 p-4 text-sm text-slate-500">
                        No airtime-to-cash requests yet.
                    </div>
                </div>
            </AppCard>
        </div>
    </MobileAppLayout>
</template>
