// TODO(backend):
// - Payment attempts API for timeline dates
// - Post-card charge + unblock after TapPay save on /cards

import type { ComposerTranslation } from 'vue-i18n';
import type { AccountBlockedViewModel, PaymentAttempt, RestoreAccessStep } from '@/types/accountBlocked';
import type { ActiveSubscription } from '@/types/subscription';
import { formatDate } from '@/utils/formatDate';
import { calculateTotalInclVat, vatRateToPercent } from '@/utils/vat';

const MAX_ATTEMPTS = 3;

const HARDCODED_ATTEMPT_DATES = [
    { date: '12 Jun', time: '00:01' },
    { date: '13 Jun', time: '00:01' },
    { date: '14 Jun', time: '00:01' },
] as const;

const HARDCODED_BLOCKED_AT = { date: '14 Jun', time: '00:03' };
const HARDCODED_LAST_ATTEMPT = '14 Jun 2026, 00:01 AST';

function isPayAsYouGoSubscription(subscription: ActiveSubscription | null | undefined): boolean {
    if (!subscription) {
        return false;
    }

    return subscription.is_pay_as_you_go === true
        || subscription.package?.name === 'pay-as-you-go';
}

function isLastChancePhase(subscription: ActiveSubscription | null | undefined): boolean {
    return subscription?.in_last_chance_phase === true;
}

function buildPaymentAttempts(t: ComposerTranslation): PaymentAttempt[] {
    // TODO: payment_attempts API — replace hardcoded dates
    const attempts: PaymentAttempt[] = HARDCODED_ATTEMPT_DATES.map((entry, index) => ({
        label: t('account_blocked.timeline.attempt_n', { n: index + 1 }),
        sublabel: `${entry.date} · ${entry.time}`,
        status: 'failed',
    }));

    attempts.push({
        label: t('account_blocked.timeline.blocked'),
        sublabel: `${HARDCODED_BLOCKED_AT.date} · ${HARDCODED_BLOCKED_AT.time}`,
        status: 'blocked',
    });

    return attempts;
}

function buildOverdueRestoreSteps(t: ComposerTranslation, amountLabel: string): RestoreAccessStep[] {
    return [1, 2, 3].map((number) => ({
        number,
        title: t(`account_blocked.steps.step_${number}.title`),
        description: t(`account_blocked.steps.step_${number}.description`, { amount: amountLabel }),
    }));
}

function buildLastChanceRestoreSteps(t: ComposerTranslation, daysRemaining: number): RestoreAccessStep[] {
    return [1, 2, 3].map((number) => ({
        number,
        title: t(`account_blocked.last_chance.steps.step_${number}.title`),
        description: t(`account_blocked.last_chance.steps.step_${number}.description`, {
            days: daysRemaining,
        }),
    }));
}

export function buildAccountBlockedViewModel(
    subscription: ActiveSubscription | null | undefined,
    t: ComposerTranslation,
    locale: string,
    formatAmount: (amount: number) => string,
    vatRate: number,
): AccountBlockedViewModel {
    const isLastChance = isLastChancePhase(subscription);
    const daysUntilCold = Math.max(0, subscription?.days_until_cold_archive ?? 0);
    const outstandingBalance = isLastChance
        ? 0
        : calculateTotalInclVat(subscription?.total_due_without_vat, vatRate);
    const amountLabel = formatAmount(outstandingBalance);
    const chargeCount = subscription?.charge_count && subscription.charge_count > 0
        ? subscription.charge_count
        : MAX_ATTEMPTS;

    return {
        variant: isLastChance ? 'last_chance' : 'overdue',
        is_pay_as_you_go: isPayAsYouGoSubscription(subscription),
        outstanding_balance: outstandingBalance,
        billing_period: formatDate(new Date(), { locale, format: 'MMMM YYYY' }),
        vat_rate_percent: vatRateToPercent(vatRate),
        charge_count: chargeCount,
        max_attempts: MAX_ATTEMPTS,
        // TODO: payment_attempts API — replace hardcoded last attempt label
        last_attempt_label: HARDCODED_LAST_ATTEMPT,
        payment_attempts: isLastChance ? [] : buildPaymentAttempts(t),
        steps: isLastChance
            ? buildLastChanceRestoreSteps(t, daysUntilCold)
            : buildOverdueRestoreSteps(t, amountLabel),
        support_email: t('account_blocked.support.email'),
        // TODO: config/support contact — replace placeholder phone
        support_phone: t('account_blocked.support.phone'),
        days_until_cold_archive: daysUntilCold,
        cold_archive_at: subscription?.cold_archive_at ?? null,
    };
}
