<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;

class AdminController extends Controller
{
    public function dashboard()
    {
        // Ambil data total peminjaman berdasarkan jangka waktu
        $data_peminjaman = DB::table('nasabah')
            ->selectRaw('jangka_waktu, SUM(jumlah_pinjaman) as total_pinjaman')
            ->groupBy('jangka_waktu')
            ->orderBy('jangka_waktu')
            ->get();

        // Format data untuk Chart.js
        $jangka_waktu = $data_peminjaman->pluck('jangka_waktu');
        $total_pinjaman = $data_peminjaman->pluck('total_pinjaman');

        // Ambil total nasabah
        $total_nasabah = DB::table('nasabah')->count();

        // Ambil data dari tabel nasabah
        $nasabah = DB::table('nasabah')
            ->select(
                'id_nasabah',
                'nama',
                'jumlah_pinjaman',
                'jangka_waktu',
                'jumlah_setoran',
                'history_pinjaman',
                'setoran_per_bulan',
                'bunga',
                'setoran_dan_bunga',
                'sisa_pinjaman'
            )
            ->orderBy('id_nasabah', 'asc')
            ->get();

        // Konversi data ke array untuk clustering
        $data = [];
        foreach ($nasabah as $n) {
            $data[] = [
                $n->history_pinjaman,
                $n->setoran_per_bulan,
                $n->bunga,
                $n->setoran_dan_bunga,
                $n->sisa_pinjaman
            ];
        }

        // Lakukan perhitungan K-Means Clustering (3 cluster)
        $result = $this->kmeans($data, 2);

        // Hitung jumlah nasabah layak dan tidak layak berdasarkan cluster
        $layak = 0;
        $tidak_layak = 0;
        foreach ($result['clusters'] as $cluster) {
            if ($cluster == 1) {
                $layak++;
            } else {
                $tidak_layak++;
            }
        }


        return view('admin.dashboard', compact('jangka_waktu', 'total_pinjaman', 'total_nasabah', 'layak', 'tidak_layak'));
    }


    public function nasabahdaftar()
    {
        $nasabah = DB::table('nasabah')->get();
        return view('admin.nasabahdaftar', compact('nasabah'));
    }

    public function nasabahtambah()
    {
        return view('admin.nasabahtambah');
    }

    public function nasabahsimpan(Request $request)
    {
        $request->validate([
            'nama' => 'required|string|max:255|unique:nasabah,nama',
            'golongan_pekerjaan' => 'required|string|max:255',
            'status_pekerjaan' => 'required|string|max:255',
            'jumlah_pinjaman' => 'required|numeric',
            'alamat' => 'required|string',
            // 'history_pinjaman' => 'required|string',
            'status' => 'required|string',
            'tabungan_simpanan_wajib' => 'required|numeric',
            'slip_gaji' => 'nullable|file|mimes:pdf,jpg,png|max:2048', // Maks 2MB
        ]);

        $filePath = null;
        if ($request->hasFile('slip_gaji')) {
            $file = $request->file('slip_gaji');
            $fileName = time() . '_' . $file->getClientOriginalName();
            $filePath = 'uploads/' . $fileName;
            $file->move(public_path('uploads'), $fileName);
        }

        DB::table('nasabah')->insert([
            'nama' => $request->nama,
            'golongan_pekerjaan' => $request->golongan_pekerjaan,
            'status_pekerjaan' => $request->status_pekerjaan,
            'jumlah_pinjaman' => $request->jumlah_pinjaman, 
            'alamat' => $request->alamat,
            'history_pinjaman' => $request->history_pinjaman ?? 0,
            'tabungan_simpanan_wajib' => $request->tabungan_simpanan_wajib,
            'slip_gaji' => $filePath,
            'setoran_per_bulan' => $request->setoran_per_bulan,
            'bunga' => $request->bunga,
            'setoran_dan_bunga' => $request->setoran_dan_bunga,
            'sisa_pinjaman' => $request->sisa_pinjaman,
            'jumlah_setoran' => $request->jumlah_setoran,
            'jangka_waktu' => $request->jangka_waktu,
            'status' => $request->status,
            'created_at' => date('Y-m-d H:i:s'),
        ]);

        return redirect()->route('nasabah.daftar')->with('success', 'Data nasabah berhasil disimpan.');
    }

    public function nasabahedit($id)
    {
        $nasabah = DB::table('nasabah')->where('id_nasabah', $id)->first();
        return view('admin.nasabahedit', compact('nasabah'));
    }

