<?php

/**
 * Aturan kelayakan PIP berdasarkan matriks:
 * - Saudara 0-1 / 2-5
 * - Punya KPS/KIP (Ya pada salah satu) / Gak punya (keduanya Tidak)
 * - Penghasilan: ≤ Rp1,99jt | Rp2jt–Rp4,99jt | > Rp5jt
 */
class KelayakanRules
{
    private const LOW_INCOME = [
        'Tidak Berpenghasilan',
        'Kurang dari Rp. 500.000',
        'Rp. 500.000 - Rp. 999.999',
        'Rp. 1.000.000 - Rp. 1.999.999',
    ];

    private const MID_INCOME = 'Rp. 2.000.000 - Rp. 4.999.999';

    private const HIGH_INCOME = [
        'Rp. 5.000.000 - Rp. 20.000.000',
        'Lebih dari Rp. 20.000.000',
    ];

    public static function hasKpsKip(array $input): bool
    {
        return ($input['kepemilikan_kps'] ?? '') === 'Ya'
            || ($input['kepemilikan_kip'] ?? '') === 'Ya';
    }

    public static function incomeTier(string $penghasilan): string
    {
        if (in_array($penghasilan, self::LOW_INCOME, true)) {
            return 'low';
        }
        if ($penghasilan === self::MID_INCOME) {
            return 'mid';
        }
        if (in_array($penghasilan, self::HIGH_INCOME, true)) {
            return 'high';
        }

        return 'unknown';
    }

    public static function saudaraGroup(int $jumlah): string
    {
        return $jumlah <= 1 ? '0-1' : '2-5';
    }

    public static function classify(array $input): array
    {
        $tier = self::incomeTier((string) ($input['penghasilan_ortu'] ?? ''));
        $saudara = self::saudaraGroup((int) ($input['jumlah_saudara'] ?? 0));
        $punyaKartu = self::hasKpsKip($input);

        // Decision matrix based on the provided image
        if ($tier === 'high' || $tier === 'unknown') {
            // Income > Rp5jt: Always Tidak Layak
            $kelas = 'Tidak Layak';
        } elseif ($tier === 'low') {
            // Income ≤ Rp1,99jt: Always Layak
            $kelas = 'Layak';
        } elseif ($tier === 'mid') {
            // Income Rp2jt - Rp4,99jt
            // Layak if (has KPS/KIP) OR (siblings >= 2)
            // Tidak Layak if (no KPS/KIP) AND (siblings 0-1)
            if ($punyaKartu || $saudara === '2-5') {
                $kelas = 'Layak';
            } else {
                $kelas = 'Tidak Layak';
            }
        } else {
            $kelas = 'Tidak Layak';
        }

        $probLayak = $kelas === 'Layak' ? 100.0 : 0.0;

        return [
            'kelas' => $kelas,
            'prob_layak' => $probLayak,
            'prob_tidak_layak' => 100.0 - $probLayak,
        ];
    }

    /** @return list<array{pekerjaan_ortu: string, penghasilan_ortu: string, jumlah_saudara: int, kepemilikan_kps: string, kepemilikan_kip: string, kelas: string}> */
    public static function generateTrainingRows(array $pekerjaanList): array
    {
        $penghasilanList = array_merge(self::LOW_INCOME, [self::MID_INCOME], self::HIGH_INCOME);
        $kpsKipCombos = [
            ['Ya', 'Ya'],
            ['Ya', 'Tidak'],
            ['Tidak', 'Ya'],
            ['Tidak', 'Tidak'],
        ];
        $rows = [];

        foreach ($pekerjaanList as $pekerjaan) {
            foreach ($penghasilanList as $penghasilan) {
                foreach ([0, 1, 2, 3, 4, 5] as $saudara) {
                    foreach ($kpsKipCombos as [$kps, $kip]) {
                        $input = [
                            'pekerjaan_ortu' => $pekerjaan,
                            'penghasilan_ortu' => $penghasilan,
                            'jumlah_saudara' => $saudara,
                            'kepemilikan_kps' => $kps,
                            'kepemilikan_kip' => $kip,
                        ];
                        $result = self::classify($input);
                        $rows[] = array_merge($input, ['kelas' => $result['kelas']]);
                    }
                }
            }
        }

        return $rows;
    }
}
