<?php

namespace App\Http\Controllers\Website;

use App\Http\Controllers\Controller;
use App\Models\CriteriaData;
use App\Models\Plant;
use App\Models\PreferenceResultPlant;
use App\Models\ReferensiAlternatif;
use Illuminate\Http\Request;

class AlternatifReferensiController extends Controller
{
    public function index()
    {
        $plants = Plant::leftJoin('referensi_alternatifs', 'plants.id', '=', 'referensi_alternatifs.plant_id')
            ->whereNull('referensi_alternatifs.plant_id')
            ->select('plants.*')
            ->get();

        $criterias = CriteriaData::all();

        $listReferensiAlternatif = ReferensiAlternatif::select(
            'referensi_alternatifs.id as referensi_alternatifs_id',
            'referensi_alternatifs.plant_id as ra_plant_id',
            'referensi_alternatifs.criteria_id as ra_criteria_id',
            'referensi_alternatifs.value_alternatif',
            'plants.id as plants_id',
            'plants.plant',
            'criteria_data.id as criteria_data_id',
            'criteria_data.criteria',
            'criteria_data.bobot',
            'criteria_data.status'
        )
            ->join('plants', 'plants.id', '=', 'referensi_alternatifs.plant_id')
            ->join('criteria_data', 'criteria_data.id',  '=', 'referensi_alternatifs.criteria_id')
            ->get();

        $groupByPlant = $listReferensiAlternatif->groupBy('ra_plant_id')->map(function ($plantData) {
            $plant = $plantData->first();

            return [
                'plant_id' => $plant->plants_id,
                'plant' => $plant->plant,
                'criteria' => $plantData->map(function ($item) {
                    return [
                        'criteria_id' => $item->criteria_data_id,
                        'criteria' => $item->criteria,
                        'value_alternatif' => $item->value_alternatif,
                        'status' => $item->status,
                        'bobot' => $item->bobot
                    ];
                })->toArray()
            ];
        });

        // dd($groupByPlant);
        return view('website.app.referensi-alternatif', compact('plants', 'criterias', 'groupByPlant'));
    }

    public function addAlternatifReferensi(Request $request)
    {
        $criterias = CriteriaData::all();

        $plantId = $request->input('plantId');

        foreach ($criterias as $key => $value) {
            ReferensiAlternatif::create([
                'plant_id' => $plantId,
                'criteria_id' => $value->id,
                'value_alternatif' => $request->input(str_replace(' ', '_', $value->criteria))
            ]);
            // dd($request, $value, $request->input(str_replace(' ', '_', $value->criteria)));
        }
        toast('Data referensi alternatif berhasil ditambahkan!', 'success');
        return redirect()->back();
    }

    public function updateAlternatifReferensi(Request $request)
    {
        $criterias = CriteriaData::all();

        $plantId = $request->input('plantId');

        foreach ($criterias as $key => $value) {
            ReferensiAlternatif::updateOrCreate(
                [
                    'plant_id' => $plantId,
                    'criteria_id' => $value->id,
                ],
                [
                    'value_alternatif' => $request->input(str_replace(' ', '_', $value->criteria))
                ]
            );
        }

        toast('Data referensi alternatif berhasil diubah!', 'success');
        return redirect()->back();
    }

    public function deleteAlternatifReferensi($id)
    {
        // hapus referensi alternatif
        $referensiAlternatif = ReferensiAlternatif::where('plant_id', '=', $id)->get();
        foreach ($referensiAlternatif as $value) {
            $value->delete();
        }

        // hapus pada relasi preference result plants
        $preferenceResultPlant = PreferenceResultPlant::where('plant_id', '=', $id)->get();
        foreach ($preferenceResultPlant as $value) {
            $value->delete();
        }

        toast('Data alternatif referensi berhasil dihapus', 'success');
        return redirect()->back();
    }

