<?php

namespace App\Filament\Widgets;

use App\Models\Line;
use Filament\Widgets\ChartWidget;
use Illuminate\Support\Js;
use Filament\Support\RawJs;
use Illuminate\Support\Stringable;

class ProductionOrderChart extends ChartWidget
{
    protected static ?string $heading = 'ProductionOrderCount';

    protected int|string|array $columnSpan = 12;

     protected static ?string $maxHeight = '330px';

    protected $listeners = ['productionOrderChart'];


    protected function getData(): array
    {
        $activeFilter = $this->filter;

        $selectedPlant = session('selected_plant');
        $selectedLine = session('selected_line');
        $selectedStatus = session('selected_status');
        $productionOrder = session('production_order');

        if (!$selectedPlant || !$selectedLine || !$productionOrder || !$selectedStatus) {
            return [
                'datasets' => [],
                'labels' => [],
            ];
        }

        // 1. Check line type
        $lineType = Line::where('id', $selectedLine)->value('type');

        // 2. Set base table and columns depending on line type
        if ($lineType == 'FG Line')
        {
            $table = 'quality_validations';
            $dateColumn = 'created_at';
            $plantColumn = 'plant_id';
            $lineColumn = 'line_id';
            $orderColumn = 'production_order';
        }
        else
        {
            $table = 'production_quantities';
            $dateColumn = 'created_at';
            $plantColumn = 'plant_id';
            $lineColumn = 'line_id';
            $orderColumn = 'production_order';
        }

        // 3. Set filter logic as before
        if ($activeFilter == 'yesterday')
        {
            $startDate = now()->subDay()->setTime(8, 0, 0);
            $endDate = now()->setTime(8, 0, 0);
            $groupBy = "EXTRACT(HOUR FROM $table.$dateColumn)";
        }
        else if ($activeFilter == 'this_week')
        {
            $startDate = now()->startOfWeek()->setTime(8, 0, 0);
            $endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0);
            $groupBy = "EXTRACT(DOW FROM $table.$dateColumn)";
        }
        else if ($activeFilter == 'this_month')
        {
            $startDate = now()->startOfMonth();
            $endDate = now()->endOfMonth();
            $groupBy = "FLOOR((EXTRACT(DAY FROM $table.$dateColumn) - 1) / 7) + 1";
        }
        else
        {
            $startDate = now()->setTime(8, 0, 0);
            $endDate = now()->copy()->addDay()->setTime(8, 0, 0);
            $groupBy = "EXTRACT(HOUR FROM $table.$dateColumn)";
        }

        // // 4. Build the query dynamically
        // $query = \DB::table($table)
        //     ->join('plants', "$table.$plantColumn", '=', 'plants.id')
        //     ->join('lines', "$table.$lineColumn", '=', 'lines.id')
        //     ->selectRaw("$groupBy AS time_unit, count(*) AS total_quantity")
        //     ->whereBetween("$table.$dateColumn", [$startDate, $endDate])
        //     ->where('plants.id', $selectedPlant)
        //     ->where('lines.id', $selectedLine)
        //     ->when($productionOrder, fn($q) => $q->where("$table.$orderColumn", $productionOrder))
        //     ->groupByRaw($groupBy)
        //     ->orderByRaw($groupBy)
        //     ->pluck('total_quantity', 'time_unit')
        //     ->toArray();

        $query = \DB::table($table)
            ->selectRaw("$groupBy AS time_unit, COUNT(*) AS total_quantity")
            ->whereBetween("$table.$dateColumn", [$startDate, $endDate])
            ->where("$table.$plantColumn", $selectedPlant)
            ->where("$table.$lineColumn", $selectedLine)
            ->where("$table.$orderColumn", $productionOrder);

        // Apply status filter only for Non-FG lines
        if ($selectedStatus && $lineType != 'FG Line') {
            $query->where('success_status', $selectedStatus);
        }

        $query = $query
            ->groupByRaw($groupBy)
            ->orderByRaw($groupBy)
            ->pluck('total_quantity', 'time_unit')
            ->toArray();

