<?php

require_once __DIR__ . '/db.php';

/**
 * @return list<string>
 */
function familyHubUsTimezoneIdentifiers(): array {
    $ids = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, 'US');
    if (is_array($ids) && $ids !== []) {
        sort($ids);
        return array_values($ids);
    }
    return [
        'Pacific/Honolulu',
        'America/Anchorage',
        'America/Los_Angeles',
        'America/Phoenix',
        'America/Denver',
        'America/Chicago',
        'America/New_York',
    ];
}

/**
 * @return array<string, mixed>
 */
function familySettingsDefaultsRaw(): array {
    return [
        'currency_symbol' => '★',
        'currency_name' => 'Stars',
        'currency_permanence' => 'permanent',
        'banking_enabled' => false,
        'banking_auto_split_enabled' => false,
        'banking_auto_split_savings_pct' => 0,
        'banking_auto_split_charity_pct' => 0,
        'banking_savings_monthly_interest_rate' => 0,
        'banking_roundup_destination' => 'off',
        'timezone' => 'America/New_York',
        'week_starts_on' => 0,
        'calendar_two_way_google' => false,
        'calendar_bill_days' => [],
        'nfc_base_url' => '',
        'nfc_show_confirmation' => true,
        'nfc_scan_cooldown_seconds' => 0,
    ];
}

/**
 * @param mixed $raw
 * @return list<array{dayOfMonth: int, title: string}>
 */
function normalizeCalendarBillDaysRaw($raw): array {
    if (!is_array($raw)) {
        return [];
    }
    $out = [];
    foreach ($raw as $row) {
        if (!is_array($row)) {
            continue;
        }
        $d = isset($row['dayOfMonth']) ? (int) $row['dayOfMonth'] : 0;
        $title = trim((string) ($row['title'] ?? ''));
        if ($d < 1 || $d > 31 || $title === '') {
            continue;
        }
        $out[] = ['dayOfMonth' => $d, 'title' => $title];
    }
    return $out;
}

function normalizeTimezoneToUs(string $tz, array $allowed): string {
    $tz = trim($tz);
    if ($tz !== '' && in_array($tz, $allowed, true)) {
        return $tz;
    }
    return 'America/New_York';
}

/**
 * Apply defaults and normalize timezone / calendar fields after merge with stored JSON.
 *
 * @param array<string, mixed> $s
 * @return array<string, mixed>
 */
function normalizeLoadedFamilySettings(array $s): array {
    $allowed = familyHubUsTimezoneIdentifiers();
    $s['timezone'] = normalizeTimezoneToUs((string) ($s['timezone'] ?? ''), $allowed);
    $bankingEnabled = $s['banking_enabled'] ?? false;
    $s['banking_enabled'] = $bankingEnabled === true || $bankingEnabled === 1 || $bankingEnabled === '1' || $bankingEnabled === 'true';
    $autoSplitEnabled = $s['banking_auto_split_enabled'] ?? false;
    $s['banking_auto_split_enabled'] = $autoSplitEnabled === true || $autoSplitEnabled === 1 || $autoSplitEnabled === '1' || $autoSplitEnabled === 'true';
    $savingsPct = (float) ($s['banking_auto_split_savings_pct'] ?? 0);
    $charityPct = (float) ($s['banking_auto_split_charity_pct'] ?? 0);
    $s['banking_auto_split_savings_pct'] = max(0, min(100, round($savingsPct, 2)));
    $s['banking_auto_split_charity_pct'] = max(0, min(100, round($charityPct, 2)));
    if (($s['banking_auto_split_savings_pct'] + $s['banking_auto_split_charity_pct']) > 100) {
        $s['banking_auto_split_charity_pct'] = max(0, round(100 - $s['banking_auto_split_savings_pct'], 2));
    }
    $monthlyRate = (float) ($s['banking_savings_monthly_interest_rate'] ?? 0);
    $s['banking_savings_monthly_interest_rate'] = max(0, round($monthlyRate, 6));
    $roundupDestination = trim((string) ($s['banking_roundup_destination'] ?? 'off'));
    if (!in_array($roundupDestination, ['off', 'savings', 'charity'], true)) {
        $roundupDestination = 'off';
    }
    $s['banking_roundup_destination'] = $roundupDestination;
    $v = $s['calendar_two_way_google'] ?? false;
    $s['calendar_two_way_google'] = $v === true || $v === 1 || $v === '1' || $v === 'true';
    $s['calendar_bill_days'] = normalizeCalendarBillDaysRaw($s['calendar_bill_days'] ?? []);
    $s['nfc_base_url'] = trim((string) ($s['nfc_base_url'] ?? ''));
    $showConfirmation = $s['nfc_show_confirmation'] ?? true;
    $s['nfc_show_confirmation'] = $showConfirmation === true || $showConfirmation === 1 || $showConfirmation === '1' || $showConfirmation === 'true';
    $cooldown = (int) ($s['nfc_scan_cooldown_seconds'] ?? 0);
    $s['nfc_scan_cooldown_seconds'] = max(0, min(600, $cooldown));
    return $s;
}

function defaultFamilySettings(): array {
    return normalizeLoadedFamilySettings(familySettingsDefaultsRaw());
}

function loadFamilySettings(): array {
    $raw = readJsonFile('family_settings.json');
    $merged = familySettingsDefaultsRaw();
    if (is_array($raw)) {
        $merged = array_merge($merged, $raw);
    }
    return normalizeLoadedFamilySettings($merged);
}

/**
 * Base app URL (without trailing slash) used for externally shared links.
 */
function familyHubAppUrl(array $familySettings): string {
    $base = trim((string) ($familySettings['nfc_base_url'] ?? ''));
    if ($base !== '') {
        return rtrim($base, '/');
    }
    $https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
    $scheme = $https ? 'https' : 'http';
    $host = trim((string) ($_SERVER['HTTP_HOST'] ?? 'localhost'));
    $script = trim((string) ($_SERVER['SCRIPT_NAME'] ?? '/index.php'));
    $dir = rtrim(str_replace('\\', '/', dirname($script)), '/');
    if ($dir === '' || $dir === '.') {
        $dir = '';
    }
    if (substr($dir, -4) === '/api') {
        $dir = substr($dir, 0, -4);
    }
    return $scheme . '://' . $host . $dir;
}

/**
 * Tab label: symbol + name (e.g. "★ Stars").
 */
function currencyTabLabel(array $familySettings): string {
    $sym = trim((string) ($familySettings['currency_symbol'] ?? ''));
    $name = trim((string) ($familySettings['currency_name'] ?? ''));
    $label = trim($sym . ' ' . $name);
    return $label !== '' ? $label : 'Currency';
}
