import 'package:syncrow_web/pages/device_managment/all_devices/models/device_community.model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_space_model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_sub_space.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_subspace.model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_tag_model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart';
import 'package:syncrow_web/pages/routines/models/curtain/curtain_function.dart';
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
import 'package:syncrow_web/pages/routines/models/flush/flush_functions.dart';
import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart';
import 'package:syncrow_web/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart';
import 'package:syncrow_web/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart';
import 'package:syncrow_web/pages/routines/models/gateway.dart';
import 'package:syncrow_web/pages/routines/models/pc/energy_clamp_functions.dart';
import 'package:syncrow_web/pages/routines/models/water_heater/water_heater_functions.dart';
import 'package:syncrow_web/pages/routines/models/wps/wps_functions.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_helper.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/enum/device_types.dart';

class AllDevicesModel {
/*
{
  "room": {
    "uuid": "75ea7d60-5104-4726-b5f8-ea426c0c6a1b",
    "name": "Room 1"
  },
  "unit": {
    "uuid": "04fd1dcf-f24a-40db-970d-d0be884ed30f",
    "name": "unit 1"
  },
  "productUuid": "894aad5c-ce03-423a-9d61-2fd0c3f67ebf",
  "productType": "3G",
  "permissionType": "CONTROLLABLE",
  "activeTime": 1722173778,
  "category": "kg",
  "categoryName": "Switch",
  "createTime": 1722173778,
  "gatewayId": "bf0294123ed2c19067skrk",
  "icon": "smart/icon/bay1642572935385vcsA/2b1f5efbaa5bbf81c3164fa312cf2032.png",
  "ip": "",
  "lat": "31.97",
  "localKey": "T/39+<l/![iv>:9M",
  "lon": "35.89",
  "model": "S01ZLSWBSA3",
  "name": "3 Gang Button Switch L-L",
  "nodeId": "60a423fffed5a7f6",
  "online": true,
  "ownerId": "199200732",
  "sub": true,
  "timeZone": "+03:00",
  "updateTime": 1723626515,
  "uuid": "5b31dae4-ce9c-4c70-b52b-7e15011163bf"
} 
*/

  DevicesModelRoom? room;
  DeviceSubspace? subspace;
  DevicesModelUnit? unit;
  DeviceCommunityModel? community;
  String? productUuid;
  String? productType;
  String? permissionType;
  int? activeTime;
  String? category;
  String? categoryName;
  int? createTime;
  String? gatewayId;
  String? icon;
  String? ip;
  String? lat;
  String? localKey;
  String? lon;
  String? model;
  String? name;
  String? nodeId;
  bool? online;
  String? ownerId;
  bool? sub;
  String? timeZone;
  int? updateTime;
  String? uuid;
  int? batteryLevel;
  String? productName;
  List<DeviceSpaceModel>? spaces;
  List<DeviceTagModel>? deviceTags;
  DeviceSubSpace? deviceSubSpace;

  AllDevicesModel(
      {this.room,
      this.subspace,
      this.unit,
      this.community,
      this.productUuid,
      this.productType,
      this.permissionType,
      this.activeTime,
      this.category,
      this.categoryName,
      this.createTime,
      this.gatewayId,
      this.icon,
      this.ip,
      this.lat,
      this.localKey,
      this.lon,
      this.model,
      this.name,
      this.nodeId,
      this.online,
      this.ownerId,
      this.sub,
      this.timeZone,
      this.updateTime,
      this.uuid,
      this.batteryLevel,
      this.productName,
      this.spaces,
      this.deviceTags,
      this.deviceSubSpace});