    public function nasabahupdate(Request $request, $id)
    {
        $nasabah = DB::table('nasabah')->where('id_nasabah', $id)->first();
        $request->validate([
            'nama' => 'required|string|max:255|unique:nasabah,nama,' . $id . ',id_nasabah',
            'golongan_pekerjaan' => 'required|string|max:255',
            'status_pekerjaan' => 'required|string|max:255',
            'jumlah_pinjaman' => 'required|numeric',
            'alamat' => 'required|string',
            'tabungan_simpanan_wajib' => 'required|numeric',
            'slip_gaji' => 'nullable|file|mimes:pdf,jpg,png|max:2048',
        ]);

        $filePath = $request->slip_gaji_lama;
        if ($request->hasFile('slip_gaji')) {
            $file = $request->file('slip_gaji');
            $fileName = time() . '_' . $file->getClientOriginalName();
            $filePath = 'uploads/' . $fileName;
            $file->move(public_path('uploads'), $fileName);
        }

        DB::table('nasabah')->where('id_nasabah', $id)->update([
            'nama' => $request->nama,
            'golongan_pekerjaan' => $request->golongan_pekerjaan,
            'status_pekerjaan' => $request->status_pekerjaan,
            'jumlah_pinjaman' => $request->jumlah_pinjaman,
            'alamat' => $request->alamat,
            'history_pinjaman' => $request->history_pinjaman ?? 0,
            'tabungan_simpanan_wajib' => $request->tabungan_simpanan_wajib,
            'slip_gaji' => $filePath,
            'setoran_per_bulan' => $request->setoran_per_bulan,
            'bunga' => $request->bunga,
            'setoran_dan_bunga' => $request->setoran_dan_bunga,
            'sisa_pinjaman' => $request->sisa_pinjaman,
            'jumlah_setoran' => $request->jumlah_setoran,
            'status' => $request->status,
            'jangka_waktu' => $request->jangka_waktu,
            'updated_at' => date('Y-m-d H:i:s'),

        ]);


        return redirect()->route('nasabah.daftar')->with('success', 'Data nasabah berhasil diperbarui.');
    }

    public function nasabahhapus($id)
    {
        DB::table('nasabah')->where('id_nasabah', $id)->delete();
        return redirect()->route('nasabah.daftar')->with('success', 'Data nasabah berhasil dihapus.');
    }



    public function datanilai()
    {
        // Ambil data dari tabel nasabah menggunakan DB::table()
        $nasabah = DB::table('nasabah')
            ->select(
                'id_nasabah',
                'nama',
                'jumlah_pinjaman',
                'jangka_waktu',
                'jumlah_setoran',
                'history_pinjaman',
                'setoran_per_bulan',
                'bunga',
                'setoran_dan_bunga',
                'sisa_pinjaman'
            )
            ->where('status', 'Nasabah Lama')
            ->orderBy('id_nasabah', 'asc')
            ->get();

        // Jika tidak ada data, return tanpa clustering
        if ($nasabah->isEmpty()) {
            return view('admin.datanilai', [
                'nasabah' => $nasabah,
                'iterations' => [],
                'initial_centroids' => []
            ]);
        }

        // Konversi data ke array untuk K-Means
        $data = [];
        foreach ($nasabah as $n) {
            $data[] = [
                $n->history_pinjaman,
                $n->setoran_per_bulan,
                $n->bunga,
                $n->setoran_dan_bunga,
                $n->sisa_pinjaman
            ];
        }

        // Lakukan clustering dengan jumlah cluster = 2
        $result = $this->kmeans($data, 2);

        // Gabungkan hasil cluster ke data nasabah
        foreach ($nasabah as $index => $n) {
            $n->cluster = $result['clusters'][$index];
            $n->kelayakan = ($n->cluster == 1) ? 'Layak' : 'Tidak Layak';  // Modify based on your classification logic
        }

        return view('admin.datanilai', [
            'nasabah' => $nasabah,
            'iterations' => $result['iterations'],
            'initial_centroids' => $result['initial_centroids']
        ]);
    }

    private function kmeans($data, $k)
    {
        $numData = count($data);
        if ($numData == 0) {
            return ['clusters' => [], 'iterations' => [], 'initial_centroids' => []];
        }

        // Pilih centroid awal secara acak
        // $initial_centroids = [];
        // $randomKeys = array_rand($data, $k);
        // foreach ($randomKeys as $key) {
        //     $initial_centroids[] = $data[$key];
        // }

        $initial_centroids = [
            $data[0], // gunakan baris data pertama
            $data[1]  // gunakan baris data kedua
        ];

        $clusters = [];
        $iterations = [];
        $changed = true;
        $iterationCount = 1;

        while ($changed) {
            $changed = false;
            $new_clusters = array_fill(0, $k, []);
            $distances = [];

            // Assign setiap data ke centroid terdekat
            foreach ($data as $index => $point) {
                $distances[$index] = [];
                foreach ($initial_centroids as $centroid) {
                    $distances[$index][] = $this->euclideanDistance($point, $centroid);
                }
                $new_cluster = array_search(min($distances[$index]), $distances[$index]);

                if (!isset($clusters[$index]) || $clusters[$index] !== $new_cluster) {
                    $changed = true;
                }

                $clusters[$index] = $new_cluster;
                $new_clusters[$new_cluster][] = $point;
            }

            // Simpan iterasi untuk tampilan
            $iterations[] = [
                'iteration' => $iterationCount,
                'clusters'  => $clusters,
                'distances' => $distances,
                'centroids' => $initial_centroids
            ];
            $iterationCount++;

            // Update centroid berdasarkan rata-rata tiap cluster
            foreach ($new_clusters as $i => $clusterData) {
                if (!empty($clusterData)) {
                    $centroid = [];
                    for ($j = 0; $j < count($clusterData[0]); $j++) {
                        $sum = array_sum(array_column($clusterData, $j));
                        $centroid[] = $sum / count($clusterData);
                    }
                    $initial_centroids[$i] = $centroid;
                }
            }
        }

        return ['clusters' => $clusters, 'iterations' => $iterations, 'initial_centroids' => $initial_centroids];
    }

