<?php
namespace app\api\controller;

use app\common\model\device\Device;
use app\common\model\device\DeviceOffline;
use app\common\model\device\MonitorAlarm;
use app\common\model\device\MonitorThreshold;
use app\common\model\land\LandProduct;
use app\common\model\LandCollection;
use app\common\model\product\ProductDevice;
use app\common\model\User;
use Exception;
use think\Db;
use think\facade\Log;

class DataCollectController extends BaseApiController
{
    public array $notNeedLogin = ['collect', 'disabled'];
    // 养殖数据采集
    public function collect()
    {
        try {

            $parmas = $this->request->post();
            Log::info('采集消息发布'.json_encode($parmas));

            $payload= json_decode($parmas['payload'], true);

            $user = User::where('account', $parmas['username'])->find();

            $device = explode('_', $parmas['topic']); // 命名规则：camera_deviceid  deviceid为设备主键id
            $deviceId = $device[1]; // 设备id

            $productDevice = ProductDevice::where('device_id', $deviceId)->find();
            $landProduct = LandProduct::where('product_id', $productDevice['product_id'])->find();
            $landId = $landProduct['land_id']; // 土地id

            // mqtt服务端 消息发布事件
            if ($parmas['event'] == 'message.publish') {

                $data = [
                    'user_id' => $user['id'],
                    'land_id' => $landId,
                    'device_id' => $deviceId,
                    'qos'=>$parmas['qos'],
                    'wind_speed' => $payload['wind_speed'],
                    'wind_direction' => $payload['wind_direction'],
                    'ambient_temperature' => $payload['ambient_temperature'],
                    'ambient_humidity' => $payload['ambient_humidity'],
                    'carbon_dioxide' => $payload['carbon_dioxide'],
                    'ambient_air_pressure' => $payload['ambient_air_pressure'],
                    'rainfall' => $payload['rainfall'],
                    'ambient_lighting' => $payload['ambient_lighting'],
                    'soil_temperature' => $payload['soil_temperature'],
                    'soil_conductivity' => $payload['soil_conductivity'],
                    'soil_moisture' => $payload['soil_moisture'],
                    'soil_PH' => $payload['soil_PH'],
                    'soil_potassium_phosphate_nitrogen' => $payload['soil_potassium_phosphate_nitrogen'],
                    'soil_potassium_phosphate_phosphorus' => $payload['soil_potassium_phosphate_phosphorus'],
                    'soil_potassium_phosphate_potassium' => $payload['soil_potassium_phosphate_potassium'],
                    'client_id'=>$parmas['clientid'],
                    'create_time'=>date('Y-m-d H:i:s'),
                    'update_time'=>date('Y-m-d H:i:s'),
                ];

                LandCollection::create($data);

                // 设备告警
                $monitorThreshold =  (new MonitorThreshold())->select()->toArray()[0];
                // 风速告警
                if ($payload['wind_speed'] > $monitorThreshold['wind_speed_max']) {
                    self::createAlarm($landId, $deviceId, 'wind_speed', '风速偏快' ,$payload['wind_speed']);
                }

                // ambient_temperature 环境温度
                if ($payload['ambient_temperature'] < $monitorThreshold['air_temp_min']) {
                    self::createAlarm($landId, $deviceId, 'ambient_temperature', '气温偏低' ,$payload['ambient_temperature']);
                }

                // ambient_temperature 环境温度
                if ($payload['ambient_temperature'] > $monitorThreshold['air_temp_max']) {
                    self::createAlarm($landId, $deviceId, 'ambient_temperature', '气温偏高' ,$payload['ambient_temperature']);
                }

                // ambient_humidity 环境湿度
                if ($payload['ambient_humidity'] < $monitorThreshold['air_mois_min']) {
                    self::createAlarm($landId, $deviceId, 'ambient_humidity', '环境湿度偏低' ,$payload['ambient_humidity']);
                }
                // ambient_humidity 环境湿度
                if ($payload['ambient_humidity'] < $monitorThreshold['air_mois_max']) {
                    self::createAlarm($landId, $deviceId, 'ambient_humidity', '环境湿度偏高' ,$payload['ambient_humidity']);
                }

                // carbon_dioxide 二氧化碳含量
                if ($payload['carbon_dioxide'] > $monitorThreshold['air_co2_content_max']) {
                    self::createAlarm($landId, $deviceId, 'carbon_dioxide', '空气二氧化碳含量偏高' ,$payload['carbon_dioxide']);
                }
                // carbon_dioxide 二氧化碳含量
                if ($payload['carbon_dioxide'] < $monitorThreshold['air_co2_content_min']) {
                    self::createAlarm($landId, $deviceId, 'carbon_dioxide', '空气二氧化碳含量偏低' ,$payload['carbon_dioxide']);
                }

                // ambient_air_pressure 大气压力
                if ($payload['ambient_air_pressure'] >= 120)
                {
                    self::createAlarm($landId, $deviceId, 'ambient_air_pressure', '大气压力偏高' ,$payload['ambient_air_pressure']);
                }
                if ($payload['ambient_air_pressure'] < 10)
                {
                    self::createAlarm($landId, $deviceId, 'ambient_air_pressure', '大气压力偏低' ,$payload['ambient_air_pressure']);
                }

                // rainfall 雨量
//                if ($payload['rainfall'] >= 100)
                // ambient_lighting 光照

                // soil_temperature 土壤温度
                if ($payload['soil_temperature'] >= $monitorThreshold['soil_temp_max']) {
                    self::createAlarm($landId, $deviceId, 'soil_temperature', '土壤温度偏高' ,$payload['soil_temperature']);
                }
                // soil_temperature 土壤温度
                if ($payload['soil_temperature'] < $monitorThreshold['soil_temp_min']) {
                    self::createAlarm($landId, $deviceId, 'soil_temperature', '土壤温度偏低' ,$payload['soil_temperature']);
                }

                // soil_conductivity 土壤电导率
//                if ($payload['soil_conductivity'] < $monitorThreshold['soil_mois_max']) {
//                    self::createAlarm($land[3], $deviceId, '土壤电导率', '土壤湿度偏高' ,$payload['soil_conductivity']);
//                }
//                if ($payload['soil_conductivity'] < $monitorThreshold['soil_mois_min']) {
//                    self::createAlarm($land[3], $deviceId, '土壤电导率', '土壤湿度偏低' ,$payload['soil_conductivity']);
//                }

                // soil_conductivity 土壤湿度
                if ($payload['soil_moisture'] < $monitorThreshold['soil_mois_max']) {
                    self::createAlarm($landId, $deviceId, 'soil_moisture', '土壤湿度偏高' ,$payload['soil_moisture']);
                }
                if ($payload['soil_moisture'] < $monitorThreshold['soil_mois_min']) {
                    self::createAlarm($landId, $deviceId, 'soil_moisture', '土壤湿度偏低' ,$payload['soil_moisture']);
                }

                // soil_PH 土壤ph值
                if ($payload['soil_PH'] < $monitorThreshold['soil_ph_max']) {
                    self::createAlarm($landId, $deviceId, 'soil_PH', '土壤PH值偏碱性' ,$payload['soil_moisture']);
                }
                if ($payload['soil_PH'] < $monitorThreshold['soil_ph_min']) {
                    self::createAlarm($landId, $deviceId, 'soil_PH', '土壤PH值偏酸性' ,$payload['soil_moisture']);
                }

                // soil_potassium_phosphate_nitrogen 土壤磷酸钾：氮
                if ($payload['soil_potassium_phosphate_nitrogen'] < $monitorThreshold['soil_n_content_max']) {
                    self::createAlarm($landId, $deviceId, 'soil_potassium_phosphate_nitrogen', '土壤磷酸钾-含氮量偏高' ,$payload['soil_potassium_phosphate_nitrogen']);
                }
                if ($payload['soil_potassium_phosphate_nitrogen'] < $monitorThreshold['soil_n_content_min']) {
                    self::createAlarm($landId, $deviceId, 'soil_potassium_phosphate_nitrogen', '土壤磷酸钾-含氮量偏低' ,$payload['soil_potassium_phosphate_nitrogen']);
                }

                // soil_potassium_phosphate_phosphorus 土壤磷酸钾：磷
                if ($payload['soil_potassium_phosphate_phosphorus'] < $monitorThreshold['soil_p_content_max']) {
                    self::createAlarm($landId, $deviceId, 'soil_potassium_phosphate_phosphorus', '土壤磷酸钾-含磷量偏高' ,$payload['soil_potassium_phosphate_phosphorus']);
                }
                if ($payload['soil_potassium_phosphate_phosphorus'] < $monitorThreshold['soil_p_content_min']) {
                    self::createAlarm($landId, $deviceId, 'soil_potassium_phosphate_phosphorus', '土壤磷酸钾-含磷量偏低' ,$payload['soil_potassium_phosphate_phosphorus']);
                }

                // soil_potassium_phosphate_potassium 土壤磷酸钾：钾
                if ($payload['soil_potassium_phosphate_potassium'] < $monitorThreshold['soil_k_content_max']) {
                    self::createAlarm($landId, $deviceId, 'soil_potassium_phosphate_potassium', '土壤磷酸钾-含钾量偏高' ,$payload['soil_potassium_phosphate_potassium']);
                }
                if ($payload['soil_potassium_phosphate_potassium'] < $monitorThreshold['soil_k_content_min']) {
                    self::createAlarm($landId, $deviceId, 'soil_potassium_phosphate_potassium', '土壤磷酸钾-含钾量偏低' ,$payload['soil_potassium_phosphate_potassium']);
                }

                return $this->success('接收成功', ['user_name'=>$parmas['username'], 'topic'=>$parmas['topic']]);
            }

            // mqtt服务端 连接断开事件 客户端断开表示该土块的所有设备都已断开 共用同一个mqtt客户端
            if ($parmas['event'] == 'client.disconnected') {

                // 查询该土地关联的设备
                $addData = [
                    'land_id' => $landId,
                    'device_id' => $deviceId,
                    'last_online_time' => $parmas['disconnected_at']/1000,
                    'disconnected_time' => $parmas['disconnected_at']/1000,
                    'create_time' => time(),
                    'update_time' => time()
                ];
                DeviceOffline::create($addData);
                Device::where('id', $deviceId)->update(['is_online' => 2]);
                return $this->success('接收成功');
            }
            // 连接链接事件 设备已上线
            if ($parmas['event'] == 'client.connected') {
                Device::where('id', $deviceId)->update(['is_online' => 1]);
                return $this->success('接收成功');
            }

        } catch (Exception $e) {
            return $this->fail($e->getMessage());
        }
        
    }

    public static function createAlarm($user_id, $device_id, $type, $content, $value)
    {
        $data = [
            'user_id' => $user_id,
            'device_id' => $device_id,
            'type' => $type,
            'content' => $content,
            'value' => $value,
            'create_time' => time(),
            'update_time' => time(),
        ];

        MonitorAlarm::create($data);
    }

    public function disabled()
    {
        $parmas = $this->request->post();
        Log::info('连接断开事件'.json_encode($parmas));
    }
}