  AllDevicesModel.fromJson(Map<String, dynamic> json) {
    room = (json['room'] != null && (json['room'] is Map))
        ? DevicesModelRoom.fromJson(json['room'])
        : null;
    subspace = (json['subspace'] != null && (json['subspace'] is Map))
        ? DeviceSubspace.fromJson(json['subspace'])
        : null;
    unit = (json['unit'] != null && (json['unit'] is Map))
        ? DevicesModelUnit.fromJson(json['unit'])
        : null;
    community = (json['community'] != null && (json['community'] is Map))
        ? DeviceCommunityModel.fromJson(json['community'])
        : null;
    productUuid = json['productUuid']?.toString();
    productType = json['productType']?.toString();
    permissionType = json['permissionType']?.toString();
    activeTime = int.tryParse(json['activeTime']?.toString() ?? '');
    category = json['category']?.toString();
    categoryName = json['categoryName']?.toString();
    createTime = int.tryParse(json['createTime']?.toString() ?? '');
    gatewayId = json['gatewayId']?.toString();
    icon = json['icon'] ?? getDefaultIcon(productType);
    ip = json['ip']?.toString();
    lat = json['lat']?.toString();
    localKey = json['localKey']?.toString();
    lon = json['lon']?.toString();
    model = json['model']?.toString();
    name = json['name']?.toString();
    nodeId = json['nodeId']?.toString();
    online = json['online'];
    ownerId = json['ownerId']?.toString();
    sub = json['sub'];
    timeZone = json['timeZone']?.toString();
    updateTime = int.tryParse(json['updateTime']?.toString() ?? '');
    uuid = json['uuid']?.toString();
    batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
    productName = json['productName']?.toString();
    deviceTags = json['deviceTag'] != null && json['deviceTag'] is List
        ? (json['deviceTag'] as List)
            .map((tag) => DeviceTagModel.fromJson(tag))
            .toList()
        : [];
    deviceSubSpace = json['subspace'] != null
        ? DeviceSubSpace.fromJson(json['subspace'])
        : DeviceSubSpace(subspaceName: '');
    if (json['spaces'] != null && json['spaces'] is List) {
      spaces = (json['spaces'] as List)
          .map((space) => DeviceSpaceModel.fromJson(space))
          .toList();
    }
  }

  String getDefaultIcon(String? productType) {
    /*
      AC
GD
3G
3G
GW
DL
WPS
CPS
AC
CPS
WPS
GW
AC
CUR
DS
1GT
2GT
3GT
1G
1G
2G
2G
DS
WH
1GT
2GT
3GT
GD
WL
WL
3G
CUR
GW
PC
PC
SOS

     */
    DeviceType type = devicesTypesMap[productType] ?? DeviceType.Other;
    String tempIcon = '';
    if (type == DeviceType.LightBulb) {
      tempIcon = Assets.lightBulb;
    } else if (type == DeviceType.CeilingSensor ||
        type == DeviceType.WallSensor) {
      tempIcon = Assets.sensors;
    } else if (type == DeviceType.AC) {
      tempIcon = Assets.ac;
    } else if (type == DeviceType.DoorLock) {
      tempIcon = Assets.doorLock;
    } else if (type == DeviceType.Curtain) {
      tempIcon = Assets.curtain;
    } else if (type == DeviceType.ThreeGang) {
      tempIcon = Assets.gangSwitch;
    } else if (type == DeviceType.Gateway) {
      tempIcon = Assets.gateway;
    } else if (type == DeviceType.OneGang) {
      tempIcon = Assets.oneGang;
    } else if (type == DeviceType.TwoGang) {
      tempIcon = Assets.twoGang;
    } else if (type == DeviceType.WH) {
      tempIcon = Assets.waterHeater;
    } else if (type == DeviceType.DS) {
      // tempIcon = Assets.mainDoor;
    } else if (type == DeviceType.OneTouch) {
      //  tempIcon = Assets.oneGang;
    } else if (type == DeviceType.TowTouch) {
      //  tempIcon = Assets.twoGang;
    } else if (type == DeviceType.GarageDoor) {
      //tempIcon = Assets.;
    } else if (type == DeviceType.ThreeTouch) {
      //  tempIcon = Assets.gang3touch;
    } else if (type == DeviceType.WaterLeak) {
      tempIcon = Assets.waterLeakNormal;
    } else if (type == DeviceType.NCPS) {
      tempIcon = Assets.sensors;
    } else if (type == DeviceType.PC) {
      tempIcon = Assets.powerClamp;
    } else {
      tempIcon = Assets.logoHorizontal;
    }
    return tempIcon;
  }

  List<DeviceFunction> get functions {
    return _getDeviceFunctions();
  }

