<?php

namespace App\Http\Controllers;

use App\Models\Sample;
use App\Models\Minggu;
use App\Models\Bulan;
use App\Models\Hasil;
use App\Models\Brand;
use App\Models\Training;
use App\Models\Testing;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class HasilController extends Controller
{
    // public function index()
    // {
    //     return view('hasiltest');
    // }

    //     public function index(Request $request)
    // {
    //     $brandId = $request->input('brand', 1);

    //     $data = Hasil::where('brands', $brandId)
    //         ->orderBy('bulan')
    //         ->orderBy('minggu')
    //         ->get();

    //     $dataPerBulan = [];

    //     foreach ($data as $item) {
    //         $bulanNama = $this->getNamaBulan($item->bulan);

    //         $dataPerBulan[$bulanNama]['minggu_' . $item->minggu] = $item->nilai_prediksi;

    //         if (!isset($dataPerBulan[$bulanNama]['total']) && $item->total_bulan !== null) {
    //             $dataPerBulan[$bulanNama]['total'] = $item->total_bulan;
    //         }
    //     }

    //     return view('hasiltest', [
    //         'brandId' => $brandId,
    //         'dataPerBulan' => $dataPerBulan
    //     ]);
    // }

    public function index(Request $request)
    {
        $brandId = $request->input('brand', 1); // default ke 1 kalau tidak ada
        $brands = Brand::all(); // ambil semua brand dari tabel

        $data = Hasil::where('brands', $brandId)
            ->orderByRaw('FIELD(bulan, ' . implode(',', $this->getUrutanBulan()) . ')')
            ->orderBy('minggu')
            ->get();

        $dataPerBulan = [];

        foreach ($data as $item) {
            $startMonth = $this->getStartMonth();
            $startYear = $this->getStartYear();

            // Hitung offset bulan terhadap bulan awal sample
            $selisihBulan = ($item->bulan - $startMonth + 12) % 12;

            // Tambah 1 tahun dari sample, lalu tambahkan +1 lagi jika bulan lebih kecil dari startMonth (artinya tahun sudah ganti)
            $tahunPrediksi = $startYear + 1;
            if ($item->bulan < $startMonth) {
                $tahunPrediksi++;
            }

            $bulanNama = $this->getNamaBulan($item->bulan) . ' ' . $tahunPrediksi;

            $dataPerBulan[$bulanNama]['minggu_' . $item->minggu] = $item->nilai_prediksi;

            // Tetap tampilkan 0 jika total 0
            if (!isset($dataPerBulan[$bulanNama]['total']) && $item->total_bulan !== null) {
                $dataPerBulan[$bulanNama]['total'] = $item->total_bulan;
            }
        }

        $hasData = $data->isNotEmpty(); // ✅ Tambahkan ini

        return view('hasil', [
            'brandId' => $brandId,
            'brands' => $brands,
            'dataPerBulan' => $dataPerBulan,
            'hasData' => $hasData, // ✅ Kirim ke view
        ]);
    }

    private function getNamaBulan($bulan)
    {
        $namaBulan = [
            1 => 'Januari',
            2 => 'Februari',
            3 => 'Maret',
            4 => 'April',
            5 => 'Mei',
            6 => 'Juni',
            7 => 'Juli',
            8 => 'Agustus',
            9 => 'September',
            10 => 'Oktober',
            11 => 'November',
            12 => 'Desember',
        ];

        return $namaBulan[$bulan] ?? 'Unknown';
    }

    private function getStartYear()
    {
        return session('startYear') ?? now()->year; // fallback ke tahun sekarang kalau tidak ada di session
    }

    private function getStartMonth()
    {
        return session('startMonth') ?? now()->month;
    }

    private function getUrutanBulan()
    {
        $startMonth = session('startMonth') ?? 1;
        $bulan = [];

        for ($i = 0; $i < 4; $i++) {
            $bulan[] = (($startMonth + $i - 1) % 12) + 1;
        }

        return $bulan;
    }

    //     public function index(Request $request)
    // {
    //     $brandId = $request->input('brand', 1);

    //     $hasil = Hasil::where('brands', $brandId)
    //         ->orderByRaw("FIELD(bulan, 'Januari', 'Februari', 'Maret', 'April')")
    //         ->orderBy('minggu')
    //         ->get()
    //         ->groupBy('bulan');

    //     return view('hasiltest', compact('hasil', 'brandId'));
    // }

    //     public function proses(Request $request)
    // {
    //     $k = 3;

    //     $brandId = $request->input('brand', 1);

    //     // Ambil ID bulan sesuai urutan yang diinginkan
    // $bulanIds = Bulan::whereIn('nama', ['Januari', 'Februari', 'Maret', 'April'])
    // ->orderByRaw("FIELD(nama, 'Januari', 'Februari', 'Maret', 'April')")
    // ->pluck('id')
    // ->toArray();

    // // Ambil ID minggu (diasumsikan minggu 1-4)
    // $mingguIds = Minggu::orderBy('id')->pluck('id')->toArray();

    //     $trainings = Training::where('brands', $brandId)->get();
    //     $testings = Testing::where('brands', $brandId)->get();

    //     $bulanList = ['Januari', 'Februari', 'Maret', 'April']; // Bisa disesuaikan
    //     $mingguKe = 1;
    //     $bulanIndex = 0;
    //     $hasilPrediksi = [];

    //     // Hapus data lama hasil prediksi dari brand yang sama
    //     Hasil::where('brands', $brandId)->delete();

    //     foreach ($testings as $index => $testing) {
    //         $distances = [];

    //         foreach ($trainings as $training) {
    //             $distance = sqrt(
    //                 pow($testing->data_1 - $training->data_1, 2) +
    //                 pow($testing->data_2 - $training->data_2, 2) +
    //                 pow($testing->data_3 - $training->data_3, 2)
    //             );

    //             $distances[] = [
    //                 'distance' => $distance,
    //                 'target' => $training->target,
    //             ];
    //         }

    //         usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);

    //         $nearest = array_slice($distances, 0, $k);
    //         $totalTarget = array_sum(array_column($nearest, 'target'));
    //         $prediksi = round($totalTarget / $k);

    //         // Simpan ke DB
    //         $bulanId = $bulanIds[$bulanIndex];
    // $mingguId = $mingguIds[$mingguKe - 1];

    // Hasil::create([
    //     'brands' => $brandId,
    //     'bulan' => $bulanId,
    //     'minggu' => $mingguId,
    //     'nilai_prediksi' => $prediksi,
    // ]);

    //         // Iterasi minggu & bulan
    //         $mingguKe++;
    //         if ($mingguKe > 4) {
    //             $mingguKe = 1;
    //             $bulanIndex++;
    //         }
    //     }

    //     return redirect()->route('hasiltest.index')->with('success', 'Data prediksi berhasil disimpan.');
    // }

    // public function proses(Request $request)
    // {
    //     $k = 3;

    //     $brandIds = Brand::pluck('id'); // Ambil semua ID brand

    //     // Ambil ID bulan sesuai urutan yang diinginkan
    //     $bulanIds = Bulan::whereIn('nama', ['Januari', 'Februari', 'Maret', 'April'])
    //         ->orderByRaw("FIELD(nama, 'Januari', 'Februari', 'Maret', 'April')")
    //         ->pluck('id')
    //         ->toArray();

    //     // Ambil ID minggu (diasumsikan minggu 1-4)
    //     $mingguIds = Minggu::orderBy('id')->pluck('id')->toArray();

    //     foreach ($brandIds as $brandId) {
    //         $trainings = Training::where('brands', $brandId)->get();
    //         $testings = Testing::where('brands', $brandId)->get();

    //         $mingguKe = 1;
    //         $bulanIndex = 0;

    //         // Hapus hasil lama untuk brand ini
    //         Hasil::where('brands', $brandId)->delete();

    //         foreach ($testings as $testing) {
    //             $distances = [];

    //             foreach ($trainings as $training) {
    //                 $distance = sqrt(
    //                     pow($testing->data_1 - $training->data_1, 2) +
    //                     pow($testing->data_2 - $training->data_2, 2) +
    //                     pow($testing->data_3 - $training->data_3, 2)
    //                 );

    //                 $distances[] = [
    //                     'distance' => $distance,
    //                     'target' => $training->target,
    //                 ];
    //             }

    //             usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);

    //             $nearest = array_slice($distances, 0, $k);
    //             $totalTarget = array_sum(array_column($nearest, 'target'));
    //             $prediksi = round($totalTarget / $k);

    //             $bulanId = $bulanIds[$bulanIndex];
    //             $mingguId = $mingguIds[$mingguKe - 1];

    //             Hasil::create([
    //                 'brands' => $brandId,
    //                 'bulan' => $bulanId,
    //                 'minggu' => $mingguId,
    //                 'nilai_prediksi' => $prediksi,
    //             ]);

    //             $mingguKe++;
    //             if ($mingguKe > 4) {
    //                 $mingguKe = 1;
    //                 $bulanIndex++;
    //             }
    //         }
    //     }

    //     return redirect()->route('hasiltest.index')->with('success', 'Prediksi berhasil dihitung untuk semua brand.');
    // }

    // public function proses(Request $request)
    // {
    //     $k = 3;

    //     // Kosongkan tabel hasil terlebih dahulu
    //     Hasil::truncate();

    //     for ($brandId = 1; $brandId <= 11; $brandId++) {
    //         $trainings = Training::where('brands', $brandId)->get();
    //         $testings = Testing::where('brands', $brandId)->get();

    //         $hasilPerBulan = [];

    //         foreach ($testings as $index => $testing) {
    //             $distances = [];

    //             foreach ($trainings as $training) {
    //                 $distance = sqrt(
    //                     pow($testing->data_1 - $training->data_1, 2) +
    //                     pow($testing->data_2 - $training->data_2, 2) +
    //                     pow($testing->data_3 - $training->data_3, 2)
    //                 );

    //                 $distances[] = [
    //                     'distance' => $distance,
    //                     'target' => $training->target,
    //                 ];
    //             }

    //             usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);

    //             $nearest = array_slice($distances, 0, $k);
    //             $totalTarget = array_sum(array_column($nearest, 'target'));
    //             $prediksi = round($totalTarget / $k);

    //             // Hitung bulan dan minggu
    //             $bulan = intdiv($index, 4) + 1;
    //             $minggu = ($index % 4) + 1;

    //             $hasilPerBulan[$bulan][] = [
    //                 'brand' => $brandId,
    //                 'bulan' => $bulan,
    //                 'minggu' => $minggu,
    //                 'nilai_prediksi' => $prediksi,
    //             ];
    //         }

    //         // Simpan ke DB, hanya 1 baris per bulan yang punya total_bulan
    //         foreach ($hasilPerBulan as $bulan => $mingguList) {
    //             $total = array_sum(array_column($mingguList, 'nilai_prediksi'));

    //             foreach ($mingguList as $i => $item) {
    //                 Hasil::create([
    //                     'brands' => $item['brand'],
    //                     'bulan' => $item['bulan'],
    //                     'minggu' => $item['minggu'],
    //                     'nilai_prediksi' => $item['nilai_prediksi'],
    //                     'total_bulan' => $i === 0 ? $total : 0, // Hanya baris pertama tiap bulan
    //                 ]);
    //             }
    //         }
    //     }

    //     return redirect()->route('hasiltest.index')->with('success', 'Data Training berhasil diambil.');
    // }

    // public function proses(Request $request)
    // {
    //     $k = 3;

    //     $allBrands = Brand::all();

    //     foreach ($allBrands as $brand) {
    //         $brandId = $brand->id;

    //         $trainings = Training::where('brands', $brandId)->get();
    //         $testings = Testing::where('brands', $brandId)->get();

    //         $hasilPerBulan = [];

    //         foreach ($testings as $index => $testing) {
    //             $distances = [];

    //             foreach ($trainings as $training) {
    //                 $distance = sqrt(
    //                     pow($testing->data_1 - $training->data_1, 2) +
    //                     pow($testing->data_2 - $training->data_2, 2) +
    //                     pow($testing->data_3 - $training->data_3, 2)
    //                 );

    //                 $distances[] = [
    //                     'distance' => $distance,
    //                     'target' => $training->target,
    //                 ];
    //             }

    //             usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
    //             $nearest = array_slice($distances, 0, $k);
    //             $totalTarget = array_sum(array_column($nearest, 'target'));
    //             $prediksi = round($totalTarget / $k);

    //             $bulan = intdiv($index, 4) + 1;
    //             $minggu = ($index % 4) + 1;

    //             $hasilPerBulan[$bulan][] = [
    //                 'brand' => $brandId,
    //                 'bulan' => $bulan,
    //                 'minggu' => $minggu,
    //                 'nilai_prediksi' => $prediksi,
    //             ];
    //         }

    //         foreach ($hasilPerBulan as $bulan => $mingguList) {
    //             $total = array_sum(array_column($mingguList, 'nilai_prediksi'));

    //             foreach ($mingguList as $i => $item) {
    //                 Hasil::create([
    //                     'brands' => $item['brand'],
    //                     'bulan' => $item['bulan'],
    //                     'minggu' => $item['minggu'],
    //                     'nilai_prediksi' => $item['nilai_prediksi'],
    //                     'total_bulan' => $i === 0 ? $total : 0,
    //                 ]);
    //             }
    //         }
    //     }

    //     return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil diambil.');
    // }

    // public function proses(Request $request)
    // {
    //     $k = 3;

    //     $allBrands = Brand::all();

    //     foreach ($allBrands as $brand) {
    //         $brandId = $brand->id;

    //         $trainings = Training::where('brands', $brandId)->get();
    //         $testings = Testing::where('brands', $brandId)->get();

    //         $hasilPerBulan = [];

    //         foreach ($testings as $index => $testing) {
    //             $distances = [];

    //             foreach ($trainings as $training) {
    //                 $distance = sqrt(pow($testing->data_1 - $training->data_1, 2) + pow($testing->data_2 - $training->data_2, 2) + pow($testing->data_3 - $training->data_3, 2));

    //                 $distances[] = [
    //                     'distance' => $distance,
    //                     'target' => $training->target,
    //                 ];
    //             }

    //             usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
    //             $nearest = array_slice($distances, 0, $k);
    //             $totalTarget = array_sum(array_column($nearest, 'target'));
    //             $prediksi = round($totalTarget / $k);

    //             // Ambil bulan dari sample yang sesuai
    //             $sample = Sample::find($testing->id);
    //             $bulan = $sample ? $sample->bulan : 1;
    //             $minggu = ($index % 4) + 1;

    //             $hasilPerBulan[$bulan][] = [
    //                 'brand' => $brandId,
    //                 'bulan' => $bulan,
    //                 'minggu' => $minggu,
    //                 'nilai_prediksi' => $prediksi,
    //             ];
    //         }

    //         foreach ($hasilPerBulan as $bulan => $mingguList) {
    //             $total = array_sum(array_column($mingguList, 'nilai_prediksi'));

    //             foreach ($mingguList as $i => $item) {
    //                 Hasil::create([
    //                     'brands' => $item['brand'],
    //                     'bulan' => $item['bulan'],
    //                     'minggu' => $item['minggu'],
    //                     'nilai_prediksi' => $item['nilai_prediksi'],
    //                     'total_bulan' => $i === 0 ? $total : 0,
    //                 ]);
    //             }
    //         }
    //     }

    //     return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil diambil.');
    // }

    public function proses(Request $request)
    {
        $k = 3;

        $allBrands = Brand::all();

        // Ambil bulan dan minggu dari brand pertama sebagai acuan
        $firstBrandId = $allBrands->first()->id;
        $referenceTesting = Testing::where('brands', $firstBrandId)->get();

        $bulanMingguMap = [];

        foreach ($referenceTesting as $index => $test) {
            $sample = Sample::find($test->id);
            $bulan = $sample ? $sample->bulan : 1;
            $minggu = ($index % 4) + 1;

            $bulanMingguMap[$index] = [
                'bulan' => $bulan,
                'minggu' => $minggu,
            ];
        }

        // Proses untuk semua brand dengan acuan bulan/minggu
        foreach ($allBrands as $brand) {
            $brandId = $brand->id;

            $trainings = Training::where('brands', $brandId)->get();
            $testings = Testing::where('brands', $brandId)->get();

            $hasilPerBulan = [];

            foreach ($testings as $index => $testing) {
                $distances = [];

                foreach ($trainings as $training) {
                    $distance = sqrt(pow($testing->data_1 - $training->data_1, 2) + pow($testing->data_2 - $training->data_2, 2) + pow($testing->data_3 - $training->data_3, 2));

                    $distances[] = [
                        'distance' => $distance,
                        'target' => $training->target,
                    ];
                }

                usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
                $nearest = array_slice($distances, 0, $k);
                $totalTarget = array_sum(array_column($nearest, 'target'));
                $prediksi = round($totalTarget / $k);

                $bulan = $bulanMingguMap[$index]['bulan'];
                $minggu = $bulanMingguMap[$index]['minggu'];

                $hasilPerBulan[$bulan][] = [
                    'brand' => $brandId,
                    'bulan' => $bulan,
                    'minggu' => $minggu,
                    'nilai_prediksi' => $prediksi,
                ];
            }

            foreach ($hasilPerBulan as $bulan => $mingguList) {
                $total = array_sum(array_column($mingguList, 'nilai_prediksi'));

                foreach ($mingguList as $i => $item) {
                    Hasil::create([
                        'brands' => $item['brand'],
                        'bulan' => $item['bulan'],
                        'minggu' => $item['minggu'],
                        'nilai_prediksi' => $item['nilai_prediksi'],
                        'total_bulan' => $i === 0 ? $total : 0,
                    ]);
                }
            }
        }

        return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil diambil.');
    }

    public function reset()
    {
        DB::table('hasil')->truncate();

        return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil direset.');
    }
}
