<?php

namespace App\Services;

use App\Models\Device;
use App\Models\TimeseriesKeyMaster;
use App\Models\TimeseriesAlertMessage;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;

class TelemetryService
{
    protected $customerInfoService;
    protected $adminService;

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

    public function getDeviceHealth(array $values): string
    {
        $hasRed = false;
        $hasOrange = false;

        foreach ($values as $value) {
            $key = $value['key_name'];
            $val = $value['value'];

            switch ($key) {
                case 'PowerLoss_value':
                    if ($val > 5 && $val < 10) {
                        return 'red';
                    } elseif ($val > 2.5 && $val < 6) {
                        $hasOrange = true;
                    }
                    break;

                case 'GlobalLevel_value':
                    if ($val > 6 && $val < 10) {
                        return 'red';
                    } elseif ($val > 3 && $val < 7) {
                        $hasOrange = true;
                    }
                    break;

                case 'PropellerEfficiency_value':
                    if ($val > 5 && $val < 10) {
                        return 'red';
                    } elseif ($val > 3 && $val < 6) {
                        $hasOrange = true;
                    }
                    break;

                // case 'OT':
                // case 'AT':
                //     $val > 50 ? $hasRed = true : $hasOrange = true;
                //     break;

                case 'TDN':
                    if ($val > 0 && $val < 401) {
                        return 'red';
                    } elseif ($val < 701) {
                        $hasOrange = true;
                    }
                    break;

                default:
                    if ($val > 0 && $val < 31) {
                        return 'red';
                    } elseif ($val < 71) {
                        $hasOrange = true;
                    }
                    break;
            }
        }

        return $hasRed ? 'red' : ($hasOrange ? 'orange' : 'green');
    }


    public function getAssetHealth(array $deviceHealthStatuses): string
    {
        if (in_array('red', $deviceHealthStatuses)) {
            return 'red';
        }
        return in_array('orange', $deviceHealthStatuses) ? 'orange' : 'green';
    }

    public function convertToUserTimezone($utcDatetime, $userTimezone = 'Asia/Kolkata', $format = 'd-M-Y H:i:s')
    {
        return Carbon::parse($utcDatetime, 'UTC')
            ->setTimezone($userTimezone)
            ->format($format);
    }

    public function getThresholdMap(): array
    {
        return [
            'ChannelSpeed' => [
                ['threshold' => 5000, 'color' => 'green']
            ],
            'StaticTorque_value' => [
                ['threshold' => 5000, 'color' => 'green']
            ],
            'StaticPower_value' => [
                ['threshold' => 5000, 'color' => 'green']
            ],
            'PropellerEfficiency_value' => [
                ['threshold' => 3, 'color' => 'green'],
                ['threshold' => 4.5, 'color' => 'orange'],
                ['threshold' => 6, 'color' => 'orange']
            ],
            'StaticTorsion_value' => [
                ['threshold' => 2.5, 'color' => 'green'],
                ['threshold' => 5, 'color' => 'orange'],
                ['threshold' => 7.5, 'color' => 'orange']
            ],
            'PowerLoss_value' => [
                ['threshold' => 3, 'color' => 'green'],
                ['threshold' => 6, 'color' => 'orange'],
                ['threshold' => 10, 'color' => 'red']
            ],
            'GlobalLevel_value' => [
                ['threshold' => 2, 'color' => 'green'],
                ['threshold' => 6, 'color' => 'orange'],
                ['threshold' => 8, 'color' => 'orange']
            ],
            'TDN' => [
                ['threshold' => 400, 'color' => 'red'],
                ['threshold' => 550, 'color' => 'orange'],
                ['threshold' => 700, 'color' => 'orange']
            ],
            'OT' => [
                ['threshold' => 30, 'color' => 'blue'],
                ['threshold' => 50, 'color' => 'blue'],
                ['threshold' => 70, 'color' => 'red'],
            ],
            'AT' => [
                ['threshold' => 30, 'color' => 'blue'],
                ['threshold' => 50, 'color' => 'blue'],
                ['threshold' => 70, 'color' => 'red'],
            ],
            'default' => [
                ['threshold' => 30, 'color' => 'red'],
                ['threshold' => 50, 'color' => 'orange'],
                ['threshold' => 70, 'color' => 'orange']
            ]
        ];
    }

