<?php

namespace App\Http\Controllers;

use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionQuantity;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ModuleFilterDataController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        //
    }

    // public function get_moduleFilterData(Request $request)
    // {
    //     $expectedUser = env('API_AUTH_USER');
    //     $expectedPw   = env('API_AUTH_PW');

    //     $header_auth = $request->header('Authorization');
    //     $expectedToken = $expectedUser . ':' . $expectedPw;

    //     if ("Bearer " . $expectedToken != $header_auth)
    //     {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => 'Invalid authorization token!'
    //         ], 403);
    //     }

    //     $moduleName = $request->header('module-name');
    //     $chartName = $request->header('chart-name');
    //     $plantName = $request->header('plant-name');
    //     $lineName = $request->header('line-name');
    //     $filterName = $request->header('filter-name');

    //     $requiredHeaders = [
    //         'module-name',
    //         'chart-name',
    //         'plant-name',
    //         'line-name',
    //         'filter-name',
    //     ];

    //     $missingHeaders = [];

    //     foreach ($requiredHeaders as $header) {
    //         if (empty($request->header($header))) {
    //             $missingHeaders[] = $header;
    //         }
    //     }

    //     if (!empty($missingHeaders)) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => 'Missing required headers: ' . implode(', ', $missingHeaders)
    //         ], 400);
    //     }

    //       // Fetch plant ID
    //     $plant = Plant::where('name', $plantName)->first();
    //     if (!$plant) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => "Plant '{$plantName}' not found!"
    //         ], 404);
    //     }

    //     // Fetch line ID
    //     $line = Line::where('name', $lineName)->where('plant_id', $plant->id)->first();
    //     if (!$line) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => "Line '{$lineName}' not found for plant '{$plantName}'"
    //         ], 404);
    //     }

    //     $activeFilter = strtolower(trim($request->header('filter-name')));

    //     if ($activeFilter == 'yesterday') {
    //         $startDate = now()->subDay()->setTime(8, 0, 0);
    //         $endDate   = now()->setTime(8, 0, 0);
    //     }
    //     elseif ($activeFilter == 'this week') {
    //         $startDate = now()->startOfWeek()->setTime(8, 0, 0);
    //         $endDate   = now()->endOfWeek()->addDay()->setTime(8, 0, 0);
    //     }
    //     elseif ($activeFilter == 'this month') {
    //         $startDate = now()->startOfMonth();
    //         $endDate   = now()->endOfMonth();
    //     }
    //     else {
    //         $startDate = now()->setTime(8, 0, 0);
    //         $endDate   = now()->copy()->addDay()->setTime(8, 0, 0);
    //     }

    //     $rowCount = ProductionQuantity::where('plant_id', $plant->id)
    //     ->where('line_id', $line->id)
    //     ->whereBetween('created_at', [$startDate, $endDate])
    //     ->count();

    //     return response()->json([
    //         'status_code' => 'SUCCESS',
    //         'status_description' => $rowCount
    //     ], 200);
    // }

    // public function get_moduleFilterData(Request $request)
    // {
    //     $expectedUser = env('API_AUTH_USER');
    //     $expectedPw   = env('API_AUTH_PW');

    //     $header_auth = $request->header('Authorization');
    //     $expectedToken = $expectedUser . ':' . $expectedPw;

    //     if ("Bearer " . $expectedToken != $header_auth) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => 'Invalid authorization token!'
    //         ], 403);
    //     }

    //     $requiredHeaders = [
    //         'module-name',
    //         'chart-name',
    //         'plant-name',
    //         'line-name',
    //         'filter-name',
    //     ];

    //     $missingHeaders = [];

    //     foreach ($requiredHeaders as $header) {
    //         if (empty($request->header($header))) {
    //             $missingHeaders[] = $header;
    //         }
    //     }

    //     if (!empty($missingHeaders)) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => 'Missing required headers: ' . implode(', ', $missingHeaders)
    //         ], 404);
    //     }

    //     $validFilters = ['Today', 'Yesterday', 'This Week', 'This Month'];
    //     $filterHeader = $request->header('filter-name');

    //     if (!in_array($filterHeader, $validFilters)) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => "Invalid filter-name value! Accepted values are: " . implode(', ', $validFilters)
    //         ], 404);
    //     }

    //     $plantName  = $request->header('plant-name');
    //     $lineName   = $request->header('line-name');
    //     $filterName = strtolower(trim($request->header('filter-name')));

    //     $plant = Plant::where('name', $plantName)->first();
    //     if (!$plant) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => "Plant '{$plantName}' not found!"
    //         ], 404);
    //     }

    //     // Set date filter range
    //     if ($filterName == 'yesterday') {
    //         $startDate = now()->subDay()->setTime(8, 0, 0);
    //         $endDate   = now()->setTime(8, 0, 0);
    //     } elseif ($filterName == 'this week') {
    //         $startDate = now()->startOfWeek()->setTime(8, 0, 0);
    //         $endDate   = now()->endOfWeek()->addDay()->setTime(8, 0, 0);
    //     } elseif ($filterName == 'this month') {
    //         $startDate = now()->startOfMonth();
    //         $endDate   = now()->endOfMonth();
    //     } else {
    //         $startDate = now()->setTime(8, 0, 0);
    //         $endDate   = now()->copy()->addDay()->setTime(8, 0, 0);
    //     }

    //     // Handle All Lines
    //     if (strtolower(trim($lineName)) == 'all lines') {
    //         $lines = Line::where('plant_id', $plant->id)->pluck('id', 'name');

    //         if ($lines->isEmpty()) {
    //             return response()->json([
    //                 'status_code' => 'ERROR',
    //                 'status_description' => "No lines found for plant '{$plantName}'"
    //             ], 404);
    //         }

    //         $lineCounts = [];

    //         foreach ($lines as $name => $id) {
    //             $count = ProductionQuantity::where('plant_id', $plant->id)
    //                 ->where('line_id', $id)
    //                 ->whereBetween('created_at', [$startDate, $endDate])
    //                 ->count();

    //             $lineCounts[$name] = $count;
    //         }

    //         return response()->json([
    //             'status_code' => 'SUCCESS',
    //             'status_description' => $lineCounts
    //         ], 200);
    //     }

    //     // Handle single line
    //     $line = Line::where('name', $lineName)->where('plant_id', $plant->id)->first();
    //     if (!$line) {
    //         return response()->json([
    //             'status_code' => 'ERROR',
    //             'status_description' => "Line '{$lineName}' not found for plant '{$plantName}'"
    //         ], 404);
    //     }

    //     $rowCount = ProductionQuantity::where('plant_id', $plant->id)
    //         ->where('line_id', $line->id)
    //         ->whereBetween('created_at', [$startDate, $endDate])
    //         ->count();

    //     $chartName = $request->header('chart-name');

    //     if ($chartName == 'Production Hourly Count')
    //     {

    //         if ($filterHeader == 'Today' || $filterHeader == 'Yesterday') {
    //             $hourlyCounts = [];

    //             $hourStart = now()->startOfDay()->addHours(8); // Today 8:00 AM
    //             if ($filterHeader == 'Yesterday') {
    //                 $hourStart->subDay(); // Yesterday 8:00 AM
    //             }

    //             $hourEndFinal = $hourStart->copy()->addDay(); // +1 day = 24 hourly slots

    //             while ($hourStart < $hourEndFinal) {
    //                 $hourEnd = $hourStart->copy()->addHour();

    //                 $label = $hourStart->format('g:i A') . ' to ' . $hourEnd->format('g:i A');

    //                 $count = ProductionQuantity::where('plant_id', $plant->id)
    //                     ->where('line_id', $line->id)
    //                     ->whereBetween('created_at', [$hourStart, $hourEnd])
    //                     ->count();

    //                 $hourlyCounts[$label] = $count;

    //                 $hourStart = $hourEnd;
    //             }

    //             return response()->json([
    //                 'status_code' => 'SUCCESS',
    //                 'hourly_data' => $hourlyCounts
    //             ], 200);
    //         }

    //         // THIS WEEK: group by weekdays (Mon to Sun)
    //         if ($filterHeader == 'This Week') {
    //             $dowCounts = ProductionQuantity::selectRaw('EXTRACT(DOW FROM created_at) as dow, COUNT(*) as total')
    //                 ->where('plant_id', $plant->id)
    //                 ->where('line_id', $line->id)
    //                 ->whereBetween('created_at', [$startDate, $endDate])
    //                 ->groupBy('dow')
    //                 ->pluck('total', 'dow');

    //             $labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
    //             $data = array_fill(0, 7, 0);

    //             foreach ($dowCounts as $dow => $count) {
    //                 $data[$dow] = $count;
    //             }

    //             // Reorder from Monday (1) to Sunday (0)
    //             $orderedData = [
    //                 $data[1] ?? 0,
    //                 $data[2] ?? 0,
    //                 $data[3] ?? 0,
    //                 $data[4] ?? 0,
    //                 $data[5] ?? 0,
    //                 $data[6] ?? 0,
    //                 $data[0] ?? 0
    //             ];

    //             return response()->json([
    //                 'status_code' => 'SUCCESS',
    //                 'weekly_labels' => $labels,
    //                 'weekly_counts' => $orderedData
    //             ], 200);
    //         }

    //         //THIS MONTH: group by weeks
    //         if ($filterHeader == 'This Month') {
    //             // Count records grouped by week number
    //             $weekCounts = ProductionQuantity::selectRaw("FLOOR((EXTRACT(DAY FROM created_at) - 1) / 7) + 1 as week_number, COUNT(*) as total")
    //                 ->where('plant_id', $plant->id)
    //                 ->where('line_id', $line->id)
    //                 ->whereBetween('created_at', [$startDate, $endDate])
    //                 ->groupBy('week_number')
    //                 ->pluck('total', 'week_number');

    //             $weeksCount = ceil($endDate->day / 7); // Total number of weeks in month
    //             $allWeeks = array_fill(1, $weeksCount, 0);
    //             $data = array_replace($allWeeks, $weekCounts->toArray());

    //             // Prepare labels like Week 1 (01 Jul - 07 Jul)
    //             $labels = [];
    //             for ($i = 1; $i <= $weeksCount; $i++) {
    //                 $weekStart = $startDate->copy()->addDays(($i - 1) * 7);
    //                 $weekEnd = $startDate->copy()->addDays($i * 7 - 1)->min($endDate);

    //                 $labels[] = "Week $i ({$weekStart->format('d M')} - {$weekEnd->format('d M')})";
    //             }

    //             $orderedData = array_values($data);

    //             return response()->json([
    //                 'status_code' => 'SUCCESS',
    //                 'monthly_labels' => $labels,
    //                 'monthly_counts' => $orderedData
    //             ], 200);
    //         }
    //     }

    //     if ($chartName == 'Production Line Count')
    //     {
    //          return response()->json([
    //             'status_code' => 'SUCCESS',
    //             'status_description' => $rowCount
    //         ], 200);
    //     }
    // }




    public function get_moduleFilterData(Request $request)
    {
        $expectedUser = env('API_AUTH_USER');
        $expectedPw   = env('API_AUTH_PW');

        $header_auth = $request->header('Authorization');
        $expectedToken = $expectedUser . ':' . $expectedPw;

        if ("Bearer " . $expectedToken != $header_auth) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid authorization token!'
            ], 403);
        }

        $requiredHeaders = [
            'module-name', 'chart-name', 'plant-name', 'line-name', 'filter-name'
        ];

        $missingHeaders = [];
        foreach ($requiredHeaders as $header) {
            if (empty($request->header($header))) {
                $missingHeaders[] = $header;
            }
        }

        if (!empty($missingHeaders)) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Missing required headers: ' . implode(', ', $missingHeaders)
            ], 404);
        }

        $validFilters = ['Today', 'Yesterday', 'This Week', 'This Month'];
        $filterHeader = $request->header('filter-name');

        if (!in_array($filterHeader, $validFilters)) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Invalid filter-name value! Accepted values are: " . implode(', ', $validFilters)
            ], 404);
        }

        $plantName  = $request->header('plant-name');
        $lineName   = $request->header('line-name');
        $filterName = strtolower(trim($request->header('filter-name')));
        $chartName  = $request->header('chart-name');

        $plant = Plant::where('name', $plantName)->first();
        if (!$plant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant '{$plantName}' not found!"
            ], 404);
        }

        $isAllLines = strtolower(trim($lineName)) == 'all lines';

        if ($isAllLines) {
            $lines = Line::where('plant_id', $plant->id)->get();
            $fgLineIds = $lines->where('type', 'FG Line')->pluck('id')->toArray();
            $nonFgLineIds = $lines->where('type', '!=', 'FG Line')->pluck('id')->toArray();
        } else {
            $line = Line::where('name', $lineName)->where('plant_id', $plant->id)->first();
            if (!$line) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Line '{$lineName}' not found for plant '{$plantName}'"
                ], 404);
            }
            $lineIds = [$line->id];
            $isFgLine = $line->type == 'FG Line';
            $baseTable = $isFgLine ? 'quality_validations' : 'production_quantities';
        }

        if ($filterName == 'yesterday') {
            $startDate = now()->subDay()->setTime(8, 0, 0);
            $endDate = now()->setTime(8, 0, 0);
            $groupBy = 'EXTRACT(HOUR FROM created_at)';
        } elseif ($filterName == 'this week') {
            $startDate = now()->startOfWeek()->setTime(8, 0, 0);
            $endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0);
            $groupBy = 'EXTRACT(DOW FROM created_at)';
        } elseif ($filterName == 'this month') {
            $startDate = now()->startOfMonth();
            $endDate = now()->endOfMonth();
            $groupBy = "FLOOR((EXTRACT(DAY FROM created_at) - 1) / 7) + 1";
        } else {
            $startDate = now()->setTime(8, 0, 0);
            $endDate = now()->copy()->addDay()->setTime(8, 0, 0);
            $groupBy = 'EXTRACT(HOUR FROM created_at)';
        }

        if ($chartName == 'Production Line Count' && $isAllLines) {
            $lineCounts = [];
            foreach ($lines as $line) {
                $table = ($line->type == 'FG Line') ? 'quality_validations' : 'production_quantities';
                $count = DB::table($table)
                    ->where('plant_id', $plant->id)
                    ->where('line_id', $line->id)
                    ->whereBetween('created_at', [$startDate, $endDate])
                    ->count();
                $lineCounts[$line->name] = $count;
            }

            return response()->json([
                'status_code' => 'SUCCESS',
                'status_description' => $lineCounts
            ], 200);
        }

        if (!$isAllLines)
        {
            $rowCount = DB::table($baseTable)
                ->where('plant_id', $plant->id)
                ->where('line_id', $line->id)
                ->whereBetween('created_at', [$startDate, $endDate])
                ->count();

            $query = DB::table($baseTable)
                ->selectRaw("$groupBy AS time_unit, COUNT(*) AS total_quantity")
                ->where('created_at', '>=', $startDate)
                ->where('created_at', '<', $endDate)
                ->where('plant_id', $plant->id)
                ->where('line_id', $line->id)
                ->groupByRaw($groupBy)
                ->orderByRaw($groupBy)
                ->pluck('total_quantity', 'time_unit')
                ->toArray();

            if ($chartName == 'Production Hourly Count') {
                if ($filterName == '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);
                } elseif ($filterName == '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, $data[2] ?? 0, $data[3] ?? 0,
                        $data[4] ?? 0, $data[5] ?? 0, $data[6] ?? 0,
                        $data[0] ?? 0,
                    ];
                } else {
                    $allHours = array_fill(0, 24, 0);
                    $data = array_replace($allHours, $query);
                    $shiftedData = [];
                    foreach ($data as $hour => $count) {
                        $nextHour = ($hour + 1) % 24;
                        $shiftedData[$nextHour] = $count;
                    }
                    $shiftedKeys = array_merge(range(9, 23), range(0, 8));
                    $orderedData = array_map(fn($hour) => $shiftedData[$hour] ?? 0, $shiftedKeys);
                    $labels = array_map(function ($hour) {
                        $prevHour = ($hour - 1 + 24) % 24;
                        return date("g:i A", strtotime("$prevHour:00")) . ' to ' . date("g:i A", strtotime("$hour:00"));
                    }, $shiftedKeys);
                }

                return response()->json([
                    'status_code' => 'SUCCESS',
                    'datasets' => [[
                        'label' => match ($filterName) {
                            'this week' => $isFgLine ? 'Daily FG Count This Week' : 'Daily Production This Week',
                            'this month' => $isFgLine ? 'Weekly FG Count This Month' : 'Weekly Production This Month',
                            'yesterday' => $isFgLine ? "Yesterday's FG Count" : "Yesterday's Hourly Production",
                            default => $isFgLine ? "Today's FG Count" : "Today's Hourly Production",
                        },
                        'data' => $orderedData
                    ]],
                    'labels' => $labels,
                ], 200);
            }

            if ($chartName == 'Production Line Count') {
                return response()->json([
                    'status_code' => 'SUCCESS',
                    'status_description' => $rowCount
                ], 200);
            }
        }
    }




    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}