    public function getListAlternatifReferensi()
    {
        $listReferensiAlternatif = ReferensiAlternatif::select(
            'referensi_alternatifs.id as referensi_alternatifs_id',
            'referensi_alternatifs.plant_id as ra_plant_id',
            'referensi_alternatifs.criteria_id as ra_criteria_id',
            'referensi_alternatifs.value_alternatif',
            'plants.id as plants_id',
            'plants.plant',
            'criteria_data.id as criteria_data_id',
            'criteria_data.criteria',
            'criteria_data.bobot',
            'criteria_data.status'
        )
            ->join('plants', 'plants.id', '=', 'referensi_alternatifs.plant_id')
            ->join('criteria_data', 'criteria_data.id',  '=', 'referensi_alternatifs.criteria_id')
            ->get();

        $listCriteria = CriteriaData::all();

        $groupByPlant = $listReferensiAlternatif->groupBy('ra_plant_id')->map(function ($plantData) {
            $plant = $plantData->first();

            return [
                'plant_id' => $plant->plants_id,
                'plant' => $plant->plant,
                'criteria' => $plantData->map(function ($item) {
                    return [
                        'criteria_id' => $item->criteria_data_id,
                        'criteria' => $item->criteria,
                        'value_alternatif' => $item->value_alternatif,
                        'status' => $item->status,
                        'bobot' => $item->bobot
                    ];
                })->toArray()
            ];
        });

        // mengecek apakah jumlah pada setiap criteria sama
        $firstGroupByPlant = count($groupByPlant[1]['criteria']);
        $checkGroupByPlant = true;
        foreach ($groupByPlant as $plant) {
            if (count($plant['criteria']) !== $firstGroupByPlant) {
                $checkGroupByPlant = false;
                break;
            }
        }

        // jika jumlah pada setiap criteria berbeda
        if ($checkGroupByPlant == false) {
            return response()->json([
                'listCriterias' => $listCriteria,
                'groupByPlant' => $groupByPlant,
                'message' => 'fail'
            ]);
        } else {
            // pembagi matriks ternomalisasi
            $countCriteria = count($groupByPlant[1]['criteria']);
            $pembagiMatriksTernomalisasi = [];
            for ($i = 0; $i < $countCriteria; $i++) {
                $sumKuadrat = 0;

                foreach ($groupByPlant as $item) {
                    $sumKuadrat += pow($item["criteria"][$i]["value_alternatif"], 2);
                }

                // Hitung akar dari jumlah kuadrat
                $pembagiMatriksTernomalisasi[$i] = round((sqrt($sumKuadrat)), 5);
            }

            // matrik ternomalisasi referensi (value / pembagi)
            $matriksTernomalisasiReferensi = [];
            foreach ($groupByPlant as $item) {
                $valueBaru = [];
                foreach ($item['criteria'] as $index => $value) {
                    $value['value_alternatif'] = round(($value['value_alternatif'] / $pembagiMatriksTernomalisasi[$index]), 5);
                    $valueBaru[] = [
                        'criteria_id' => $value['criteria_id'],
                        'criteria' => $value['criteria'],
                        'value_alternatif' => $value['value_alternatif'],
                        'status' => $value['status'],
                        'bobot' => $value['bobot']
                    ];
                }
                $matriksTernomalisasiReferensi[] = [
                    'plant_id' => $item['plant_id'],
                    'plant' => $item['plant'],
                    'criteria' => $valueBaru
                ];
            }

            // matrik ternomalisasi referensi (value / pembagi)
            $ternomalisasiTerbobotReferensi = [];
            foreach ($groupByPlant as $item) {
                $valueBaru = [];
                foreach ($item['criteria'] as $index => $value) {
                    $value['value_alternatif'] = round(($value['value_alternatif'] / $pembagiMatriksTernomalisasi[$index]), 5);
                    $valueBaru[] = [
                        'criteria_id' => $value['criteria_id'],
                        'criteria' => $value['criteria'],
                        'value_alternatif' => round(($value['value_alternatif'] * $value['bobot']), 5),
                        'status' => $value['status'],
                        'bobot' => $value['bobot']
                    ];
                }
                $ternomalisasiTerbobotReferensi[] = [
                    'plant_id' => $item['plant_id'],
                    'plant' => $item['plant'],
                    'criteria' => $valueBaru
                ];
            }

            // solusi ideal referensi
            // 1. pengumpulan hasil data terbobot berdasarkan criteria
            $criteria_values = [];
            foreach ($ternomalisasiTerbobotReferensi as $ternomalisasi) {
                foreach ($ternomalisasi['criteria'] as $index => $criteria) {
                    $criteria_values[$index]['criteria_id'] = $criteria['criteria_id'];
                    $criteria_values[$index]['criteria'] = $criteria['criteria'];
                    $criteria_values[$index]['status'] = $criteria['status'];
                    $criteria_values[$index]['values'][] = $criteria['value_alternatif'];
                }
            }

            // 2. menentukan ideal positif dan ideal negatif
            $ideal_positif = [];
            $ideal_negatif = [];

            foreach ($criteria_values as $index => $criteria) {
                if ($criteria['status'] === "benefit") {
                    $ideal_positif[$index] = max($criteria['values']);
                    $ideal_negatif[$index] = min($criteria['values']);
                } else {
                    $ideal_positif[$index] = min($criteria['values']);
                    $ideal_negatif[$index] = max($criteria['values']);
                }
            }

            // solusi ideal terbobot referensi
            $determinanReferensi = [];
            foreach ($ternomalisasiTerbobotReferensi as $ternomalisasi) {
                $jumlahDeterminanPositif = 0;
                $jumlahDeterminanNegatif = 0;
                foreach ($ternomalisasi['criteria'] as $index => $criteria) {
                    $jumlahDeterminanPositif += pow(($criteria['value_alternatif'] - $ideal_positif[$index]), 2);
                    $jumlahDeterminanNegatif += pow(($criteria['value_alternatif'] - $ideal_negatif[$index]), 2);
                }
                $determinanReferensi[] = [
                    'id' => $ternomalisasi['plant_id'],
                    'plant' => $ternomalisasi['plant'],
                    'determinanPositif' => round((sqrt($jumlahDeterminanPositif)), 5),
                    'determinanNegatif' => round((sqrt($jumlahDeterminanNegatif)), 5)
                ];
            }

            return response()->json([
                'listCriterias' => $listCriteria,
                'groupByPlant' => $groupByPlant,
                'pembagiMatriksTernomalisasi' => $pembagiMatriksTernomalisasi,
                'matriksTernomalisasiReferensi' => $matriksTernomalisasiReferensi,
                'ternomalisasiTerbobotReferensi' => $ternomalisasiTerbobotReferensi,
                'solusiIdealPositif' => $ideal_positif,
                'solusiIdealNegatif' => $ideal_negatif,
                'determinanReferensi' => $determinanReferensi
            ]);
        }
    }

    public function addPreferensiResultReferensi()
    {
        $response = $this->getListAlternatifReferensi();

        $data = json_decode($response->getContent(), true);

        $preferenceResultPlant = $data['determinanReferensi'];
        foreach ($preferenceResultPlant as $preference) {
            // dd($preference, round($preference['determinanNegatif'] / ($preference['determinanNegatif'] + $preference['determinanPositif']), 5), $month, $year);
            PreferenceResultPlant::updateOrCreate(
                [
                    'plant_id' => $preference['id'],
                ],
                [
                    'value_preference' => round($preference['determinanNegatif'] / ($preference['determinanNegatif'] + $preference['determinanPositif']), 5)
                ]
            );
        }

        return response()->json([
            'message' => 'success'
        ]);
    }
}
