<?php

namespace App\Filament\Widgets;

use App\Models\MfmReading;
use Carbon\Carbon;
use Filament\Widgets\ChartWidget;
use Filament\Support\RawJs;

class TrendChartAnalysis extends ChartWidget
{
    protected static ?string $heading = 'Trend Chart Analysis';


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


    protected int|string|array $columnSpan = 12;

      // Add a property to receive filters from parent or externally

    protected function getData(): array
    {
        $fromDatetime = session('from_datetime');
        $toDatetime = session('to_datetime');
        $selectedPlant = session('selected_plant');
        $meterId = session('selected_meter');
        $parameter = session('parameter');

        if (empty($fromDatetime) || empty($toDatetime) || empty($selectedPlant) || empty($meterId) || empty($parameter)) {
            return [
                'labels' => [],
                'datasets' => [],
            ];
        }

        $fromDateTime = Carbon::parse($fromDatetime);
        $toDateTime = Carbon::parse($toDatetime);

        if ($fromDateTime->gt($toDateTime) || $fromDateTime->gt(now()) || $toDateTime->gt(now())) {
            return [
                'labels' => [],
                'datasets' => [],
            ];
        }

        $durationHours = $fromDateTime->diffInHours($toDateTime);
        //dd($durationHours);
        if ($durationHours < 1 || $durationHours > 24) {
            return [
                'labels' => [],
                'datasets' => [],
            ];
        }

        $intervalCount = $durationHours > 12 ? 12 : 10;
        $intervalMinutes = $durationHours > 12 ? 120 : floor(($durationHours * 60) / $intervalCount);

        $labels = [];

        if ($parameter == 'Phase Voltage') {

            // Helper function to get min, max, avg for a column with PostgreSQL casting
            $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
                $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));