    public function getThresholdLimit($deviceId): array
    {
        $device = Device::find($deviceId);
        return [
            'ChannelSpeed' => [
                ['min' => 0, 'max' => $device->speed_limit ?? 50000]
            ],
            'PowerLoss_value' => [
                ['min' => 0, 'max' => 10]
            ],
            'GlobalLevel_value' => [
                ['min' => 0, 'max' => 10]
            ],
            'StaticTorque_value' => [
                ['min' => 0, 'max' => $device->torque_limit ?? 50000]
            ],
            'StaticPower_value' => [
                ['min' => 0, 'max' => $device->power_limit ?? 500000]
            ],
            'PropellerEfficiency_value' => [
                ['min' => 0, 'max' => 10]
            ],
            'StaticTorsion_value' => [
                ['min' => 0, 'max' => 6]
            ],
            'TDN' => [
                ['min' => 0, 'max' => 1400]
            ],
            'OT' => [
                ['min' => 0, 'max' => 100]
            ],
            'AT' => [
                ['min' => 0, 'max' => 100]
            ],
            'default' => [
                ['min' => 0, 'max' => 100]
            ]
        ];
    }

    public function getHealthStatus(float $value, array $thresholds): string
    {
        foreach ($thresholds as $t) {
            if ($value < $t['threshold']) {
                return match ($t['color']) {
                    'red' => 'Alert',
                    'orange' => 'Attention',
                    'green' => 'Stable',
                    'blue' => 'Stable',
                    default => $t['threshold'] == 70 ? 'Stable' : 'Alert'
                };
            }
        }
        return 'Stable';
    }

    public function transformTelemetryData(string $deviceId, array $data, array $displayNameMap, bool $isActive): array
    {
        $transformedTelemetry = [];
        $dateTime = null;

        if (!empty($data) && is_array($data)) {
            foreach ($data as $key => $items) {
                foreach ($items as $item) {
                    $dateTime = Carbon::createFromTimestamp($item['ts'] / 1000)->format('d-M-Y H:i:s');
                    $value = $item['value'];

                    $thresholds = $this->getThresholdMap()[$key] ?? $this->getThresholdMap()['default'];
                    $thresholdLimits = $this->getThresholdLimit($deviceId)[$key] ?? $this->getThresholdLimit($deviceId)['default'];

                    if(!$value){
                        $transformedTelemetry[] = [
                            'display_name'  => $displayNameMap[$key] ?? $key,
                            'value'         => "",
                            'health_status' => "",
                            'status_color'  => "",
                            'thresholds'    => $thresholds,
                            'limit'         => $thresholdLimits
                        ];
                    } else {
                        $status = $this->getHealthStatus($value, $thresholds);
                        $statusColor = match($status) {
                            'Alert' => 'red',
                            'Attention' => 'orange',
                            'Stable' => 'green'
                        };

                        $transformedTelemetry[] = [
                            'display_name'  => $displayNameMap[$key] ?? $key,
                            'value'         => $this->getTypeWiseValue($key, $value),
                            'health_status' => !$isActive
                                ? 'Offline'
                                : (in_array($displayNameMap[$key], ['Speed', 'RPM']) ? '' : $status),
                            // 'health_status' => in_array($displayNameMap[$key], ['Speed', 'RPM']) ? '' : $status,
                            'status_color'  => !$isActive ? 'gray' : $statusColor,
                            'thresholds'    => $thresholds,
                            'limit'         => $thresholdLimits
                        ];
                    }
                }
            }
        }

        return [
            'telemetry' => $transformedTelemetry,
            'dateTime' => $dateTime
        ];
    }

    public function getTypeWiseValue($key, $value){
        if($key === 'PowerLoss_value' || $key === 'GlobalLevel_value' || $key === 'OT' || $key === 'PropellerEfficiency_value') {
            return round($value, 2);
        } else if($key === 'StaticTorsion_value' || $key === 'StaticTorque_value' || $key === 'StaticPower_value'){
            return round($value,3);
        } else {
            return round($value);
        }
    }
}
