<?php

namespace App\Support;

use App\Models\Setting;
use App\Models\Student;

/**
 * Family (sibling) fee discount policy.
 *
 * When a single parent has enough children enrolled, the school rewards the
 * family — either by making one child free, or by giving every sibling a
 * percentage off. The threshold and mode are configurable.
 */
class SiblingDiscount
{
    public const KEY = 'sibling_discount';

    public static function policy(): array
    {
        return Setting::get(self::KEY, [
            'enabled' => true,
            'min_children' => 3,      // families with this many active kids qualify
            'mode' => 'free_one',     // 'free_one' | 'percent'
            'percent' => 25,          // used when mode = percent
        ]);
    }

    public static function savePolicy(array $p): array
    {
        $clean = [
            'enabled' => (bool) ($p['enabled'] ?? true),
            'min_children' => max(2, (int) ($p['min_children'] ?? 3)),
            'mode' => in_array($p['mode'] ?? 'free_one', ['free_one', 'percent'], true) ? $p['mode'] : 'free_one',
            'percent' => min(100, max(1, (int) ($p['percent'] ?? 25))),
        ];
        Setting::put(self::KEY, $clean);

        return $clean;
    }

    /** Family grouping key — the linked guardian account, else shared parent identity. */
    public static function familyKey(Student $s): string
    {
        if ($s->guardian_id) {
            return 'g'.$s->guardian_id;
        }

        return (string) ($s->father_mobile ?: ($s->guardian_mobile ?: ($s->father_name ?: 'student-'.$s->id)));
    }

    /**
     * Map of student_id => discount info for every student that qualifies.
     * info = ['percent' => int, 'reason' => 'free'|'percent', 'family_size' => int]
     *
     * @param  \Illuminate\Support\Collection<Student>|null  $students  active students (fetched if null)
     */
    public static function forAll($students = null): array
    {
        $policy = self::policy();
        if (! $policy['enabled']) {
            return [];
        }

        $students ??= Student::where('status', 'active')->get();

        $families = [];
        foreach ($students as $s) {
            $families[self::familyKey($s)][] = $s;
        }

        $out = [];
        foreach ($families as $kids) {
            $size = count($kids);
            if ($size < $policy['min_children']) {
                continue;
            }
            if ($policy['mode'] === 'percent') {
                foreach ($kids as $s) {
                    $out[$s->id] = ['percent' => $policy['percent'], 'reason' => 'percent', 'family_size' => $size];
                }
            } else {
                // free_one — the most recently admitted child (highest id) is free.
                usort($kids, fn ($a, $b) => $b->id <=> $a->id);
                $free = $kids[0];
                $out[$free->id] = ['percent' => 100, 'reason' => 'free', 'family_size' => $size];
            }
        }

        return $out;
    }

    /** Discount info for one student, or null. */
    public static function forStudent(Student $student): ?array
    {
        return self::forAll()[$student->id] ?? null;
    }
}
