from yoovo.shared.bypassed import _YoovoBypassedSensor
from yoovo.app import get_registry
import logging
import traceback

logger = logging.getLogger("yoovo.hardware")


def _safe_create(name, factory, *args, **kwargs):
    registry = get_registry()
    try:
        instance = factory(*args, **kwargs)
        registry.register(name, instance)
        return instance
    except Exception as e:
        instance = _YoovoBypassedSensor()
        registry.register(name, instance, bypassed_reason=str(e))
        error_msg = (
            f"\n{'='*60}\n"
            f"  HARDWARE ERROR: {name} failed to initialize\n"
            f"  Reason: {e}\n"
            f"  Check wiring and connections for {name}.\n"
            f"{'='*60}"
        )
        logger.error(error_msg)
        logger.debug(traceback.format_exc())
        print(error_msg)
        return instance


class LED:
    def __new__(cls, pin, frequency=1000, name=None):
        from yoovo.hardware.rpi.CompiledLedLight import CompiledLedLight
        return _safe_create(name or f"LED_pin{pin}", CompiledLedLight, pin, frequency)


class KnockSensor:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy031Sensor import CompiledKy031Sensor
        pull = pull or CompiledKy031Sensor.PUD_UP
        return _safe_create(name or f"KnockSensor_pin{pin}", CompiledKy031Sensor, pin, pull)


