<?php

namespace App\Http\Controllers\APIS\CustomerApi;

use App\Http\Controllers\Controller;
use App\Models\Asset;
use App\Models\Device;
use App\Models\User;
use App\Models\UserAssetLink;
use App\Services\AdminService;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Http;
use Illuminate\Container\Attributes\Auth;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use Exception;
use Illuminate\Support\Carbon;

class UserAssetLinkController extends Controller
{
    private $adminService;

    public function __construct(AdminService $adminService)
    {
        $this->adminService = $adminService;
    }

    // public function index()
    // {
    //     try {
    //         $token = readHeaderToken();

    //         // Fetch user with assets and device counts
    //         $user = User::with(['assets.devices'])
    //             ->withCount([
    //                 'assets as active_devices_count' => function ($query) {
    //                     $query->whereHas('devices', function ($q) {
    //                         $q->where('active', 1);
    //                     });
    //                 },
    //                 'assets as inactive_devices_count' => function ($query) {
    //                     $query->whereHas('devices', function ($q) {
    //                         $q->where('active', 0);
    //                     });
    //                 }
    //             ])
    //             ->where('id', $token['sub'])
    //             ->first();

    //         if (!$user) {
    //             return response()->json(['error' => 'User not found'], 404);
    //         }

    //         $bearerToken = $this->adminService->getToken();
    //         $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080');


    //         // Log::info('Devices: ' . json_encode($user->assets->flatMap->devices));
    //         foreach ($user->assets->flatMap->devices as $device) {
    //             $device->health_status = null;
    //             $device->online = null;

    //             // Fetch device details from API using customer_id
    //             $deviceResponse = Http::withHeaders([
    //                 'accept' => 'application/json',
    //                 'Authorization' => 'Bearer ' . $bearerToken,
    //             ])->get("$apiBaseUrl/api/customer/{$device->customer_id}/deviceInfos", [
    //                 'pageSize' => 100,
    //                 'page' => 0
    //             ]);

    //             if (!$deviceResponse->successful()) {
    //                 Log::error("Failed to fetch device info for Customer ID: {$device->customer_id}, Error: " . $deviceResponse->body());
    //                 continue;
    //             }

    //             $deviceData = collect($deviceResponse->json()['data'] ?? []);
    //             $matchingDevice = $deviceData->firstWhere('id.id', $device->id);

    //             // Explicitly set online status for all devices
    //             $device->online = $matchingDevice['active'] ?? null;

    //             // Fetch telemetry data for the device
    //             $telemetryResponse = Http::withHeaders([
    //                 'accept' => 'application/json',
    //                 'Authorization' => 'Bearer ' . $bearerToken,
    //             ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [
    //                 'useStrictDataTypes' => 'false'
    //             ]);

    //             if (!$telemetryResponse->successful()) {
    //                 Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body());
    //                 continue;
    //             }

    //             $telemetryData = $telemetryResponse->json();
    //             // Log::info('Telemetry data: ' . json_encode($telemetryData));

    //             $engineName = $telemetryData['Engine_Name'][0]['value'] ?? null;

    //             // Extract values from telemetry data
    //             $mechanicalHealthValue1 = isset($telemetryData['MechanicalHealth_value'][0]['value'])
    //                 ? (float) $telemetryData['MechanicalHealth_value'][0]['value']
    //                 : null;

    //             $engineEfficiencyValue1 = isset($telemetryData['EngineEfficiency_value'][0]['value'])
    //                 ? (float) $telemetryData['EngineEfficiency_value'][0]['value']
    //                 : null;

    //             $engineEfficiencyValue4 = isset($telemetryData['EngineEfficiency_valueInHealth'][0]['value'])
    //                 ? (float) $telemetryData['EngineEfficiency_valueInHealth'][0]['value']
    //                 : null;

    //             $powerLossValue1 = isset($telemetryData['PowerLoss_value'][0]['value'])
    //                 ? (float) $telemetryData['PowerLoss_value'][0]['value']
    //                 : null;

    //             // Default health status
    //             $healthStatusColor = '#0EC23E'; // Green

