<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Barryvdh\DomPDF\Facade\Pdf;

class MonitoringController extends Controller
{
    public function index(Request $request)
    {
        $filters = [
            'periode' => $request->periode ?? date('Y-m'),
            'jenis' => $request->jenis,
            'status' => $request->status,
            'search' => $request->search,
        ];
        Session::put('monitoring_filters', $filters);
        $hasFilter = $request->has('periode') || $request->has('jenis') || $request->has('status') || $request->has('search');
        if ($hasFilter) {
            Session::put('monitoring_filters', $filters);
            Session::put('monitoring_filtered', true);
        }
        [$tahun, $bulan] = explode('-', $filters['periode']);
        $bulan = (int) $bulan;
        $tahun = (int) $tahun;
        $totalBarang = DB::table('items')
            ->where('kategori', 0)
            ->count();
        $dataMonitoring = DB::table('prediction_results as p')
            ->join('item_usage_monthly as u', function ($join) {
                $join->on('u.kode', '=', 'p.kode')
                    ->on('u.bulan', '=', 'p.bulan_prediksi')
                    ->on('u.tahun', '=', 'p.tahun_prediksi');
            })
            ->join('items as i', 'i.kode', '=', 'p.kode')
            ->where('i.kategori', 0)
            ->where('p.bulan_prediksi', $bulan)
            ->where('p.tahun_prediksi', $tahun)
            ->distinct()
            ->count('p.kode');
        $barangBelumDimonitor = $totalBarang - $dataMonitoring;
        if ($barangBelumDimonitor < 0) {
            $barangBelumDimonitor = 0;
        }
        $monitoringData = DB::table('prediction_results as p')
            ->join('items as i', 'i.kode', '=', 'p.kode')
            ->join('item_usage_monthly as u', function ($join) {
                $join->on('u.kode', '=', 'p.kode')
                    ->on('u.bulan', '=', 'p.bulan_prediksi')
                    ->on('u.tahun', '=', 'p.tahun_prediksi');
            })
            ->where('i.kategori', 0)
            ->where('p.bulan_prediksi', $bulan)
            ->where('p.tahun_prediksi', $tahun)
            ->when($filters['jenis'], function ($query) use ($filters) {
                $query->where('i.jenis', $filters['jenis']);
            })
            ->when($filters['status'], function ($query) use ($filters) {
                if ($filters['status'] == 'naik') {
                    $query->whereRaw('
        p.jumlah_prediksi > u.total_pemakaian
    ');
                } elseif ($filters['status'] == 'turun') {
                    $query->whereRaw('
        p.jumlah_prediksi < u.total_pemakaian
    ');
                } elseif ($filters['status'] == 'stabil') {
                    $query->whereRaw('
        p.jumlah_prediksi = u.total_pemakaian
    ');
                }
            })
            ->when($filters['search'], function ($query) use ($filters) {
                $query->where(function ($q) use ($filters) {
                    $q->where('p.kode', 'like', '%' . $filters['search'] . '%')
                        ->orWhere('i.nama_barang', 'like', '%' . $filters['search'] . '%');
                });
            })
            ->select(
                'p.kode',
                'i.nama_barang',
                'i.jenis',
                'i.satuan',
                'i.fluktuatif',
                'u.total_pemakaian as pemakaian_terakhir',
                'u.bulan as bulan_terakhir',
                'u.tahun as tahun_terakhir',
                'p.jumlah_prediksi',
                'p.tanggal_prediksi',
                DB::raw('
                    (p.jumlah_prediksi - u.total_pemakaian)
                    as selisih
                '),
                DB::raw("
                    CASE
                        WHEN p.jumlah_prediksi > u.total_pemakaian
                            THEN 'naik'
                        WHEN p.jumlah_prediksi < u.total_pemakaian
                            THEN 'turun'
                        ELSE 'stabil'
                    END as status
                ")
            )
            ->orderBy('p.kode')
            ->get();
        $barangTidakStabil = $monitoringData
            ->where('status', '!=', 'stabil')
            ->count();
        $totalNaik = $monitoringData
            ->where('status', 'naik')
            ->count();
        $totalTurun = $monitoringData
            ->where('status', 'turun')
            ->count();
        $totalStabil = $monitoringData
            ->where('status', 'stabil')
            ->count();
        $totalStatus = $totalNaik + $totalTurun + $totalStabil;
        if ($totalStatus == 0) {
            $persenNaik = 0;
            $persenStabil = 0;
            $persenTurun = 0;
        } else {
            $persenNaik = round(($totalNaik / $totalStatus) * 100, 1);
            $persenStabil = round(($totalStabil / $totalStatus) * 100, 1);
            $persenTurun = round(($totalTurun / $totalStatus) * 100, 1);
        }
        $jenisList = DB::table('items')
            ->select('jenis')
            ->whereNotNull('jenis')
            ->distinct()
            ->orderBy('jenis')
            ->pluck('jenis');
        $minDateUsage = DB::table('item_usage_monthly')
            ->selectRaw('MIN(CONCAT(tahun,"-",LPAD(bulan,2,"0"))) as min_date')
            ->value('min_date');
        $maxDateUsage = DB::table('item_usage_monthly')
            ->selectRaw('MAX(CONCAT(tahun,"-",LPAD(bulan,2,"0"))) as max_date')
            ->value('max_date');
        $minDatePrediksi = DB::table('prediction_results')
            ->selectRaw('MIN(CONCAT(tahun_prediksi,"-",LPAD(bulan_prediksi,2,"0"))) as min_date')
            ->value('min_date');
        $maxDatePrediksi = DB::table('prediction_results')
            ->selectRaw('MAX(CONCAT(tahun_prediksi,"-",LPAD(bulan_prediksi,2,"0"))) as max_date')
            ->value('max_date');
        $minPeriode = min(array_filter([$minDateUsage, $minDatePrediksi]));
        $maxPeriode = max(array_filter([$maxDateUsage, $maxDatePrediksi]));
        $availablePeriods = DB::table('item_usage_monthly')
            ->selectRaw('DISTINCT CONCAT(tahun,"-",LPAD(bulan,2,"0")) as periode')
            ->pluck('periode')
            ->toArray();
        $availablePeriodsPrediksi = DB::table('prediction_results')
            ->selectRaw('DISTINCT CONCAT(tahun_prediksi,"-",LPAD(bulan_prediksi,2,"0")) as periode')
            ->pluck('periode')
            ->toArray();
        $availablePeriods = array_values(array_unique(array_merge($availablePeriods, $availablePeriodsPrediksi)));
        $periodeUsage = DB::table('item_usage_monthly')
            ->select('tahun', 'bulan')
            ->distinct();
        $periodePrediksi = DB::table('prediction_results')
            ->select('tahun_prediksi as tahun', 'bulan_prediksi as bulan')
            ->distinct();
        $periode = $periodeUsage
            ->union($periodePrediksi)
            ->get()
            ->map(function ($item) {
                return [
                    'value' => $item->tahun . '-' . str_pad($item->bulan, 2, '0', STR_PAD_LEFT),
                    'label' => $item->bulan . '/' . $item->tahun
                ];
            })
            ->unique('value')
            ->values()
            ->sortByDesc('value');
        return view('monitoring-prediksi', [
            'filters' => $filters,
            'jenisList' => $jenisList,
            'minPeriode' => $minPeriode,
            'maxPeriode' => $maxPeriode,
            'availablePeriods' => $availablePeriods,
            'totalBarang' => $totalBarang,
            'dataMonitoring' => $dataMonitoring,
            'barangBelumDimonitor' => $barangBelumDimonitor,
            'barangTidakStabil' => $barangTidakStabil,
            'monitoringData' => $monitoringData,
            'totalNaik' => $totalNaik,
            'totalTurun' => $totalTurun,
            'totalStabil' => $totalStabil,
            'persenNaik' => $persenNaik,
            'persenStabil' => $persenStabil,
            'persenTurun' => $persenTurun
        ]);
    }

    public function printPdf(Request $request)
    {
        $filters = [
            'periode' => $request->periode ?? date('Y-m'),
            'jenis' => $request->jenis,
            'status' => $request->status,
            'search' => $request->search,
        ];
        if (!Session::has('monitoring_filters')) {
            return redirect()->back()->with('error', 'Silakan klik Tampilkan terlebih dahulu sebelum mencetak.');
        }
        [$tahun, $bulan] = explode('-', $filters['periode']);
        $bulan = (int) $bulan;
        $tahun = (int) $tahun;
        $monitoringData = DB::table('prediction_results as p')
            ->join('items as i', 'i.kode', '=', 'p.kode')
            ->join('item_usage_monthly as u', function ($join) {
                $join->on('u.kode', '=', 'p.kode')
                    ->on('u.bulan', '=', 'p.bulan_prediksi')
                    ->on('u.tahun', '=', 'p.tahun_prediksi');
            })
            ->where('i.kategori', 0)
            ->where('p.bulan_prediksi', $bulan)
            ->where('p.tahun_prediksi', $tahun)
            ->when($filters['jenis'], function ($query) use ($filters) {
                $query->where('i.jenis', $filters['jenis']);
            })
            ->when($filters['status'], function ($query) use ($filters) {
                if ($filters['status'] == 'naik') {
                    $query->whereRaw('
        p.jumlah_prediksi > u.total_pemakaian
    ');
                } elseif ($filters['status'] == 'turun') {
                    $query->whereRaw('
        p.jumlah_prediksi < u.total_pemakaian
    ');
                } elseif ($filters['status'] == 'stabil') {
                    $query->whereRaw('
        p.jumlah_prediksi = u.total_pemakaian
    ');
                }
            })
            ->when($filters['search'], function ($query) use ($filters) {
                $query->where(function ($q) use ($filters) {
                    $q->where('p.kode', 'like', '%' . $filters['search'] . '%')
                        ->orWhere('i.nama_barang', 'like', '%' . $filters['search'] . '%');
                });
            })
            ->select(
                'p.kode',
                'i.nama_barang',
                'i.jenis',
                'i.satuan',
                'u.total_pemakaian as pemakaian_terakhir',
                'u.bulan as bulan_terakhir',
                'u.tahun as tahun_terakhir',
                'p.jumlah_prediksi',
                'p.tanggal_prediksi',
                DB::raw('(p.jumlah_prediksi - u.total_pemakaian) as selisih'),
                DB::raw("
            CASE
                WHEN p.jumlah_prediksi > u.total_pemakaian THEN 'naik'
                WHEN p.jumlah_prediksi < u.total_pemakaian THEN 'turun'
                ELSE 'stabil'
            END as status
        ")
            )
            ->orderBy('p.kode')
            ->get();
        $totalBarang = $monitoringData->count();
        $totalNaik = $monitoringData->where('status', 'naik')->count();
        $totalTurun = $monitoringData->where('status', 'turun')->count();
        $totalStabil = $monitoringData->where('status', 'stabil')->count();
        $periodeText = \Carbon\Carbon::createFromFormat('Y-m', $filters['periode'])
            ->translatedFormat('F Y');
        $pdf = Pdf::loadView('monitoring-prediksi-pdf', [
            'rows' => $monitoringData,
            'periode' => $periodeText,
            'totalBarang' => $totalBarang,
            'totalNaik' => $totalNaik,
            'totalTurun' => $totalTurun,
            'totalStabil' => $totalStabil,
        ]);
        Session::forget('monitoring_filtered');
        return $pdf->download('monitoring-prediksi.pdf');
    }

    public function delete($kode)
    {
        DB::table('prediction_results')
            ->where('kode', $kode)
            ->delete();
        return response()->json(['success' => true]);
    }
}