class GasSensor:
    def __new__(cls, digital_pin=None, digital_active_low=True, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledGasSensor import CompiledGasSensor
        return _safe_create(
            name or f"GasSensor_pin{digital_pin}",
            CompiledGasSensor, digital_pin=digital_pin, digital_active_low=digital_active_low, channel=channel
        )


class Button_Sensor:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy004Sensor import CompiledKy004Sensor
        pull = pull or CompiledKy004Sensor.PUD_UP
        return _safe_create(name or f"ButtonSensor_pin{pin}", CompiledKy004Sensor, pin, pull)


class PIR:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledPirSensor import CompiledPirSensor
        return _safe_create(name or f"PIR_pin{pin}", CompiledPirSensor, pin, pull)


class ServoMotor:
    def __new__(cls, mode="continuous", pin=None, name=None):
        from yoovo.hardware.rpi.CompiledServoMotor import CompiledServoMotor
        return _safe_create(name or f"Servo_pin{pin}", CompiledServoMotor, mode, pin)


class StepperMotor:
    def __new__(cls, dir_pin=None, step_pin=None, name=None):
        from yoovo.hardware.rpi.CompiledStepperMotor import CompiledStepperMotor
        return _safe_create(name or "StepperMotor", CompiledStepperMotor, dir_pin=dir_pin, step_pin=step_pin)


class LCD:
    def __new__(cls, address=0x27, cols=16, rows=2, name=None):
        from yoovo.hardware.rpi.CompiledLCD import CompiledLCD
        return _safe_create(name or "LCD", CompiledLCD, address, rows, cols)


class Buzzer:
    def __new__(cls, pin=None, buzzer_type="ACTIVE", active_high=True, name=None):
        from yoovo.hardware.rpi.CompiledBuzzerSensor import CompiledBuzzerSensor
        return _safe_create(name or f"Buzzer_pin{pin}", CompiledBuzzerSensor, pin=pin, buzzer_type=buzzer_type, active_high=active_high)


class RgbLed:
    def __new__(cls, red_pin=None, green_pin=None, blue_pin=None, name=None):
        from yoovo.hardware.rpi.CompiledRgbLed import CompiledRgbLed
        return _safe_create(name or "RgbLed", CompiledRgbLed, red_pin, green_pin, blue_pin)


class TemperatureSensor:
    def __new__(cls, pin=None, name=None):
        from yoovo.hardware.rpi.CompiledKy001Sensor import CompiledKy001Sensor
        return _safe_create(name or "TempSensor", CompiledKy001Sensor)


class VibrationSensor:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy002Sensor import CompiledKy002Sensor
        return _safe_create(name or f"VibrationSensor_pin{pin}", CompiledKy002Sensor, pin, pull)


class HallSensor:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy003Sensor import CompiledKy003Sensor
        return _safe_create(name or f"HallSensor_pin{pin}", CompiledKy003Sensor, pin, pull)


class LightBarrier:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy010Sensor import CompiledKy010Sensor
        return _safe_create(name or f"LightBarrier_pin{pin}", CompiledKy010Sensor, pin, pull)


class NtcSensor:
    def __new__(cls, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy013Sensor import CompiledKy013Sensor
        return _safe_create(name or f"NtcSensor_ch{channel}", CompiledKy013Sensor, channel=channel)


class TempHumiditySensor:
    def __new__(cls, sensor_type="DHT11", pin=None, name=None):
        from yoovo.hardware.rpi.CompiledKy015Sensor import CompiledKy015Sensor
        return _safe_create(name or f"TempHumidity_pin{pin}", CompiledKy015Sensor, sensor_type, pin)


class TiltSwitch:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy017Sensor import CompiledKy017Sensor
        return _safe_create(name or f"TiltSwitch_pin{pin}", CompiledKy017Sensor, pin, pull)


class Photoresistor:
    def __new__(cls, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy018Sensor import CompiledKy018Sensor
        return _safe_create(name or f"Photoresistor_ch{channel}", CompiledKy018Sensor, channel)


class Relay:
    def __new__(cls, pin, active_high=True, name=None):
        from yoovo.hardware.rpi.CompiledKy019Sensor import CompiledKy019Sensor
        return _safe_create(name or f"Relay_pin{pin}", CompiledKy019Sensor, pin, active_high)


class ReedSwitch:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy021Sensor import CompiledKy021Sensor
        return _safe_create(name or f"ReedSwitch_pin{pin}", CompiledKy021Sensor, pin, pull)


class Joystick:
    def __new__(cls, x_channel=0, y_channel=1, button_pin=None, name=None):
        from yoovo.hardware.rpi.CompiledKy023Sensor import CompiledKy023Sensor
        return _safe_create(name or "Joystick", CompiledKy023Sensor, x_channel, y_channel, button_pin)


class HallEffectSensor:
    def __new__(cls, digital_pin=None, digital_active_low=True, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy024Sensor import CompiledKy024Sensor
        return _safe_create(name or f"HallEffect_pin{digital_pin}", CompiledKy024Sensor, digital_pin=digital_pin, digital_active_low=digital_active_low, channel=channel)


class ReedSensor:
    def __new__(cls, digital_pin=None, digital_active_low=True, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy025Sensor import CompiledKy025Sensor
        return _safe_create(name or f"ReedSensor_pin{digital_pin}", CompiledKy025Sensor, digital_pin=digital_pin, digital_active_low=digital_active_low, channel=channel)


class FlameSensor:
    def __new__(cls, digital_pin=None, digital_active_low=True, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy026Sensor import CompiledKy026Sensor
        return _safe_create(name or f"FlameSensor_pin{digital_pin}", CompiledKy026Sensor, digital_pin=digital_pin, digital_active_low=digital_active_low, channel=channel)


class ThermistorSensor:
    def __new__(cls, digital_pin=None, digital_active_low=True, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy028Sensor import CompiledKy028Sensor
        return _safe_create(name or f"Thermistor_pin{digital_pin}", CompiledKy028Sensor, digital_pin=digital_pin, digital_active_low=digital_active_low, channel=channel)


class TwoColorLed:
    def __new__(cls, red_pin=None, green_pin=None, name=None):
        from yoovo.hardware.rpi.CompiledKy029Sensor import CompiledKy029Sensor
        return _safe_create(name or "TwoColorLed", CompiledKy029Sensor, red_pin, green_pin)


class ObstacleDetector:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy032Sensor import CompiledKy032Sensor
        return _safe_create(name or f"ObstacleDetector_pin{pin}", CompiledKy032Sensor, pin, pull)


class LineTracker:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy033Sensor import CompiledKy033Sensor
        return _safe_create(name or f"LineTracker_pin{pin}", CompiledKy033Sensor, pin, pull)


class FlashLed:
    def __new__(cls, pin, name=None):
        from yoovo.hardware.rpi.CompiledKy034Sensor import CompiledKy034Sensor
        return _safe_create(name or f"FlashLed_pin{pin}", CompiledKy034Sensor, pin)


class MagneticSensor:
    def __new__(cls, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy035Sensor import CompiledKy035Sensor
        return _safe_create(name or f"MagneticSensor_ch{channel}", CompiledKy035Sensor, channel=channel)


class TouchSensor:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, digital_pin=None, channel=0, pull_up_down=None, name=None):
        from yoovo.hardware.rpi.CompiledKy036Sensor import CompiledKy036Sensor
        return _safe_create(name or f"TouchSensor_pin{digital_pin}", CompiledKy036Sensor, digital_pin=digital_pin, channel=channel, pull_up_down=pull_up_down)


class Microphone:
    def __new__(cls, digital_pin=None, digital_active_low=True, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy037Sensor import CompiledKy037Sensor
        return _safe_create(name or f"Microphone_pin{digital_pin}", CompiledKy037Sensor, digital_pin=digital_pin, digital_active_low=digital_active_low, channel=channel)


class HeartbeatSensor:
    def __new__(cls, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledKy039Sensor import CompiledKy039Sensor
        return _safe_create(name or f"Heartbeat_ch{channel}", CompiledKy039Sensor, channel)


class RotaryEncoder:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin_clk, pin_dt, pin_sw=None, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledKy040Sensor import CompiledKy040Sensor
        return _safe_create(name or "RotaryEncoder", CompiledKy040Sensor, pin_clk, pin_dt, pin_sw, pull)


class UltrasonicSensor:
    def __new__(cls, trigger_pin, echo_pin, name=None):
        from yoovo.hardware.rpi.CompiledKy050Sensor import CompiledKy050Sensor
        return _safe_create(name or "Ultrasonic", CompiledKy050Sensor, trigger_pin, echo_pin)


class MotionSensor:
    def __new__(cls, name=None):
        from yoovo.hardware.rpi.CompiledMpuSensor import CompiledMpuSensor
        return _safe_create(name or "MotionSensor", CompiledMpuSensor)


class SoilMoisture:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin=None, pull=None, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledSoilMoistureSensor import CompiledSoilMoistureSensor
        return _safe_create(name or f"SoilMoisture_ch{channel}", CompiledSoilMoistureSensor, pin, pull, channel)


class Thermocouple:
    def __new__(cls, pin=None, name=None):
        from yoovo.hardware.rpi.CompiledThermocoupleSensor import CompiledThermocoupleSensor
        return _safe_create(name or "Thermocouple", CompiledThermocoupleSensor, pin)


class WaterLevel:
    def __new__(cls, pin=None, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledWaterLevelSensor import CompiledWaterLevelSensor
        return _safe_create(name or f"WaterLevel_ch{channel}", CompiledWaterLevelSensor, pin, channel)


class LedMatrix:
    def __new__(cls, interface='spi', name=None, **kwargs):
        from yoovo.hardware.rpi.CompiledLedMatrix import CompiledLedMatrix
        return _safe_create(name or "LedMatrix", CompiledLedMatrix, interface=interface, **kwargs)


class PwmOutput:
    def __new__(cls, pin, frequency=1000, name=None):
        from yoovo.hardware.rpi.CompiledPwmOutput import CompiledPwmOutput
        return _safe_create(name or f"PwmOutput_pin{pin}", CompiledPwmOutput, pin, frequency)


class Timer:
    def __new__(cls, interval=1000, is_loop=True, callback=None, name=None):
        from yoovo.hardware.rpi.CompiledTimer import CompiledTimer
        return _safe_create(name or "Timer", CompiledTimer, interval, is_loop, callback)


class AnalogDigitalInput:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, channel=0, name=None):
        from yoovo.hardware.rpi.CompiledAnalogDigitalInput import CompiledAnalogDigitalInput
        return _safe_create(name or f"AnalogDigitalInput_pin{pin}", CompiledAnalogDigitalInput, pin, pull, channel)


class DigitalInput:
    PUD_UP = "PUD_UP"
    PUD_DOWN = "PUD_DOWN"
    PUD_OFF = "PUD_OFF"

    def __new__(cls, pin, pull=None, name=None):
        from yoovo.hardware.rpi.CompiledDigitalInput import CompiledDigitalInput
        return _safe_create(name or f"DigitalInput_pin{pin}", CompiledDigitalInput, pin, pull)


class AnalogInput:
    def __new__(cls, channel, name=None):
        from yoovo.hardware.rpi.CompiledAnalogInput import CompiledAnalogInput
        return _safe_create(name or f"AnalogInput_ch{channel}", CompiledAnalogInput, channel)