                return [
                    'min' => round($min ?? 0, 2),
                    'max' => round($max ?? 0, 2),
                    'avg' => round($avg ?? 0, 2),
                ];
            };

            // Get aggregated data for all relevant columns
            $voltageRYSummary = $dataAggregation('voltage_ry');
            $voltageYBSummary = $dataAggregation('voltage_yb');
            $voltageBRSummary = $dataAggregation('voltage_br');
            $frequencySummary = $dataAggregation('frequency');

            // Labels for each bar on X-axis (min, max, avg per column)
            $labels = [
                'Voltage RY Min', 'Voltage RY Max', 'Voltage RY Avg',
                'Voltage YB Min', 'Voltage YB Max', 'Voltage YB Avg',
                'Voltage BR Min', 'Voltage BR Max', 'Voltage BR Avg',
                'Frequency Min', 'Frequency Max', 'Frequency Avg',
            ];

            // Ordered data values matching labels above
            $dataValues = [
                $voltageRYSummary['min'], $voltageRYSummary['max'], $voltageRYSummary['avg'],
                $voltageYBSummary['min'], $voltageYBSummary['max'], $voltageYBSummary['avg'],
                $voltageBRSummary['min'], $voltageBRSummary['max'], $voltageBRSummary['avg'],
                $frequencySummary['min'], $frequencySummary['max'], $frequencySummary['avg'],
            ];

            // Colors by aggregation type: Min - yellow, Max - green, Avg - blue
        $aggregationColors = [
                'rgba(204, 163, 0, 0.8)',    // Darker yellow (Min)
                'rgba(30, 120, 120, 0.8)',   // Darker teal/green (Max)
                'rgba(30, 90, 140, 0.8)',    // Darker blue (Avg)
            ];

            // Each set of 3 bars per column repeats the colors: min, max, avg
            $backgroundColorArray = [];
            foreach (range(1, 4) as $group) { // 4 column groups
                foreach ($aggregationColors as $color) {
                    $backgroundColorArray[] = $color;
                }
            }

            // Construct chart data structure
            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => 'Phase Voltage & Frequency Stats',
                        // Bar values array: 12 bars total (4 groups × 3 stats each)
                        'data' => $dataValues,
                        'backgroundColor' => $backgroundColorArray,
                        'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
                        'borderWidth' => 1,
                    ],
                ],
            ];
        }
        else if ($parameter == 'Line Voltage') {

            // Helper function to get min, max, avg for a column with PostgreSQL casting
            $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
                $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));

                return [
                    'min' => round($min ?? 0, 2),
                    'max' => round($max ?? 0, 2),
                    'avg' => round($avg ?? 0, 2),
                ];
            };

            // Get aggregated data for all relevant columns
            $voltageRNSummary = $dataAggregation('voltage_r_n');
            $voltageYNSummary = $dataAggregation('voltage_y_n');
            $voltageBNSummary = $dataAggregation('voltage_b_n');
            $frequencySummary = $dataAggregation('frequency');

            // Labels for each bar on X-axis (min, max, avg per column)
            $labels = [
                'Voltage RN Min', 'Voltage RN Max', 'Voltage RN Avg',
                'Voltage YN Min', 'Voltage YN Max', 'Voltage YN Avg',
                'Voltage BN Min', 'Voltage BN Max', 'Voltage BN Avg',
                'Frequency Min', 'Frequency Max', 'Frequency Avg',
            ];

            // Ordered data values matching labels above
            $dataValues = [
                $voltageRNSummary['min'], $voltageRNSummary['max'], $voltageRNSummary['avg'],
                $voltageYNSummary['min'], $voltageYNSummary['max'], $voltageYNSummary['avg'],
                $voltageBNSummary['min'], $voltageBNSummary['max'], $voltageBNSummary['avg'],
                $frequencySummary['min'], $frequencySummary['max'], $frequencySummary['avg'],
            ];

            // Colors by aggregation type: Min - yellow, Max - green, Avg - blue
        $aggregationColors = [
                'rgba(204, 163, 0, 0.8)',    // Darker yellow (Min)
                'rgba(30, 120, 120, 0.8)',   // Darker teal/green (Max)
                'rgba(30, 90, 140, 0.8)',    // Darker blue (Avg)
            ];

            // Each set of 3 bars per column repeats the colors: min, max, avg
            $backgroundColorArray = [];
            foreach (range(1, 4) as $group) { // 4 column groups
                foreach ($aggregationColors as $color) {
                    $backgroundColorArray[] = $color;
                }
            }

            // Construct chart data structure
            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => 'Phase Voltage & Frequency Stats',
                        // Bar values array: 12 bars total (4 groups × 3 stats each)
                        'data' => $dataValues,
                        'backgroundColor' => $backgroundColorArray,
                        'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
                        'borderWidth' => 1,
                    ],
                ],
            ];
        }
        else if ($parameter == 'Current') {

            // Helper function to get min, max, avg for a column with PostgreSQL casting
            $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
                $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));

                return [
                    'min' => round($min ?? 0, 2),
                    'max' => round($max ?? 0, 2),
                    'avg' => round($avg ?? 0, 2),
                ];
            };

            // Get aggregated data for all relevant columns
            $curR = $dataAggregation('current_r');
            $curY = $dataAggregation('current_y');
            $curB = $dataAggregation('current_b');
            $curN = $dataAggregation('current_n');

            // Labels for each bar on X-axis (min, max, avg per column)
            $labels = [
                'Current R Min', 'Current R Max', 'Current R Avg',
                'Current Y Min', 'Current Y Max', 'Current Y Avg',
                'Current B Min', 'Current B Max', 'Current B Avg',
                'Current N Min', 'Current N Max', 'Current N Avg',
            ];

            // Ordered data values matching labels above
            $dataValues = [
                $curR['min'], $curR['max'], $curR['avg'],
                $curY['min'], $curY['max'], $curY['avg'],
                $curB['min'], $curB['max'], $curB['avg'],
                $curN['min'], $curN['max'], $curN['avg'],
            ];

            // Colors by aggregation type: Min - yellow, Max - green, Avg - blue
        $aggregationColors = [
                'rgba(204, 163, 0, 0.8)',    // Darker yellow (Min)
                'rgba(30, 120, 120, 0.8)',   // Darker teal/green (Max)
                'rgba(30, 90, 140, 0.8)',    // Darker blue (Avg)
            ];

            // Each set of 3 bars per column repeats the colors: min, max, avg
            $backgroundColorArray = [];
            foreach (range(1, 4) as $group) { // 4 column groups
                foreach ($aggregationColors as $color) {
                    $backgroundColorArray[] = $color;
                }
            }

            // Construct chart data structure
            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => 'Phase Voltage & Frequency Stats',
                        // Bar values array: 12 bars total (4 groups × 3 stats each)
                        'data' => $dataValues,
                        'backgroundColor' => $backgroundColorArray,
                        'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
                        'borderWidth' => 1,
                    ],
                ],
            ];
        }
        else if ($parameter == 'Active Power') {

            // Helper function to get min, max, avg for a column with PostgreSQL casting
            $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
                $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));

                return [
                    'min' => round($min ?? 0, 2),
                    'max' => round($max ?? 0, 2),
                    'avg' => round($avg ?? 0, 2),
                ];
            };

            // Get aggregated data for all relevant columns
            $activePowR = $dataAggregation('active_power_r');
            $activePowY = $dataAggregation('active_power_y');
            $activePowB = $dataAggregation('active_power_b');
            $activePowTot = $dataAggregation('active_power_total');

            // Labels for each bar on X-axis (min, max, avg per column)
            $labels = [
                'ActivePow R Min', 'ActivePow R Max', 'ActivePow R Avg',
                'ActivePow Y Min', 'ActivePow Y Max', 'ActivePow Y Avg',
                'ActivePow B Min', 'ActivePow B Max', 'ActivePow B Avg',
                'ActivePow Tot Min', 'ActivePow Tot Max', 'ActivePow Tot Avg',
            ];

            // Ordered data values matching labels above
            $dataValues = [
                $activePowR['min'], $activePowR['max'], $activePowR['avg'],
                $activePowY['min'], $activePowY['max'], $activePowY['avg'],
                $activePowB['min'], $activePowB['max'], $activePowB['avg'],
                $activePowTot['min'], $activePowTot['max'], $activePowTot['avg'],
            ];

            // Colors by aggregation type: Min - yellow, Max - green, Avg - blue
        $aggregationColors = [
                'rgba(204, 163, 0, 0.8)',    // Darker yellow (Min)
                'rgba(30, 120, 120, 0.8)',   // Darker teal/green (Max)
                'rgba(30, 90, 140, 0.8)',    // Darker blue (Avg)
            ];

            // Each set of 3 bars per column repeats the colors: min, max, avg
            $backgroundColorArray = [];
            foreach (range(1, 4) as $group) { // 4 column groups
                foreach ($aggregationColors as $color) {
                    $backgroundColorArray[] = $color;
                }
            }

            // Construct chart data structure
            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => 'Phase Voltage & Frequency Stats',
                        // Bar values array: 12 bars total (4 groups × 3 stats each)
                        'data' => $dataValues,
                        'backgroundColor' => $backgroundColorArray,
                        'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
                        'borderWidth' => 1,
                    ],
                ],
            ];
        }
        else if ($parameter == 'Power Factor') {

            // Helper function to get min, max, avg for a column with PostgreSQL casting
            $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
                $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));

                return [
                    'min' => round($min ?? 0, 2),
                    'max' => round($max ?? 0, 2),
                    'avg' => round($avg ?? 0, 2),
                ];
            };

            // Get aggregated data for all relevant columns
            $powFacR = $dataAggregation('power_factor_r');
            $powFacY = $dataAggregation('power_factor_y');
            $powFacB = $dataAggregation('power_factor_b');
            $powFacTot = $dataAggregation('power_factor_total');

            // Labels for each bar on X-axis (min, max, avg per column)
            $labels = [
                'PowerFac R Min', 'PowerFac R Max', 'PowerFac R Avg',
                'PowerFac Y Min', 'PowerFac Y Max', 'PowerFac Y Avg',
                'PowerFac B Min', 'PowerFac B Max', 'PowerFac B Avg',
                'PowerFac Tot Min', 'PowerFac Tot Max', 'PowerFac Tot Avg',
            ];

            // Ordered data values matching labels above
            $dataValues = [
                $powFacR['min'], $powFacR['max'], $powFacR['avg'],
                $powFacY['min'], $powFacY['max'], $powFacY['avg'],
                $powFacB['min'], $powFacB['max'], $powFacB['avg'],
                $powFacTot['min'], $powFacTot['max'], $powFacTot['avg'],
            ];

            // Colors by aggregation type: Min - yellow, Max - green, Avg - blue
        $aggregationColors = [
                'rgba(204, 163, 0, 0.8)',    // Darker yellow (Min)
                'rgba(30, 120, 120, 0.8)',   // Darker teal/green (Max)
                'rgba(30, 90, 140, 0.8)',    // Darker blue (Avg)
            ];

            // Each set of 3 bars per column repeats the colors: min, max, avg
            $backgroundColorArray = [];
            foreach (range(1, 4) as $group) { // 4 column groups
                foreach ($aggregationColors as $color) {
                    $backgroundColorArray[] = $color;
                }
            }

            // Construct chart data structure
            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => 'Phase Voltage & Frequency Stats',
                        // Bar values array: 12 bars total (4 groups × 3 stats each)
                        'data' => $dataValues,
                        'backgroundColor' => $backgroundColorArray,
                        'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
                        'borderWidth' => 1,
                    ],
                ],
            ];
        }
        else if ($parameter == 'Units') {

            // Helper function to get min, max, avg for a column with PostgreSQL casting
            $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) {
                $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));
                $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime])
                    ->where('mfm_meter_id', $meterId)
                    ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision"));

                return [
                    'min' => round($min ?? 0, 2),
                    'max' => round($max ?? 0, 2),
                    'avg' => round($avg ?? 0, 2),
                ];
            };

            // Get aggregated data for all relevant columns
            $appEneRec = $dataAggregation('apparent_energy_received');
            $reaEneRec = $dataAggregation('reactive_energy_received');
            $actEneRec = $dataAggregation('active_energy_received');


            // Labels for each bar on X-axis (min, max, avg per column)
            $labels = [
                'AppEneRec Min', 'AppEneRec Max', 'AppEneRec Avg',
                'ReaEneRec Min', 'ReaEneRec Max', 'ReaEneRec Avg',
                'ActEneRec Min', 'ActEneRec Max', 'ActEneRec Avg',
            ];

            // Ordered data values matching labels above
            $dataValues = [
                $appEneRec['min'], $appEneRec['max'], $appEneRec['avg'],
                $reaEneRec['min'], $reaEneRec['max'], $reaEneRec['avg'],
                $actEneRec['min'], $actEneRec['max'], $actEneRec['avg'],
            ];

            // Colors by aggregation type: Min - yellow, Max - green, Avg - blue
        $aggregationColors = [
                'rgba(204, 163, 0, 0.8)',    // Darker yellow (Min)
                'rgba(30, 120, 120, 0.8)',   // Darker teal/green (Max)
                'rgba(30, 90, 140, 0.8)',    // Darker blue (Avg)
            ];

            // Each set of 3 bars per column repeats the colors: min, max, avg
            $backgroundColorArray = [];
            foreach (range(1, 4) as $group) { // 4 column groups
                foreach ($aggregationColors as $color) {
                    $backgroundColorArray[] = $color;
                }
            }

            // Construct chart data structure
            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => 'Phase Voltage & Frequency Stats',
                        // Bar values array: 12 bars total (4 groups × 3 stats each)
                        'data' => $dataValues,
                        'backgroundColor' => $backgroundColorArray,
                        'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray),
                        'borderWidth' => 1,
                    ],
                ],
            ];
        }
        else
        {
            $data = [];
            $labels = [];
            $currentStart = $fromDateTime->copy();
            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => ucfirst(str_replace('_', ' ', $parameter)),
                        'data' => $data,
                        'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
                        'borderColor' => 'rgba(75, 192, 192, 1)',
                        'fill' => false,
                        'tension' => 0.3,
                        'pointRadius' => 5,
                        'pointHoverRadius' => 7,
                    ],
                ],
            ];
        }
    }
    protected function getOptions(): array
    {
        return [
            'plugins' => [
                'datalabels' => [
                    'anchor' => 'start',
                    'align' => 'start',
                    'offset' => -15,
                    'color' => '#000',
                    'font' => [
                        'weight' => 'bold',
                    ],
                    'formatter' => RawJs::make('function(value) {
                        return value;
                    }'),
                ],
            ],
            'scales' => [
                'y' => [
                    'beginAtZero' => true,
                    'ticks' => [
                        'stepSize' => 1,
                    ],
                ],
            ],
        ];
    }



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