<?php

declare(strict_types=1);

/**
 * 技師進階資料：出生年（換算年齡）、三圍（英吋）、罩杯；後台可開關 profile_stats_enabled。
 */

require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_masseur_rewards.php';

/** @return list<string> */
function fate_masseur_cup_size_options(): array
{
    return ['A', 'A-', 'B', 'B+', 'C', 'C+', 'D', 'D+', 'E', 'E+', 'F', 'G', 'H'];
}

function fate_masseur_profile_stats_ensure_schema(PDO $pdo): void
{
    static $done = false;
    if ($done) {
        return;
    }
    $cols = [
        'birth_year' => 'SMALLINT UNSIGNED NULL DEFAULT NULL',
        'measure_bust' => 'SMALLINT UNSIGNED NULL DEFAULT NULL',
        'measure_waist' => 'SMALLINT UNSIGNED NULL DEFAULT NULL',
        'measure_hip' => 'SMALLINT UNSIGNED NULL DEFAULT NULL',
        'cup_size' => 'VARCHAR(8) NULL DEFAULT NULL',
        'profile_stats_hidden' => 'TINYINT NOT NULL DEFAULT 0',
    ];
    try {
        $existing = [];
        foreach ($pdo->query('SHOW COLUMNS FROM `fate_store_masseurs`')->fetchAll(PDO::FETCH_ASSOC) as $c) {
            $existing[(string) ($c['Field'] ?? '')] = true;
        }
        foreach ($cols as $name => $def) {
            if (!isset($existing[$name])) {
                $pdo->exec('ALTER TABLE `fate_store_masseurs` ADD COLUMN `' . $name . '` ' . $def);
            }
        }
        $done = true;
    } catch (Throwable) {
        /* 無 ALTER 權限時略過 */
    }
}

function fate_masseur_profile_stats_parse_optional_int(mixed $raw, int $min, int $max): ?int
{
    if ($raw === null) {
        return null;
    }
    $s = trim((string) $raw);
    if ($s === '' || $s === 'none' || $s === '無資料') {
        return null;
    }
    if (!preg_match('/^\d+$/', $s)) {
        return null;
    }
    $n = (int) $s;
    if ($n < $min || $n > $max) {
        return null;
    }

    return $n;
}

function fate_masseur_profile_stats_parse_cup(mixed $raw): ?string
{
    if ($raw === null) {
        return null;
    }
    $s = strtoupper(trim((string) $raw));
    if ($s === '' || $s === 'NONE' || $s === '無資料') {
        return null;
    }
    if (!in_array($s, fate_masseur_cup_size_options(), true)) {
        return null;
    }

    return $s;
}

/** @return array{bust:array{min:int,max:int},waist:array{min:int,max:int},hip:array{min:int,max:int}} */
function fate_masseur_measure_inch_ranges(): array
{
    return [
        'bust' => ['min' => 18, 'max' => 70],
        'waist' => ['min' => 14, 'max' => 60],
        'hip' => ['min' => 18, 'max' => 70],
    ];
}

function fate_masseur_measure_inch_label(?int $value): string
{
    return $value !== null ? ((string) $value . '″') : '—';
}

/** @param array<string,mixed> $masseur */
function fate_masseur_profile_stats_hidden_from_row(array $masseur): bool
{
    if (!array_key_exists('profile_stats_hidden', $masseur)) {
        return false;
    }

    return (int) ($masseur['profile_stats_hidden'] ?? 0) === 1;
}

/** 前台（店家頁、討論區）是否顯示此技師的年齡／身材（不含正式會員限制）。 */
function fate_masseur_profile_stats_show_public(array $masseur): bool
{
    if (!fate_masseur_profile_stats_enabled()) {
        return false;
    }

    return !fate_masseur_profile_stats_hidden_from_row($masseur);
}

/** 目前訪客／會員是否可看此技師的年齡／身材（含正式會員專區限制）。 */
function fate_masseur_profile_stats_visible_to_viewer(PDO $pdo, int $memberId, array $masseur): bool
{
    if (!fate_masseur_profile_stats_show_public($masseur)) {
        return false;
    }
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_member_tier.php';

    return fate_member_can_access_formal_only($pdo, $memberId, fate_masseur_profile_stats_formal_only());
}