    //             if ($engineName === "Torque") {
    //                 $healthStatusColor = '#0EC23E'; // Green
    //             } elseif (
    //                 ($mechanicalHealthValue1 > 0 && $mechanicalHealthValue1 < 31) ||
    //                 ($engineEfficiencyValue1 > 0 && $engineEfficiencyValue1 < 31) ||
    //                 ($engineEfficiencyValue4 > 0 && $engineEfficiencyValue4 < 31) ||
    //                 ($powerLossValue1 > 0 && $powerLossValue1 < 31)
    //             ) {
    //                 $healthStatusColor = '#EF7F30'; // Red
    //             } elseif (
    //                 ($mechanicalHealthValue1 > 30 && $mechanicalHealthValue1 < 71) ||
    //                 ($engineEfficiencyValue1 > 30 && $engineEfficiencyValue1 < 71) ||
    //                 ($engineEfficiencyValue4 > 30 && $engineEfficiencyValue4 < 71) ||
    //                 ($powerLossValue1 > 30 && $powerLossValue1 < 71)
    //             ) {
    //                 $healthStatusColor = '#FFC164'; // Yellow
    //             }

    //             $device->health_status = "<div style='height: 10px; width: 10px; border-radius: 50%; display: inline-block; margin-left: 10px; background-color: $healthStatusColor'></div>";
    //         }


    //         return response()->json($user);
    //     } catch (Exception $e) {
    //         Log::error('Error fetching telemetry data: ' . $e->getMessage());
    //         return response()->json(['error' => 'Failed to fetch data'], 500);
    //     }
    // }

    // public function index()
    // {
    //     try {
    //         $token = readHeaderToken();

    //         $user = User::with(['assets.devices'])
    //             ->withCount([
    //                 'assets as active_devices_count' => function ($query) {
    //                     $query->whereHas('devices', function ($q) {
    //                         $q->where('active', 1);
    //                     });
    //                 },
    //                 'assets as inactive_devices_count' => function ($query) {
    //                     $query->whereHas('devices', function ($q) {
    //                         $q->where('active', 0);
    //                     });
    //                 }
    //             ])
    //             ->where('id', $token['sub'])
    //             ->first();

    //         if (!$user) {
    //             return response()->json(['error' => 'User not found'], 404);
    //         }

    //         $bearerToken = $this->adminService->getToken();
    //         $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080');
    //         $thirtyDaysAgo = now()->subDays(30)->timestamp * 1000;
    //         $currentTime = now()->timestamp * 1000;


    //         $deviceParameters = [
    //             'Engine Health' => ['MechanicalHealth_valueInPercent', 'EngineEfficiency_valueInPercent', 'PowerLoss_value'],
    //             'Bearing' => ['MBearing_valueInPercent', 'MElectromag_valueInPercent', 'MStressStability_valueInPercent'],
    //             'Mechanical Health' => ['BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
    //             'Regularity/Deviation' => ['RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'],
    //             'Bearing Status' => ['BearingStatus_valueInPercent', 'RegularityDeviation_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'],
    //             'Shaft/Blades Health' => ['BladeStatusGas_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'],
    //             'Combustion Kit' => ['CombustionKit_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'TurbineCoupling_valueInPercent'],
    //             'Coupling/Alignment' => ['TurbineCoupling_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent'],
    //             'Electromagnetic Stress' => ['MElectromag_valueInPercent', 'MStressStability_valueInPercent', 'MBearing_valueInPercent'],
    //             'Stability' => ['MStressStability_valueInPercent', 'MElectromag_valueInPercent', 'MBearing_valueInPercent'],
    //             'Global (Unbalance/Alignment/Looseness)' => ['GlobalMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
    //             'Shock Index' => ['GlobalKurto_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
    //             'Shaft/Clearance' => ['2KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
    //             'Bearings' => ['4KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '8KMixed_valueInPercent'],
    //             'Friction' => ['8KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent'],
    //         ];

    //         foreach ($user->assets as $asset) {
    //             $asset->celebration_message = null;
    //             $asset->celebration_icon = false; // Default to false
    //             $healthyDevices = [];

    //             foreach ($asset->devices as $device) {
    //                 $device->celebration_message = null;
    //                 $device->celebration_icon = false; // Default to false

    //                 $telemetryResponse = Http::withHeaders([
    //                     'accept' => 'application/json',
    //                     'Authorization' => 'Bearer ' . $bearerToken,
    //                 ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [
    //                     'startTs' => $thirtyDaysAgo,
    //                     'endTs' => $currentTime,
    //                     'useStrictDataTypes' => 'false'
    //                 ]);

    //                 if (!$telemetryResponse->successful()) {
    //                     Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body());
    //                     continue;
    //                 }

