<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Helpdesk;
use App\Models\Artikel;
use App\Models\Faq;
use App\Models\HasilPrediksi;
use App\Models\DataPenjualan;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;

class DashboardAdminControllers extends Controller
{
    public function index(Request $request)
    {
        // Mengubah ke format Array untuk membuang spasi gaib penyebab error 'role' dan 'status'
        $totalUser = User::where(['role' => 'user'])->count();
        $pendingBantuan = Helpdesk::where(['status' => 'pending'])->count();
        $totalArtikel = Artikel::count();
        $totalFaq = Faq::count();

        $rerataPenjualan = (int) round(DataPenjualan::avg('jumlah') ?? 0);

        $selectedPangkalanId = $request->filled('pangkalan_id') ? (string) $request->input('pangkalan_id') : null;

        if ($selectedPangkalanId !== null) {
            $lastTransaction = DataPenjualan::where(['user_id' => $selectedPangkalanId])->orderBy('tanggal', 'desc')->first();
        } else {
            $lastTransaction = DataPenjualan::orderBy('tanggal', 'desc')->first();
        }
        
        $baseDate = $lastTransaction ? Carbon::parse($lastTransaction->tanggal) : Carbon::today();

        /** @var Collection $pangkalanList */
        $pangkalanList = User::where(['role' => 'user'])->get();

        $salesChart = $this->generateSalesChartData($baseDate, $selectedPangkalanId);
        $chartDates = $salesChart['dates'];
        $chartLabels = $salesChart['labels'];
        $lineChartData = $salesChart['data'];
        $totalDataAsliTersedia = $salesChart['total'];

        $predictionChart = $this->generatePredictionChartData($baseDate, $selectedPangkalanId);
        $predictionDates = $predictionChart['dates'];
        $predictionLabels = $predictionChart['labels'];
        $predictionChartData = $predictionChart['data'];
        $totalPrediksiTersedia = $predictionChart['total'];

        $pieData = $this->generatePieData();
        $aktivitasPrediksi = $this->generateAktivitasLogData($pangkalanList);
        $recentBantuan = Helpdesk::with('user')->latest()->take(5)->get();

        return view('admin.dashboard.index', compact(
            'totalUser', 'pendingBantuan', 'totalArtikel', 'totalFaq', 'pangkalanList', 'selectedPangkalanId',
            'rerataPenjualan', 'lineChartData', 'chartDates', 'chartLabels', 'totalDataAsliTersedia',
            'pieData', 'aktivitasPrediksi', 'predictionChartData', 'predictionDates', 'predictionLabels', 'totalPrediksiTersedia', 'recentBantuan'
        ));
    }

    private function generateSalesChartData(Carbon $baseDate, ?string $selectedPangkalanId): array
    {
        $chartDates = collect();
        for ($i = 6; $i >= 0; $i--) {
            $chartDates->push((clone $baseDate)->subDays($i)->format('Y-m-d'));
        }
        
        $chartLabels = $chartDates->map(function($d) {
            return Carbon::parse($d)->locale('id')->translatedFormat('d M');
        })->toArray();
            
        $lineChartData = [];
        $totalDataAsliTersedia = 0;

        if ($selectedPangkalanId !== null) {
            $pangkalan = User::where(['role' => 'user'])->find($selectedPangkalanId);
            if ($pangkalan) {
                $pangkalanData = [];
                foreach ($chartDates as $date) {
                    // Menggunakan struktur array pasangkan data kolom secara presisi
                    $nilaiJual = (int) DataPenjualan::where(['user_id' => $pangkalan->id, 'tanggal' => $date])->sum('jumlah');
                    $pangkalanData[] = $nilaiJual;
                    $totalDataAsliTersedia += $nilaiJual;
                }
                $lineChartData[] = [
                    'label' => $pangkalan->name,
                    'data' => $pangkalanData
                ];
            }
        } else {
            $globalSalesData = [];
            foreach ($chartDates as $date) {
                $nilaiJualGlobal = (int) DataPenjualan::where(['tanggal' => $date])->sum('jumlah');
                $globalSalesData[] = $nilaiJualGlobal;
                $totalDataAsliTersedia += $nilaiJualGlobal;
            }
            $lineChartData[] = [
                'label' => 'Total Volume Seluruh Pangkalan',
                'data' => $globalSalesData
            ];
        }

        return [
            'dates'  => $chartDates,
            'labels' => $chartLabels,
            'data'   => $lineChartData,
            'total'  => $totalDataAsliTersedia
        ];
    }

