<?php

namespace App\Services;

use App\Models\JackpotSetUp;
use App\Models\JackpotBetting;

use Illuminate\Support\Facades\Log;

class JackpotService
{


    public function resultPrediction($periods, $distribute_amount_in_user)
    {
        $numbers = JackpotBetting::where('period_id', $periods->id)
            ->get();



        $samples = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

        $finalResult = '';


        $distributionLimit = $distribute_amount_in_user;
        $max = PHP_INT_MAX;

        $hasnumber1Bets = JackpotBetting::where('period_id', $periods->id)
            ->get();

        if ($hasnumber1Bets) {
            $number1Bets = JackpotBetting::select('number', \DB::raw('SUM(`1`) as total'))
                ->where('period_id', $periods->id)
                ->where('1', '<=', $distributionLimit)
                ->groupBy('number')
                ->orderByDesc('total')
                ->first();

            if ($number1Bets) {
                $number1 = $number1Bets->number;
                $resultnumber1 = $number1[4];
                $distributionLimit -= $number1Bets->total;
            } else {
                $lastDigits = $hasnumber1Bets->map(function ($bet) {
                    $numberStr = $bet->number;
                    // -1 index gives last digit
                    return strlen($numberStr) >= 1 ? (int) $numberStr[-1] : null;
                });


                $secondLastDigits = $secondLastDigits
                    ->unique()
                    ->values();

                // remove $digitToRemove and all digits in $secondLastDigits
                $availableDigits = $samples
                    ->reject(function ($digit) use ($secondLastDigits) {
                        return $secondLastDigits->contains($digit);
                    })
                    ->values();

                // pick a random digit from remaining ones
                $resultnumber1 = $availableDigits->random();

                if (!$resultnumber1) {
                    $resultnumber1 = rand(0, 9);
                }

                $firstFourDigits = '';
                for ($i = 0; $i < 4; $i++) {
                    $firstFourDigits .= rand(0, 9);
                }

                // combine with the last digit
                $number1 = $firstFourDigits . $resultnumber1;
            }
        } else {
            $resultnumber1 = rand(0, 9);
            $firstFourDigits = '';
            for ($i = 0; $i < 4; $i++) {
                $firstFourDigits .= rand(0, 9);
            }

            // combine with the last digit
            $number1 = $firstFourDigits . $resultnumber1;
        }


        $finalResult = $resultnumber1;



        $hasnumber2Bets = JackpotBetting::where('period_id', $periods->id)
            ->whereRaw('RIGHT(number, 1) = ?', [$finalResult])
            ->get();

        if ($hasnumber2Bets) {
            // Fetch the number with the largest sum
            $number2Bets = JackpotBetting::select('number', \DB::raw('SUM(`2`) as total'))
                ->where('period_id', $periods->id)
                ->whereRaw('RIGHT(number, 1) = ?', [$finalResult])
                ->where('2', '<=', $distributionLimit)
                ->groupBy('number')
                ->orderByDesc('total')
                ->first();

            if ($number2Bets) {
                $distributionLimit -= $number2Bets->total;
                $number1 = $number2Bets->number;
                $resultnumber2 = $number1[3];
            } else {
                $secondLastDigits = $hasnumber2Bets->map(function ($bet) {
                    $numberStr = $bet->number;
                    // -2 index gives second last digit
                    return strlen($numberStr) >= 2 ? (int) $numberStr[-2] : null;
                });

                $digitToRemove = $number1[3];

                $secondLastDigits = $secondLastDigits
                    ->unique()
                    ->values()
                    ->reject(function ($digit) use ($digitToRemove) {
                        return $digit == $digitToRemove;
                    })->values();

                // remove $digitToRemove and all digits in $secondLastDigits
                $availableDigits = $samples
                    ->reject(function ($digit) use ($digitToRemove, $secondLastDigits) {
                        return $digit == $digitToRemove || $secondLastDigits->contains($digit);
                    })
                    ->values();

                // pick a random digit from remaining ones
                $resultnumber2 = $availableDigits->random();

                if (!$resultnumber2) {
                    $resultnumber2 = rand(0, 9);
                }

                $number1[3] = $resultnumber2;
            }
        } else {

            $resultnumber2 = rand(0, 9);
            $number1[3] = $resultnumber2;
        }


        $finalResult = $resultnumber2 . $finalResult;


        $hasnumber3Bets = JackpotBetting::where('period_id', $periods->id)
            ->whereRaw('RIGHT(number, 2) = ?', [$finalResult])
            ->get();

        if ($hasnumber3Bets) {
            // Fetch the number with the largest sum
            $number3Bets = JackpotBetting::select('number', \DB::raw('SUM(`3`) as total'))
                ->where('period_id', $periods->id)
                ->whereRaw('RIGHT(number, 2) = ?', [$finalResult])
                ->where('3', '<=', $distributionLimit)
                ->groupBy('number')
                ->orderByDesc('total')
                ->first();

            if ($number3Bets) {
                $distributionLimit -= $number3Bets->total;
                $number1 = $number3Bets->number;
                $resultnumber3 = $number1[2];
            } else {
                $thirdLastDigits = $hasnumber3Bets->map(function ($bet) {
                    $numberStr = $bet->number;
                    // -3 index gives third last digit
                    return strlen($numberStr) >= 3 ? (int) $numberStr[-3] : null;
                });


                $digitToRemove = $number1[2];

                $thirdLastDigits = $thirdLastDigits
                    ->unique()
                    ->values()
                    ->reject(function ($digit) use ($digitToRemove) {
                        return $digit == $digitToRemove;
                    })->values();

                // remove $digitToRemove and all digits in $thirdLastDigits
                $availableDigits = $samples
                    ->reject(function ($digit) use ($digitToRemove, $thirdLastDigits) {
                        return $digit == $digitToRemove || $thirdLastDigits->contains($digit);
                    })
                    ->values();

                // pick a random digit from remaining ones
                $resultnumber3 = $availableDigits->random();

                if (!$resultnumber3) {
                    $resultnumber3 = rand(0, 9);
                }

                $number1[2] = $resultnumber3;
            }
        } else {

            $resultnumber3 = rand(0, 9);
            $number1[2] = $resultnumber3;
        }


        $finalResult = $resultnumber3 . $finalResult;



        $hasnumber4Bets = JackpotBetting::where('period_id', $periods->id)
            ->whereRaw('RIGHT(number, 3) = ?', [$finalResult])
            ->get();

        if ($hasnumber4Bets) {
            // Fetch the number with the largest sum
            $number4Bets = JackpotBetting::select('number', \DB::raw('SUM(`4`) as total'))
                ->where('period_id', $periods->id)
                ->whereRaw('RIGHT(number, 3) = ?', [$finalResult])
                ->where('4', '<=', $distributionLimit)
                ->groupBy('number')
                ->orderByDesc('total')
                ->first();

            if ($number4Bets) {
                $distributionLimit -= $number4Bets->total;
                $number1 = $number4Bets->number;
                $resultnumber4 = $number1[1];
            } else {
                $fourLastDigits = $hasnumber4Bets->map(function ($bet) {
                    $numberStr = $bet->number;
                    // -3 index gives third last digit
                    return strlen($numberStr) >= 4 ? (int) $numberStr[-4] : null;
                });


                $digitToRemove = $number1[1];

                $fourLastDigits = $fourLastDigits
                    ->unique()
                    ->values()
                    ->reject(function ($digit) use ($digitToRemove) {
                        return $digit == $digitToRemove;
                    })->values();

                // remove $digitToRemove and all digits in $fourLastDigits
                $availableDigits = $samples
                    ->reject(function ($digit) use ($digitToRemove, $fourLastDigits) {
                        return $digit == $digitToRemove || $fourLastDigits->contains($digit);
                    })
                    ->values();

                // pick a random digit from remaining ones
                $resultnumber4 = $availableDigits->random();

                if (!$resultnumber4) {
                    $resultnumber4 = rand(0, 9);
                }

                $number1[1] = $resultnumber4;
            }
        } else {

            $resultnumber4 = rand(0, 9);
            $number1[1] = $resultnumber4;
        }


        $finalResult = $resultnumber4 . $finalResult;


        $hasnumber5Bets = JackpotBetting::where('period_id', $periods->id)
            ->whereRaw('RIGHT(number, 4) = ?', [$finalResult])
            ->get();

        if ($hasnumber5Bets) {
            // Fetch the number with the largest sum
            $number5Bets = JackpotBetting::select('number', \DB::raw('SUM(`5`) as total'))
                ->where('period_id', $periods->id)
                ->whereRaw('RIGHT(number, 4) = ?', [$finalResult])
                ->where('5', '<=', $distributionLimit)
                ->groupBy('number')
                ->orderByDesc('total')
                ->first();

            if ($number5Bets) {
                $distributionLimit -= $number5Bets->total;
                $number1 = $number5Bets->number;
                $resultnumber5 = $number1[0];
            } else {
                $fiveLastDigits = $hasnumber5Bets->map(function ($bet) {
                    $numberStr = $bet->number;
                    // -3 index gives third last digit
                    return strlen($numberStr) >= 5 ? (int) $numberStr[-5] : null;
                });


                $digitToRemove = $number1[0];

                $fiveLastDigits = $fiveLastDigits
                    ->unique()
                    ->values()
                    ->reject(function ($digit) use ($digitToRemove) {
                        return $digit == $digitToRemove;
                    })->values();

                // remove $digitToRemove and all digits in $fiveLastDigits
                $availableDigits = $samples
                    ->reject(function ($digit) use ($digitToRemove, $fiveLastDigits) {
                        return $digit == $digitToRemove || $fiveLastDigits->contains($digit);
                    })
                    ->values();

                // pick a random digit from remaining ones
                $resultnumber5 = $availableDigits->random();

                if (!$resultnumber5) {
                    $resultnumber5 = rand(0, 9);
                }

                $number1[0] = $resultnumber5;
            }
        } else {

            $resultnumber5 = rand(0, 9);
            $number1[0] = $resultnumber5;
        }


        $finalResult = $resultnumber5 . $finalResult;


        

        return $finalResult;
    }

    private function getMatchLength($number, $finalNumber)
    {
        for ($len = 5; $len >= 1; $len--) {
            if (substr($number, -$len) === substr($finalNumber, -$len)) {
                return $len;
            }
        }
        return 0;
    }
}