    //                 $telemetryData = $telemetryResponse->json();
    //                 $deviceType = trim($device->type) ?? 'Unknown';
    //                 $parameters = $deviceParameters[$deviceType] ?? [];

    //                 $averages = [];
    //                 foreach ($parameters as $param) {
    //                     $averages[$param] = collect($telemetryData[$param] ?? [])
    //                         ->pluck('value')->map(fn($v) => (float)$v)->avg();
    //                 }

    //                 if (collect($averages)->filter(fn($avg) => $avg > 70)->isNotEmpty()) {
    //                     $device->celebration_icon = true; // Set to true
    //                     $device->celebration_message = "Your device '{$device->name}' has maintained good health for the past 30 days.";
    //                     $healthyDevices[] = $device->name;
    //                 }
    //             }

    //             if (!empty($healthyDevices)) {
    //                 $asset->celebration_icon = true; // Set to true
    //                 $asset->celebration_message = "Your asset '{$asset->name}' has maintained good health for the past 30 days, along with the following devices: " . implode(", ", $healthyDevices) . ".";
    //             }
    //         }

    //         return response()->json($user);
    //     } catch (Exception $e) {
    //         Log::error('Error fetching telemetry data: ' . $e->getMessage());
    //         return response()->json(['error' => 'Failed to fetch data'], 500);
    //     }
    // }