    private function generatePredictionChartData(Carbon $baseDate, ?string $selectedPangkalanId): array
    {
        $predictionDates = collect();
        for ($i = 1; $i <= 7; $i++) {
            $predictionDates->push((clone $baseDate)->addDays($i)->format('Y-m-d'));
        }

        $predictionLabels = $predictionDates->map(function($d) {
            return Carbon::parse($d)->locale('id')->translatedFormat('d M');
        })->toArray();

        $predictionChartData = [];
        $totalPrediksiTersedia = 0;

        if ($selectedPangkalanId !== null) {
            $pangkalan = User::where(['role' => 'user'])->find($selectedPangkalanId);
            if ($pangkalan) {
                $pangkalanPrediksi = [];
                foreach ($predictionDates as $date) {
                    $nilaiEstimasi = (int) HasilPrediksi::where(['user_id' => $pangkalan->id, 'tanggal' => $date])->sum('estimasi');
                    $pangkalanPrediksi[] = $nilaiEstimasi;
                    $totalPrediksiTersedia += $nilaiEstimasi;
                }
                $predictionChartData[] = [
                    'label' => $pangkalan->name,
                    'data' => $pangkalanPrediksi
                ];
            }
        } else {
            $globalPredData = [];
            foreach ($predictionDates as $date) {
                $nilaiEstimasiGlobal = (int) HasilPrediksi::where(['tanggal' => $date])->sum('estimasi');
                $globalPredData[] = $nilaiEstimasiGlobal;
                $totalPrediksiTersedia += $nilaiEstimasiGlobal;
            }
            $predictionChartData[] = [
                'label' => 'Total Estimasi Seluruh Pangkalan',
                'data' => $globalPredData
            ];
        }

        return [
            'dates'  => $predictionDates,
            'labels' => $predictionLabels,
            'data'   => $predictionChartData,
            'total'  => $totalPrediksiTersedia
        ];
    }

    private function generatePieData(): array
    {
        $salesData = DataPenjualan::select('jumlah')->get();
        return [
            'rendah' => $salesData->filter(fn($item) => $item->jumlah < 10)->count(),
            'sedang' => $salesData->filter(fn($item) => $item->jumlah >= 10 && $item->jumlah <= 15)->count(),
            'tinggi' => $salesData->filter(fn($item) => $item->jumlah > 15)->count(),
        ];
    }

    private function generateAktivitasLogData(Collection $pangkalanList): Collection
    {
        $aktivitasPangkalan = [];
        foreach ($pangkalanList as $pangkalan) {
            $latestSales = DataPenjualan::where(['user_id' => $pangkalan->id])->orderBy('created_at', 'desc')->first();
            $latestPred = HasilPrediksi::where(['user_id' => $pangkalan->id])->orderBy('created_at', 'desc')->first();

            if ($latestSales || $latestPred) {
                $salesTime = $latestSales ? $latestSales->created_at : null;
                $predTime = $latestPred ? $latestPred->created_at : null;

                $pilihAksi = ($salesTime && $predTime && $salesTime->gt($predTime)) || $latestSales && !$latestPred ? 'sales' : 'prediksi';

                if ($pilihAksi == 'sales') {
                    $aktivitasPangkalan[] = [
                        'name' => $pangkalan->name,
                        'aksi' => 'melakukan input data penjualan',
                        'waktu' => $latestSales->created_at
                    ];
                } else {
                    $aktivitasPangkalan[] = [
                        'name' => $pangkalan->name,
                        'aksi' => 'melakukan prediksi',
                        'waktu' => $latestPred->created_at
                    ];
                }
            }
        }
        return collect($aktivitasPangkalan)->sortByDesc(fn($activity) => $activity['waktu'])->take(7);
    }
}