<?php

namespace App\Http\Controllers\APIS\CustomerApi;

use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\User;
use Illuminate\Http\Request;
use App\Services\CustomerInfoService;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Tymon\JWTAuth\Facades\JWTAuth;


class CustomerDeviceInfoController extends Controller
{
    protected $customerInfoService;

    public function __construct(CustomerInfoService $customerInfoService)
    {
        $this->customerInfoService = $customerInfoService;
    }






    // public function customerDeviceInfo(Request $request)
    // {
    // try {
    //     $tokenPayload = getTokenFromHeader($request);

    //     if (isset($tokenPayload['error'])) {
    //         return response()->json($tokenPayload, 401);
    //     }

    //     $userId = $tokenPayload['sub'];

    //     // Get user with assets and devices
    //     $user = User::with(['assets' => function($query) {
    //                     $query->with(['devices:id,name,asset_id']);
    //                 }])
    //         ->where('id', $userId)
    //         ->first();

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

    //     try {
    //         // Get devices data from ThingsBoard service
    //         $devicesArray = $this->customerInfoService->getThingsBoardDevices($user->customer_id);

    //         if (!is_array($devicesArray)) {
    //             throw new \Exception("Invalid devices data received from service");
    //         }

    //         $thingsBoardDevices = collect($devicesArray);

    //         // Process devices
    //         $deviceDetails = $user->assets->flatMap(function ($asset) use ($thingsBoardDevices) {
    //             return $thingsBoardDevices->whereIn('id.id', $asset->devices->pluck('id')->toArray())
    //                 ->map(function ($tbDevice) {
    //                     return [
    //                         'device_id' => $tbDevice['id']['id'],
    //                         'active' => $tbDevice['active'] ?? false
    //                     ];
    //                 });
    //         });

    //         // Calculate counts
    //         $good = $deviceDetails->where('active', true)->count();
    //         $moderate = $deviceDetails->where('active', false)->count();
    //         $total_count = $good + $moderate;

    //         // Successful response
    //         return response()->json([
    //             'good' => $good,
    //             'moderate' => $moderate,
    //             'total_count' => $total_count
    //         ], 200);

    //     } catch (\Exception $serviceException) {
    //         Log::error("ThingsBoard service error: " . $serviceException->getMessage());
    //         return response()->json([
    //             'error' => 'Failed to fetch device information',
    //             'details' => $serviceException->getMessage()
    //         ], 503);
    //     }

    // } catch (\Exception $e) {
    //     Log::error("Customer device info error: " . $e->getMessage());
    //     return response()->json([
    //         'error' => 'An unexpected error occurred',
    //         'details' => $e->getMessage()
    //     ], 500);
    // }

    // }



    // public function customerDeviceInfo(Request $request)
    // {
    //     try {


    //         $token = readHeaderToken();

    //         if (!$token) {
    //             return response()->json([
    //                 'success' => false,
    //                 'error' => 'Authorization token required'
    //             ], 401);
    //         }


    //         $user = User::with(['assets.devices:id,name,asset_id'])
    //             ->find($token['sub']);

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

    //         $devicesArray = $this->customerInfoService->getThingsBoardDevices($user->customer_id);

    //         if (isset($devicesArray['error'])) {
    //             throw new \Exception($devicesArray['message'] ?? 'Failed to fetch devices');
    //         }

    //         if (!is_array($devicesArray)) {
    //             throw new \Exception("Invalid devices data format received from service");
    //         }


    //         $userDeviceIds = $user->assets->flatMap->devices->pluck('id')->toArray();

    //         $activeCount = collect($devicesArray)
    //             ->whereIn('id.id', $userDeviceIds)
    //             ->where('active', true)
    //             ->count();

    //          $deviceIdCount = count($userDeviceIds);
    //         return response()->json([
    //             'data' => [
    //                 'active_count' => $activeCount,
    //                 'total_count' => $deviceIdCount,
    //             ],
    //             'success' => true
    //         ], 200);

    //     } catch (\Exception $e) {
    //         Log::error("Device info error: " . $e->getMessage());
    //         $statusCode = ($e->getMessage() === "Invalid devices data format received from service") ? 503 : 500;

    //         return response()->json([
    //             'error' => 'server_error',
    //             'message' => 'An error occurred',
    //             'details' => $e->getMessage()
    //         ], $statusCode);
    //     }
    // }