  //! Functions for Devices Types
  List<DeviceFunction> _getDeviceFunctions() {
    switch (productType) {
      case 'AC':
        return [
          SwitchFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          ModeFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          TempSetFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          CurrentTempFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          LevelFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          ChildLockFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
        ];

      case '1G':
        return [
          OneGangSwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
          OneGangCountdownFunction(
              deviceId: uuid ?? '', deviceName: name ?? ''),
        ];

      case '2G':
        return [
          TwoGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
          TwoGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
          TwoGangCountdown1Function(
              deviceId: uuid ?? '', deviceName: name ?? ''),
          TwoGangCountdown2Function(
              deviceId: uuid ?? '', deviceName: name ?? ''),
        ];

      case '3G':
        return [
          ThreeGangSwitch1Function(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          ThreeGangSwitch2Function(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          ThreeGangSwitch3Function(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          ThreeGangCountdown1Function(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          ThreeGangCountdown2Function(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          ThreeGangCountdown3Function(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
        ];
      case 'WPS':
        return [
          //IF Functions
          PresenceStateFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          CurrentDistanceFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          IlluminanceValueFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          PresenceTimeFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),

          //THEN Functions
          FarDetectionFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          MotionSensitivityFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          MotionLessSensitivityFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          IndicatorFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          NoOneTimeFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
        ];
      case 'GW':
        return [
          GatewaySwitchAlarmSound(
            deviceId: uuid ?? '',
            deviceName: name ?? '',
            type: 'BOTH',
          ),
          GatewayMasterState(
            deviceId: uuid ?? '',
            deviceName: name ?? '',
            type: 'BOTH',
          ),
          GatewayFactoryReset(
            deviceId: uuid ?? '',
            deviceName: name ?? '',
            type: 'BOTH',
          ),
        ];
      case 'CPS':
        return CeilingSensorHelper.getCeilingSensorFunctions(
          uuid: uuid ?? '',
          name: name ?? '',
        );
      case 'CUR':
        return [
          ControlCurtainFunction(
            deviceId: uuid ?? '',
            deviceName: name ?? '',
            type: 'BOTH',
          )
        ];
      case 'NCPS':
        return [
          FlushPresenceDelayFunction(
            deviceId: uuid ?? '',
            deviceName: name ?? '',
            type: 'IF',
          ),

          FlushIlluminanceFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          //THEN Functions
          FlushSensitivityFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          FlushNearDetectionFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          FlushMaxDetectDistFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          FlushTargetConfirmTimeFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          FlushDisappeDelayFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          FlushIndentLevelFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
          FlushTriggerLevelFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
        ];
      case 'WH':
        return [
          WHRestartStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          WHSwitchFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          TimerConfirmTimeFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
          BacklightFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
        ];
      case 'PC':
        return [
          TotalEnergyConsumedStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          TotalActivePowerConsumedStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          VoltagePhaseSequenceDetectionFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          TotalCurrentStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          FrequencyStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),

          // Phase A
          EnergyConsumedAStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          ActivePowerAStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          VoltageAStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          PowerFactorAStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          CurrentAStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),

          // Phase B
          EnergyConsumedBStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          ActivePowerBStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          VoltageBStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          CurrentBStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          PowerFactorBStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),

          // Phase C
          EnergyConsumedCStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          ActivePowerCStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          VoltageCStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          CurrentCStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
          PowerFactorCStatusFunction(
              deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
        ];
      default:
        return [];
    }
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    if (room != null) {
      data['room'] = room!.toJson();
    }
    if (subspace != null) {
      data['subspace'] = subspace!.toJson();
    }
    if (unit != null) {
      data['unit'] = unit!.toJson();
    }
    if (community != null) {
      data['community'] = community!.toJson();
    }
    data['productUuid'] = productUuid;
    data['productType'] = productType;
    data['permissionType'] = permissionType;
    data['activeTime'] = activeTime;
    data['category'] = category;
    data['categoryName'] = categoryName;
    data['createTime'] = createTime;
    data['gatewayId'] = gatewayId;
    data['icon'] = icon;
    data['ip'] = ip;
    data['lat'] = lat;
    data['localKey'] = localKey;
    data['lon'] = lon;
    data['model'] = model;
    data['name'] = name;
    data['nodeId'] = nodeId;
    data['online'] = online;
    data['ownerId'] = ownerId;
    data['sub'] = sub;
    data['timeZone'] = timeZone;
    data['updateTime'] = updateTime;
    data['uuid'] = uuid;
    data['battery'] = batteryLevel;
    data['productName'] = productName;
    if (spaces != null) {
      data['spaces'] = spaces!.map((space) => space.toJson()).toList();
    }
    return data;
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is AllDevicesModel &&
        other.room == room &&
        other.subspace == subspace &&
        other.unit == unit &&
        other.productUuid == productUuid &&
        other.productType == productType &&
        other.permissionType == permissionType &&
        other.activeTime == activeTime &&
        other.category == category &&
        other.categoryName == categoryName &&
        other.createTime == createTime &&
        other.gatewayId == gatewayId &&
        other.icon == icon &&
        other.ip == ip &&
        other.lat == lat &&
        other.localKey == localKey &&
        other.lon == lon &&
        other.model == model &&
        other.name == name &&
        other.nodeId == nodeId &&
        other.online == online &&
        other.ownerId == ownerId &&
        other.sub == sub &&
        other.timeZone == timeZone &&
        other.updateTime == updateTime &&
        other.uuid == uuid &&
        other.productName == productName &&
        other.batteryLevel == batteryLevel;
  }

  @override
  int get hashCode {
    return room.hashCode ^
        subspace.hashCode ^
        unit.hashCode ^
        productUuid.hashCode ^
        productType.hashCode ^
        permissionType.hashCode ^
        activeTime.hashCode ^
        category.hashCode ^
        categoryName.hashCode ^
        createTime.hashCode ^
        gatewayId.hashCode ^
        icon.hashCode ^
        ip.hashCode ^
        lat.hashCode ^
        localKey.hashCode ^
        lon.hashCode ^
        model.hashCode ^
        name.hashCode ^
        nodeId.hashCode ^
        online.hashCode ^
        ownerId.hashCode ^
        sub.hashCode ^
        timeZone.hashCode ^
        updateTime.hashCode ^
        uuid.hashCode ^
        productName.hashCode ^
        batteryLevel.hashCode;
  }

  Map<String, DeviceType> devicesTypesMap = {
    "AC": DeviceType.AC,
    "GW": DeviceType.Gateway,
    "CPS": DeviceType.CeilingSensor,
    "DL": DeviceType.DoorLock,
    "WPS": DeviceType.WallSensor,
    "3G": DeviceType.ThreeGang,
    "2G": DeviceType.TwoGang,
    "1G": DeviceType.OneGang,
    "CUR": DeviceType.Curtain,
    "WH": DeviceType.WH,
    "DS": DeviceType.DS,
    "1GT": DeviceType.OneTouch,
    "2GT": DeviceType.TowTouch,
    "3GT": DeviceType.ThreeTouch,
    "GD": DeviceType.GarageDoor,
    "WL": DeviceType.WaterLeak,
    "NCPS": DeviceType.NCPS,
    "PC": DeviceType.PC,
  };

  AllDevicesModel copyWith({
    DevicesModelRoom? room,
    DeviceSubspace? subspace,
    DevicesModelUnit? unit,
    DeviceCommunityModel? community,
    String? productUuid,
    String? productType,
    String? permissionType,
    int? activeTime,
    String? category,
    String? categoryName,
    int? createTime,
    String? gatewayId,
    String? icon,
    String? ip,
    String? lat,
    String? localKey,
    String? lon,
    String? model,
    String? name,
    String? nodeId,
    bool? online,
    String? ownerId,
    bool? sub,
    String? timeZone,
    int? updateTime,
    String? uuid,
    int? batteryLevel,
    String? productName,
    List<DeviceSpaceModel>? spaces,
    List<DeviceTagModel>? deviceTags,
    DeviceSubSpace? deviceSubSpace,
  }) {
    return AllDevicesModel(
      room: room ?? this.room,
      subspace: subspace ?? this.subspace,
      unit: unit ?? this.unit,
      community: community ?? this.community,
      productUuid: productUuid ?? this.productUuid,
      productType: productType ?? this.productType,
      permissionType: permissionType ?? this.permissionType,
      activeTime: activeTime ?? this.activeTime,
      category: category ?? this.category,
      categoryName: categoryName ?? this.categoryName,
      createTime: createTime ?? this.createTime,
      gatewayId: gatewayId ?? this.gatewayId,
      icon: icon ?? this.icon,
      ip: ip ?? this.ip,
      lat: lat ?? this.lat,
      localKey: localKey ?? this.localKey,
      lon: lon ?? this.lon,
      model: model ?? this.model,
      name: name ?? this.name,
      nodeId: nodeId ?? this.nodeId,
      online: online ?? this.online,
      ownerId: ownerId ?? this.ownerId,
      sub: sub ?? this.sub,
      timeZone: timeZone ?? this.timeZone,
      updateTime: updateTime ?? this.updateTime,
      uuid: uuid ?? this.uuid,
      batteryLevel: batteryLevel ?? this.batteryLevel,
      productName: productName ?? this.productName,
      spaces: spaces ?? this.spaces,
      deviceTags: deviceTags ?? this.deviceTags,
      deviceSubSpace: deviceSubSpace ?? this.deviceSubSpace,
    );
  }
}
