<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use App\Models\DataAlumni;
use App\Models\Jabatan;
use App\Models\TahunAngkatan;

class ProsesKmeansController extends Controller
{
    public function index()
    {
        $angkatan = TahunAngkatan::all();
        $jabatanMap = Jabatan::pluck('Kategori_bidang_kerja', 'id_kategori')->toArray();

        return view('proses_klasifikasi', compact('angkatan', 'jabatanMap'));
    }

    public function proses(Request $request)
    {
        $request->validate([
            'id_angkatan' => 'required',
        ]);

        $id_angkatan = $request->id_angkatan;
        // Ambil list angkatan untuk dropdown di view
        $angkatan = TahunAngkatan::all();

        // Ambil data alumni sesuai angkatan
        $data = DataAlumni::with(['jabatan', 'kualifikasiBidang', 'tahunAngkatan'])
            ->where('angkatan', $id_angkatan)
            ->get();

        if ($data->isEmpty()) {
            return redirect()->back()->with('error', 'Data alumni untuk angkatan tersebut tidak ditemukan.');
        }

        // Siapkan dataset numerik untuk K-Means
        $dataset = $data->map(function ($item) {
            return [
                'id'          => $item->id_alumni,
                'nama'        => $item->nama,
                'nim'         => $item->nim,
                'angkatan'    => optional($item->tahunAngkatan)->tahun,
                'pekerjaan'   => $item->pekerjaan,
                // 'jabatan'     => optional($item->jabatan)->nilai ?? 0,
                'jabatan' => is_object($item->jabatan) ? $item->jabatan->nilai : (isset($item->jabatan) ? $item->jabatan : 0),
                'kualifikasi' => optional($item->kualifikasiBidang)->nilai ?? 0,
            ];
        })->toArray();

        // Inisialisasi centroid awal (manual)
        $centroids = [
            ['jabatan' => 1, 'kualifikasi' => 0], //C0
            ['jabatan' => 3, 'kualifikasi' => 3], //C1
            ['jabatan' => 6, 'kualifikasi' => 6], //C2
        ];

        $centroid_awal = json_encode($centroids);

        // Define cluster labels
        $clusterLabels = [
            0 => 'TIDAK SESUAI',
            1 => 'KURANG SESUAI',
            2 => 'SESUAI'
        ];

        $maxIterasi = 10;
        $hasil_iterasi = [];

        // Proses iterasi
        for ($iterasi = 1; $iterasi <= $maxIterasi; $iterasi++) {
            $clusters = [];
            // Assign ke cluster terdekat
            foreach ($dataset as $item) {
                $jarak = array_map(function ($cent) use ($item) {
                    return sqrt(
                        pow($item['jabatan'] - $cent['jabatan'], 2) +
                        pow($item['kualifikasi'] - $cent['kualifikasi'], 2)
                    );
                }, $centroids);
                $cluster_id = array_search(min($jarak), $jarak);
                $clusters[$cluster_id][] = $item;
            }

            // Hitung centroid baru
            $newCentroids = [];
            foreach (range(0, count($centroids) - 1) as $ci) {
                if (!empty($clusters[$ci])) {
                    $avgJabatan     = collect($clusters[$ci])->avg('jabatan');
                    $avgKualifikasi = collect($clusters[$ci])->avg('kualifikasi');
                    $newCentroids[] = [
                        'jabatan'     => round($avgJabatan, 4),
                        'kualifikasi' => round($avgKualifikasi, 4),
                    ];
                } else {
                    // Pertahankan centroid lama jika kosong
                    $newCentroids[] = $centroids[$ci];
                }
            }

            // Kumpulkan data untuk tampilan iterasi ini
            $iterData = [];
            $timestamp = Carbon::now()->format('d-m-Y H:i');
            foreach ($dataset as $item) {
                $jarak = array_map(function ($cent) use ($item) {
                    return sqrt(
                        pow($item['jabatan'] - $cent['jabatan'], 2) +
                        pow($item['kualifikasi'] - $cent['kualifikasi'], 2)
                    );
                }, $centroids);
                $cluster_id = array_search(min($jarak), $jarak);
                $iterData[] = [
                    'id'            => $item['id'],
                    'nama'          => $item['nama'],
                    'nim'           => $item['nim'],
                    'angkatan'      => $item['angkatan'],
                    'pekerjaan'     => $item['pekerjaan'],
                    'jabatan'       => $item['jabatan'],
                    'kualifikasi'   => $item['kualifikasi'],
                    'cluster'       => $cluster_id,
                    // 'klasifikasi'   => 'Cluster ' . ($cluster_id + 1),
                    'klasifikasi'   => 'Cluster ' . ($cluster_id) . ' - ' . $clusterLabels[$cluster_id],
                    'waktu_proses'  => $timestamp,
                ];

                // Simpan data hasil klasifikasi dari iterasi terakhir
                if ($iterasi == $maxIterasi || $newCentroids === $centroids) {
                    $finalData[] = [
                        'id' => $item['id'],
                        'cluster' => $cluster_id
                    ];
                } 
            }

            $hasil_iterasi[] = [
                'iterasi'   => $iterasi,
                'centroids' => $centroids,
                'data'      => $iterData,
            ];

            if ($newCentroids === $centroids) {
                // Update finalData jika konvergen sebelum iterasi maksimum
                $finalData = []; // Reset dulu
                foreach ($iterData as $item) {
                    $finalData[] = [
                        'id' => $item['id'],
                        'cluster' => $item['cluster']
                    ];
                }
                break;
            }
            $centroids = $newCentroids;
        }

        // Hasil centroid akhir
        $centroid_akhir = $centroids;
        // Jumlah iterasi yang dilakukan
        $jumlah_iterasi = count($hasil_iterasi);

        // Keterangan klasifikasi untuk tampilan
        $keterangan_klasifikasi = [
            'C0' => 'TIDAK SESUAI',
            'C1' => 'KURANG SESUAI',
            'C2' => 'SESUAI'
        ];
        // Encode centroid akhir untuk disimpan ke database
        // $centroid_akhir_json = json_encode($centroid_akhir);
        
        // return view('proses_klasifikasi', [
        //     'angkatan'       => $angkatan,
        //     'jabatanMap'     => Jabatan::pluck('Kategori_bidang_kerja', 'id_kategori')->toArray(),
        //     'hasil_iterasi'  => $hasil_iterasi,
        //     'centroid_awal'  => $centroid_awal,
        //     'centroid_akhir' => $centroid_akhir,
        //     'centroid_akhir_json' => $centroid_akhir_json,
        //     'id_angkatan'    => $id_angkatan,
        //     'keterangan_klasifikasi' => $keterangan_klasifikasi,
        //     'jumlah_iterasi' => $jumlah_iterasi,
        //     'finalData'      => $finalData, // Data yang akan disimpan
        
        $centroid_akhir_json = json_encode($centroid_akhir);
        
        return view('proses_klasifikasi', [
            'angkatan'       => $angkatan,
            'jabatanMap'     => Jabatan::pluck('Kategori_bidang_kerja', 'id_kategori')->toArray(),
            'hasil_iterasi'  => $hasil_iterasi,
            'centroid_awal'  => $centroid_awal,
            'centroid_akhir' => $centroid_akhir,
            'centroid_akhir_json' => $centroid_akhir_json,
            'id_angkatan'    => $id_angkatan,
            'keterangan_klasifikasi' => $keterangan_klasifikasi,
            'jumlah_iterasi' => $jumlah_iterasi,
            'finalData'      => $finalData, // Data yang akan disimpan
        ]);
    }

}