    public function customerDeviceInfo(Request $request)
    {
        try {
            $token = readHeaderToken($request);
            if (!$token) {
                return response()->json([
                    'success' => false,
                    'error' => 'authorization_required',
                    'message' => 'Authorization token required'
                ], 401);
            }

            // Get user with devices
            $user = User::with(['assets.devices:id,name,asset_id'])
                ->find($token['sub']);

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

            // Get user's device IDs
            $userDevices = $user->assets->flatMap->devices;
            $userDeviceIds = $userDevices->pluck('id')->toArray();

            if (empty($userDeviceIds)) {
                return response()->json([
                    'data' => [
                        'active_count' => 0,
                        'total_count' => 0,
                        'alarms_count' => 0,
                        'red_count' => 0,
                        'yellow_count' => 0,
                        'green_count' => 0
                    ],
                    'success' => true
                ], 200);
            }

            // Get devices and alarms from service
            $serviceResponse = $this->customerInfoService->getCustomerDevicesAndAlarms(
                $user->customer_id,
                $userDeviceIds
            );

            // Handle service errors
            if (isset($serviceResponse['error'])) {
                throw new \Exception($serviceResponse['message'] ?? 'Service request failed');
            }

            // Process devices
            $devices = $serviceResponse['devices'] ?? [];
            $activeCount = collect($devices)
                ->whereIn('id.id', $userDeviceIds)
                ->where('active', true)
                ->count();

            // Process alarms
            $alarms = $serviceResponse['alarms'] ?? [];
            $recentAlarms = $this->filterRecentAlarms($alarms);

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


            $bad = 0;
            $moderate = 0;
            $good = 0;

            foreach ($userDevices as $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;

                $mechanicalHealthValue1 = isset($telemetryData['MechanicalHealth_valueInPercent'][0]['value'])
                    ? (float) $telemetryData['MechanicalHealth_valueInPercent'][0]['value']
                    : null;

                $engineEfficiencyValue1 = isset($telemetryData['EngineEfficiency_valueInPercent'][0]['value'])
                    ? (float) $telemetryData['EngineEfficiency_valueInPercent'][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;

                // Determine health status
                if ($engineName === "Torque") {
                    $good++;
                } elseif (
                    ($mechanicalHealthValue1 > 0 && $mechanicalHealthValue1 < 31) ||
                    ($engineEfficiencyValue1 > 0 && $engineEfficiencyValue1 < 31) ||
                    ($engineEfficiencyValue4 > 0 && $engineEfficiencyValue4 < 31) ||
                    ($powerLossValue1 > 0 && $powerLossValue1 < 31)
                ) {
                    $bad++;
                } elseif (
                    ($mechanicalHealthValue1 >= 31 && $mechanicalHealthValue1 < 71) ||
                    ($engineEfficiencyValue1 >= 31 && $engineEfficiencyValue1 < 71) ||
                    ($engineEfficiencyValue4 >= 31 && $engineEfficiencyValue4 < 71) ||
                    ($powerLossValue1 >= 31 && $powerLossValue1 < 71)
                ) {
                    $moderate++;
                } else {
                    $good++;
                }
            }

            return response()->json([
                'data' => [
                    'active_count' => $activeCount,
                    'total_count' => count($userDeviceIds),
                    'alarms_count' => count($recentAlarms),
                    'bad' => $bad,
                    'moderate' => $moderate,
                    'good' => $good,
                ],
                'success' => true
            ], 200);
        } catch (\Exception $e) {
            Log::error("Device info error: " . $e->getMessage());
            return response()->json([
                'success' => false,
                'error' => 'server_error',
                'message' => 'An error occurred while fetching device information',
                'details' => $e->getMessage()
            ], 500);
        }
    }


    private function filterRecentAlarms(array $alarms): array
    {
        $twentyFourHoursAgo = (time() - 86400) * 1000;

        return array_values(array_filter($alarms, function ($alarm) use ($twentyFourHoursAgo) {
            return ($alarm['createdTime'] ?? 0) >= $twentyFourHoursAgo;
        }));
    }

    public function userInfo(Request $request){
        try{
            $token = readHeaderToken();
            $userId = $token['sub'];

            $user = User::find($userId);
            if(!$user){
                return response()->json([
                    'success' => false,
                    'error' => 'user_not_found',
                    'message' => 'User not found'
                ], 404);
            }

            return response()->json($user);


        } catch(\Exception $e){
            return response()->json([
                'success' => false,
                'error' => 'server_error',
                'message' => 'An error occurred while fetching user information',
                'details' => $e->getMessage()
            ], 500);
        }
    }
}