    private function euclideanDistance($point1, $point2)
    {
        $sum = 0;
        for ($i = 0; $i < count($point1); $i++) {
            $sum += pow($point1[$i] - $point2[$i], 2);
        }
        return sqrt($sum);
    }



    public function laporan()
    {
        // Ambil data dari tabel nasabah
        $nasabah = DB::table('nasabah')
            ->select(
                'id_nasabah',
                'nama',
                'golongan_pekerjaan',
                'status_pekerjaan',
                'tabungan_simpanan_wajib',
                'jumlah_pinjaman',
                'jangka_waktu',
                'jumlah_setoran',
                'history_pinjaman',
                'setoran_per_bulan',
                'bunga',
                'setoran_dan_bunga',
                'sisa_pinjaman'
            )
            ->orderBy('id_nasabah', 'asc')
            ->get();

        // Konversi data ke array untuk clustering
        $data = [];
        foreach ($nasabah as $n) {
            $data[] = [
                $n->history_pinjaman,
                $n->setoran_per_bulan,
                $n->bunga,
                $n->setoran_dan_bunga,
                $n->sisa_pinjaman
            ];
        }
        // Lakukan perhitungan K-Means Clustering (3 cluster)
        $result = $this->kmeans($data, 2);

        // Gabungkan hasil cluster ke data nasabah
        foreach ($nasabah as $index => $n) {
            $n->cluster = $result['clusters'][$index];
            $n->kelayakan = ($n->cluster == 1) ? 'Layak' : 'Tidak Layak';  // Modify based on your classification logic
        }

        // Return ke view dengan data dan cluster
        return view('admin.laporan', compact('nasabah'));
    }


    public function laporancetak()
    {
        // Ambil data dari tabel nasabah
        $nasabah = DB::table('nasabah')
            ->select(
                'id_nasabah',
                'nama',
                'golongan_pekerjaan',
                'status_pekerjaan',
                'tabungan_simpanan_wajib',
                'jumlah_pinjaman',
                'jangka_waktu',
                'jumlah_setoran',
                'history_pinjaman',
                'setoran_per_bulan',
                'bunga',
                'setoran_dan_bunga',
                'sisa_pinjaman'
            )
            ->orderBy('id_nasabah', 'asc')
            ->get();

        // Konversi data ke array untuk clustering
        $data = [];
        foreach ($nasabah as $n) {
            $data[] = [
                $n->history_pinjaman,
                $n->setoran_per_bulan,
                $n->bunga,
                $n->setoran_dan_bunga,
                $n->sisa_pinjaman
            ];
        }

        // Lakukan perhitungan K-Means Clustering (3 cluster)
        $result = $this->kmeans($data, 2);

        // Gabungkan hasil cluster ke data nasabah
        foreach ($nasabah as $index => $n) {
            $n->cluster = $result['clusters'][$index];
            $n->kelayakan = ($n->cluster == 1) ? 'Layak' : 'Tidak Layak';  // Modify based on your classification logic
        }

        // Return ke view dengan data untuk cetak
        return view('admin.laporancetak', compact('nasabah'));
    }

    public function pengaturan()
    {
        return view('admin.pengaturan', ['user' => Auth::user()]);
    }

    public function pengaturansimpan(Request $request)
    {
        $user = Auth::user();

        // Validasi input
        $request->validate([
            'username' => 'required|string|max:255',
            'email' => 'required|email|unique:users,email,' . $user->id,
            'password' => 'nullable|min:6|confirmed',
            'foto' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
        ]);

        // Update foto jika ada upload
        if ($request->hasFile('foto')) {


            // Simpan foto baru
            $fotoName = time() . '.' . $request->foto->extension();
            $request->foto->move(public_path('foto'), $fotoName);
            $user->foto = $fotoName;
        }

        // Update data user
        $user->username = $request->username;
        $user->email = $request->email;

        // Update password jika diisi
        if ($request->password) {
            $user->password = Hash::make($request->password);
        }

        $user->save();

        return redirect()->to('admin/pengaturan')->with('success', 'Profil berhasil diperbarui.');
    }
}