/**
 * @param array<string,mixed> $post
 * @return array{birth_year:?int,measure_bust:?int,measure_waist:?int,measure_hip:?int,cup_size:?string,profile_stats_hidden:bool}
 */
function fate_masseur_profile_stats_parse_post(array $post): array
{
    $curYear = (int) date('Y');
    $minBirth = $curYear - 80;
    $maxBirth = $curYear - 16;
    $ranges = fate_masseur_measure_inch_ranges();

    return [
        'birth_year' => fate_masseur_profile_stats_parse_optional_int($post['birth_year'] ?? null, $minBirth, $maxBirth),
        'measure_bust' => fate_masseur_profile_stats_parse_optional_int($post['measure_bust'] ?? null, $ranges['bust']['min'], $ranges['bust']['max']),
        'measure_waist' => fate_masseur_profile_stats_parse_optional_int($post['measure_waist'] ?? null, $ranges['waist']['min'], $ranges['waist']['max']),
        'measure_hip' => fate_masseur_profile_stats_parse_optional_int($post['measure_hip'] ?? null, $ranges['hip']['min'], $ranges['hip']['max']),
        'cup_size' => fate_masseur_profile_stats_parse_cup($post['cup_size'] ?? null),
        'profile_stats_hidden' => !empty($post['profile_stats_hidden']),
    ];
}

function fate_masseur_age_from_birth_year(?int $birthYear, ?int $atYear = null): ?int
{
    if ($birthYear === null || $birthYear <= 0) {
        return null;
    }
    $y = $atYear ?? (int) date('Y');
    $age = $y - $birthYear;
    if ($age < 0 || $age > 120) {
        return null;
    }

    return $age;
}

/** @return list<int> */
function fate_masseur_birth_year_options(): array
{
    $cur = (int) date('Y');
    $years = [];
    for ($y = $cur - 16; $y >= $cur - 75; $y--) {
        $years[] = $y;
    }

    return $years;
}

/**
 * @param array<string,mixed> $masseur
 * @return array{age:?int,birth_year:?int,age_label:string,measurements_label:string,cup_label:string,has_any:bool}
 */
function fate_masseur_profile_stats_display(array $masseur): array
{
    $birthYear = isset($masseur['birth_year']) && $masseur['birth_year'] !== null && $masseur['birth_year'] !== ''
        ? (int) $masseur['birth_year']
        : null;
    $age = fate_masseur_age_from_birth_year($birthYear);
    if ($age !== null && $birthYear !== null) {
        $ageLabel = $age . ' 歲（' . $birthYear . '）';
    } else {
        $ageLabel = '無資料';
    }

    $bust = isset($masseur['measure_bust']) && $masseur['measure_bust'] !== null && $masseur['measure_bust'] !== ''
        ? (int) $masseur['measure_bust'] : null;
    $waist = isset($masseur['measure_waist']) && $masseur['measure_waist'] !== null && $masseur['measure_waist'] !== ''
        ? (int) $masseur['measure_waist'] : null;
    $hip = isset($masseur['measure_hip']) && $masseur['measure_hip'] !== null && $masseur['measure_hip'] !== ''
        ? (int) $masseur['measure_hip'] : null;
    if ($bust !== null && $waist !== null && $hip !== null) {
        $measureLabel = fate_masseur_measure_inch_label($bust) . ' / ' . fate_masseur_measure_inch_label($waist) . ' / ' . fate_masseur_measure_inch_label($hip);
    } elseif ($bust === null && $waist === null && $hip === null) {
        $measureLabel = '無資料';
    } else {
        $parts = [
            fate_masseur_measure_inch_label($bust),
            fate_masseur_measure_inch_label($waist),
            fate_masseur_measure_inch_label($hip),
        ];
        $measureLabel = implode(' / ', $parts);
    }

    $cup = trim((string) ($masseur['cup_size'] ?? ''));
    $cupLabel = $cup !== '' ? $cup : '無資料';

    $hasAny = $age !== null
        || $bust !== null || $waist !== null || $hip !== null
        || $cup !== '';

    return [
        'age' => $age,
        'birth_year' => $birthYear,
        'age_label' => $ageLabel,
        'measurements_label' => $measureLabel,
        'cup_label' => $cupLabel,
        'has_any' => $hasAny,
    ];
}
