import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_model.dart';
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
import 'package:syncrow_web/pages/routines/models/wps/wps_operational_value.dart';
import 'package:syncrow_web/utils/constants/assets.dart';

abstract class WpsFunctions extends DeviceFunction<WallSensorModel> {
  final String type;

  WpsFunctions({
    required super.deviceId,
    required super.deviceName,
    required super.code,
    required super.operationName,
    required super.icon,
    required this.type,
    super.step,
    super.unit,
    super.max,
    super.min,
  });

  List<WpsOperationalValue> getOperationalValues();
}

// For far_detection (75-600cm in 75cm steps)
class FarDetectionFunction extends WpsFunctions {
  
  final double min;
    @override
  final double max;
    @override
  final double step;
  @override
  final String unit;

  FarDetectionFunction(
      {required super.deviceId, required super.deviceName, required type})
      : min = 75,
        max = 600,
        step = 75,
        unit = 'cm',
        super(
          type: type,
          code: 'far_detection',
          operationName: 'Far Detection',
          icon: Assets.farDetectionIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() {
    final values = <WpsOperationalValue>[];
    for (var value = min; value <= max; value += step.toInt()) {
      values.add(WpsOperationalValue(
        icon: Assets.currentDistanceIcon,
        description: '$value $unit',
        value: value,
      ));
    }
    return values;
  }
}

// For presence_time (0-65535 minutes)
class PresenceTimeFunction extends WpsFunctions {
  final double min;
  final double max;
  final double step;
  final String unit;

  PresenceTimeFunction(
      {required super.deviceId, required super.deviceName, required type})
      : min = 0,
        max = 65535,
        step = 1,
        unit = 'Min',
        super(
          type: type,
          code: 'presence_time',
          operationName: 'Presence Time',
          icon: Assets.presenceTimeIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() {
    return [
      WpsOperationalValue(
        icon: icon,
        description: 'Custom $unit',
        value: null,
      )
    ];
  }
}

// For motion_sensitivity_value (1-5 levels)
class MotionSensitivityFunction extends WpsFunctions {
  final double min;
  final double max;
  final double step;

  MotionSensitivityFunction(
      {required super.deviceId, required super.deviceName, required type})
      : min = 1,
        max = 5,
        step = 1,
        super(
          type: type,
          code: 'motion_sensitivity_value',
          operationName: 'Motion Detection Sensitivity',
          icon: Assets.motionDetectionSensitivityIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() {
    return List.generate(
      (max - min) ~/ step + 1,
      (index) => WpsOperationalValue(
        icon: Assets.motionDetectionSensitivityValueIcon,
        description: '${min + (index * step)}',
        value: min + (index * step),
      ),
    );
  }
}

class MotionLessSensitivityFunction extends WpsFunctions {
  final double min;
  final double max;
  final double step;

  MotionLessSensitivityFunction(
      {required super.deviceId, required super.deviceName, required type})
      : min = 1,
        max = 5,
        step = 1,
        super(
          type: type,
          code: 'motionless_sensitivity',
          operationName: 'Motionless Detection Sensitivity',
          icon: Assets.motionlessDetectionSensitivityIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() {
    return List.generate(
      (max - min) ~/ step + 1,
      (index) => WpsOperationalValue(
        icon: Assets.currentDistanceIcon,
        description: '${min + (index * step)}',
        value: min + (index * step),
      ),
    );
  }
}

class IndicatorFunction extends WpsFunctions {
  IndicatorFunction(
      {required super.deviceId, required super.deviceName, required type})
      : super(
          type: type,
          code: 'indicator',
          operationName: 'Indicator',
          icon: Assets.IndicatorIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() => [
        WpsOperationalValue(
          icon: Assets.assetsAcPower,
          description: "ON",
          value: true,
        ),
        WpsOperationalValue(
          icon: Assets.assetsAcPowerOFF,
          description: "OFF",
          value: false,
        ),
      ];
}

class NoOneTimeFunction extends WpsFunctions {
  final double min;
  final double max;
  final String unit;

  NoOneTimeFunction(
      {required super.deviceId, required super.deviceName, required type})
      : min = 10,
        max = 10000,
        unit = '秒',
        super(
          type: type,
          code: 'no_one_time',
          operationName: 'Nobody Time',
          icon: Assets.nobodyTime,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() {
    return [
      WpsOperationalValue(
        icon: icon,
        description: 'Custom $unit',
        value: null,
      )
    ];
  }
}

class PresenceStateFunction extends WpsFunctions {
  PresenceStateFunction(
      {required super.deviceId, required super.deviceName, required type})
      : super(
          type: type,
          code: 'presence_state',
          operationName: 'Presence State',
          icon: Assets.presenceStateIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() => [
        WpsOperationalValue(
          icon: Assets.assetsAcPower,
          description: "None",
          value: 'none',
        ),
        WpsOperationalValue(
          icon: Assets.presenceStateIcon,
          description: "Presence",
          value: 'presence',
        ),
      ];
}

class CurrentDistanceFunction extends WpsFunctions {
  final double min;
  final double max;
  final double step;

  CurrentDistanceFunction(
      {required super.deviceId, required super.deviceName, required type})
      : min = 1,
        max = 600,
        step = 1,
        super(
          type: type,
          code: 'dis_current',
          operationName: 'Current Distance',
          icon: Assets.currentDistanceIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() {
    List<WpsOperationalValue> values = [];
    for (int cm = min.toInt(); cm <= max; cm += step.toInt()) {
      values.add(WpsOperationalValue(
        icon: Assets.assetsTempreture,
        description: "${cm}CM",
        value: cm,
      ));
    }
    return values;
  }
}

class IlluminanceValueFunction extends WpsFunctions {
  final double min;
  final double max;
  final double step;

  IlluminanceValueFunction({
    required super.deviceId,
    required super.deviceName,
    required super.type,
  })  : min = 0,
        max = 10000,
        step = 10,
        super(
          code: 'illuminance_value',
          operationName: 'Illuminance Value',
          icon: Assets.IlluminanceIcon,
        );

  @override
  List<WpsOperationalValue> getOperationalValues() {
    List<WpsOperationalValue> values = [];
    for (int lux = min.toInt(); lux <= max; lux += step.toInt()) {
      values.add(WpsOperationalValue(
        icon: Assets.IlluminanceIcon,
        description: "$lux Lux",
        value: lux,
      ));
    }
    return values;
  }
}