        if ($activeFilter == 'this_month')
        {
            $weeksCount = ceil($endDate->day / 7);
            $allWeeks = array_fill(1, $weeksCount, 0);
            $data = array_replace($allWeeks, $query);

            $labels = [];
            for ($i = 1; $i <= $weeksCount; $i++) {
                $weekStart = $startDate->copy()->addDays(($i - 1) * 7)->format('d M');
                $weekEnd = $startDate->copy()->addDays($i * 7 - 1)->min($endDate)->format('d M');
                $labels[] = "Week $i ($weekStart - $weekEnd)";
            }

            $orderedData = array_values($data);
        }
        else if ($activeFilter == 'this_week')
        {
            $labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
            $data = array_fill(0, 7, 0);
            foreach ($query as $dow => $count) {
                $data[$dow] = $count;
            }
            $orderedData = [
                $data[1] ?? 0, // Monday
                $data[2] ?? 0, // Tuesday
                $data[3] ?? 0, // Wednesday
                $data[4] ?? 0, // Thursday
                $data[5] ?? 0, // Friday
                $data[6] ?? 0, // Saturday
                $data[0] ?? 0, // Sunday
            ];
        }
        // else
        // {
        //     $allHours = array_fill(0, 24, 0);
        //     $data = array_replace($allHours, $query);

        //     $shiftedKeys = array_merge(range(9, 23), range(0, 8));
        //     $orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);

        //     $labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys);
        // }
        else
        {
            $allHours = array_fill(0, 24, 0);
            $data = array_replace($allHours, $query);

            // Shift counts - move each hour's count to the next hour
            $shiftedData = [];
            foreach ($data as $hour => $count) {
                $nextHour = ($hour + 1) % 24;
                $shiftedData[$nextHour] = $count;
            }

            // Order from 9AM to 8AM next day
            $shiftedKeys = array_merge(range(9, 23), range(0, 8));
            $orderedData = array_map(fn($hour) => $shiftedData[$hour] ?? 0, $shiftedKeys);

            // Create labels
            $labels = array_map(function($hour) {
                return date("g A", strtotime("$hour:00"));
            }, $shiftedKeys);
        }

        $orderedData = array_map(function ($value)
        {
            return ($value == 0 || is_null($value)) ? null : $value;
        }, $orderedData);


        return [
            'datasets' => [
                [
                   'label' => match ($activeFilter)
                    {
                        'this_week' => $lineType == 'FG Line'
                            ? "Daily Fg Production Order Count This Week"
                            : "Daily Production Order Count This Week",
                        'this_month' => $lineType == 'FG Line'
                            ? "Weekly Fg Production Order Count This Month"
                            : "Weekly Production Order Count This Month",
                        'yesterday' => $lineType == 'FG Line'
                            ? "Yesterday's Hourly Fg Order Count Production"
                            : "Yesterday's Hourly Order Count Production",
                        default => $lineType == 'FG Line'
                            ? "Today's Hourly Fg Production Order Count"
                            : "Today's Hourly Production Order Count",
                    },

                    'data' => $orderedData,
                    'borderColor' => 'rgba(75, 192, 192, 1)',
                    'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
                    'fill' => false,
                    'tension' => 0.3,
                ],
            ],
            'labels' => $labels,
        ];
    }

    protected function getType(): string
    {
        return 'bar';
    }

    protected function getOptions(): array
    {
        return [
             'plugins' => [
                    'datalabels' => [
                           'anchor' => 'start',
                            'align' => 'start',
                            'offset' => -15,
                        'color' => '#000',
                        'font' => [
                            'weight' => 'bold',
                        ],
                        'formatter' => Js::from("function(value) { return Number(value); }"),
                    ],
                ],
            'scales' => [
                'y' => [
                    'beginAtZero' => true,
                    'ticks' => [
                        'stepSize' => 0.5,
                    ],
                ],
            ],
        ];
    }

    protected function getFilters(): ?array
    {
        return [
            'today' => 'Today',
            'yesterday' => 'Yesterday',
            'this_week'=> 'This Week',
            'this_month'=> 'This Month',
        ];
    }

    public static function canView(): bool
    {
        // Only show on HourlyProduction page
        return request()->routeIs('filament.pages.production-order-count');
    }
}