    public function index()
    {
        try {
            $token = readHeaderToken();

            $user = User::with(['assets.devices'])
                ->withCount([
                    'assets as active_devices_count' => function ($query) {
                        $query->whereHas('devices', function ($q) {
                            $q->where('active', 1);
                        });
                    },
                    'assets as inactive_devices_count' => function ($query) {
                        $query->whereHas('devices', function ($q) {
                            $q->where('active', 0);
                        });
                    }
                ])
                ->where('id', $token['sub'])
                ->first();

            if (!$user) {
                return response()->json(['error' => 'User not found'], 404);
            }

            $bearerToken = $this->adminService->getToken();
            $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080');
            $currentDate = now();
            $currentMonth = $currentDate->month;
            $currentYear = $currentDate->year;

            $deviceParameters = [
                'Engine Health' => ['MechanicalHealth_valueInPercent', 'EngineEfficiency_valueInPercent', 'PowerLoss_value'],
                'Bearing' => ['MBearing_valueInPercent', 'MElectromag_valueInPercent', 'MStressStability_valueInPercent'],
                'Mechanical Health' => ['BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
                'Regularity/Deviation' => ['RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'],
                'Bearing Status' => ['BearingStatus_valueInPercent', 'RegularityDeviation_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'],
                'Shaft/Blades Health' => ['BladeStatusGas_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'],
                'Combustion Kit' => ['CombustionKit_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'TurbineCoupling_valueInPercent'],
                'Coupling/Alignment' => ['TurbineCoupling_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent'],
                'Electromagnetic Stress' => ['MElectromag_valueInPercent', 'MStressStability_valueInPercent', 'MBearing_valueInPercent'],
                'Stability' => ['MStressStability_valueInPercent', 'MElectromag_valueInPercent', 'MBearing_valueInPercent'],
                'Global (Unbalance/Alignment/Looseness)' => ['GlobalMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
                'Shock Index' => ['GlobalKurto_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
                'Shaft/Clearance' => ['2KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'],
                'Bearings' => ['4KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '8KMixed_valueInPercent'],
                'Friction' => ['8KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent'],
            ];

            foreach ($user->assets as $asset) {
                $asset->celebration_message = null;
                $asset->celebration_icon = false;
                $healthyDevices = [];

                foreach ($asset->devices as $device) {
                    $device->celebration_icon = false;
                    $device->celebration_message = null;
                    $device->online = null;
                    $device->celebration_message = null;

                    $device->celebration_icon = false; // Default to false
                    $device->health_status = 'green';



                    // Fetch online status
                    $deviceResponse = Http::withHeaders([
                        'accept' => 'application/json',
                        'Authorization' => 'Bearer ' . $bearerToken,
                    ])->get("{$apiBaseUrl}api/customer/{$device->customer_id}/deviceInfos", [
                        'pageSize' => 100,
                        'page' => 0
                    ]);

                    if (!$deviceResponse->successful()) {
                        Log::error("Failed to fetch device info for Customer ID: {$device->customer_id}, Error: " . $deviceResponse->body());
                        continue;
                    }

                    $deviceData = collect($deviceResponse->json()['data'] ?? []);
                    $matchingDevice = $deviceData->firstWhere('id.id', $device->id);
                    $device->online = $matchingDevice['active'] ?? false;

                    $deviceType = trim($device->type) ?? 'Unknown';
                    $parameters = $deviceParameters[$deviceType] ?? [];
                    $allParametersHealthy = true;

                    foreach ($parameters as $param) {
                        $allDaysHealthy = true;
                        $daysInMonth = now()->daysInMonth;

                        for ($day = 1; $day <= $daysInMonth; $day++) {
                            $startOfDay = Carbon::create($currentYear, $currentMonth, $day)->startOfDay();
                            $endOfDay = Carbon::create($currentYear, $currentMonth, $day)->endOfDay();

                            $dailyResponse = Http::withHeaders([
                                'accept' => 'application/json',
                                'Authorization' => 'Bearer ' . $bearerToken,
                            ])->get("{$apiBaseUrl}api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [
                                'startTs' => $startOfDay->timestamp * 1000,
                                'endTs' => $endOfDay->timestamp * 1000,
                                'useStrictDataTypes' => 'false'
                            ]);

                            if (!$dailyResponse->successful()) {
                                Log::error("Failed to fetch daily telemetry for Device ID: {$device->id}, Day: $day, Error: " . $dailyResponse->body());
                                $allDaysHealthy = false;
                                break;
                            }

                            $dailyData = $dailyResponse->json();
                            $dailyAvg = collect($dailyData[$param] ?? [])->pluck('value')->map(fn($v) => (float)$v)->avg();

                            if ($dailyAvg <= 70 || is_null($dailyAvg)) {
                                $allDaysHealthy = false;
                                break;
                            }
                        }

                        if (!$allDaysHealthy) {
                            $allParametersHealthy = false;
                            break;
                        }
                    }

                    // === Fetch telemetry once for alerts ===
                    $telemetryResponse = Http::withHeaders([
                        'accept' => 'application/json',
                        'Authorization' => 'Bearer ' . $bearerToken,
                    ])->get("{$apiBaseUrl}api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries");

                    $telemetryData = $telemetryResponse->successful() ? $telemetryResponse->json() : [];

                    // === Alert Logic ===
                    $alerts = [];
                    $deviceModel = Device::with([
                        'timeseriesKeys' => function ($query) {
                            $query->where(function ($q) {
                                $q->where('display_on_dashboard', true)
                                  ->orWhere('display_on_popup', true);
                            })
                            ->select('id', 'device_profile_xid', 'key_name', 'display_name')
                            ->with(['timeseriesAlert' => function ($query) {
                                $query->select('id', 'timeseries_key_master_xid', 'min_value', 'max_value', 'alert_msg');
                            }]);
                        }
                    ])->find($device->id);

                    if ($deviceModel) {
                        foreach ($deviceModel->timeseriesKeys as $key) {
                            $keyName = $key->key_name;
                            $dataPoint = $telemetryData[$keyName][0] ?? null;

                            if (!$dataPoint || !isset($dataPoint['value'])) {
                                continue;
                            }

                            $currentValue = (float) $dataPoint['value'];

                            foreach ($key->timeseriesAlert as $alert) {
                                $minValue = $alert->min_value !== null ? (float) $alert->min_value : null;
                                $maxValue = $alert->max_value !== null ? (float) $alert->max_value : null;

                                $isBelowMin = $minValue !== null && $currentValue < $minValue;
                                $isAboveMax = $maxValue !== null && $currentValue > $maxValue;

                                if ($isBelowMin || $isAboveMax) {
                                    $alerts[] = $alert->alert_msg;
                                }
                            }
                        }
                    }

                    $device->alert = $alerts;

                    // === Celebration logic ===
                    if ($allParametersHealthy && !empty($parameters)) {
                        $device->celebration_icon = true;
                        $device->celebration_message = "Your device '{$device->name}' maintained > 70 average for every parameter on all days of this month.";
                        $healthyDevices[] = $device->name;
                    }
                }

                if (!empty($healthyDevices)) {
                    $asset->celebration_icon = true;
                    $asset->celebration_message = "Your asset '{$asset->name}' has healthy devices this month: " . implode(', ', $healthyDevices) . ".";
                }
            }

            return response()->json($user);
        } catch (Exception $e) {
            Log::error('Error fetching telemetry data: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to fetch data'], 500);
        }
    }

}
