import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import display, spi, time
from esphome.const import CONF_ID, CONF_SPI_ID

DEPENDENCIES = ["spi", "time"]

nixie_display_ns = cg.esphome_ns.namespace("nixie_display")
NixieDisplay = nixie_display_ns.class_(
    "NixieDisplay", display.DisplayBuffer, spi.SPIDevice
)

CONF_ANODE0_PIN = "anode0_pin"
CONF_ANODE1_PIN = "anode1_pin"
CONF_ANODE2_PIN = "anode2_pin"
CONF_LE_PIN = "le_pin"
CONF_REFRESH_INTERVAL_US = "refresh_interval_us"
CONF_TIME_ID = "time_id"
CONF_DEBUG_LOGGING = "debug_logging"
CONF_ANTI_POISONING = "anti_poisoning"
CONF_LAMBDA_HOLD_MS = "lambda_hold_ms"
CONF_AUTO_TIME = "auto_time"

CONFIG_SCHEMA = display.FULL_DISPLAY_SCHEMA.extend(
    {
        cv.GenerateID(): cv.declare_id(NixieDisplay),
        cv.Required(CONF_SPI_ID): cv.use_id(spi.SPIComponent),
        cv.Required(CONF_ANODE0_PIN): pins.gpio_output_pin_schema,
        cv.Required(CONF_ANODE1_PIN): pins.gpio_output_pin_schema,
        cv.Required(CONF_ANODE2_PIN): pins.gpio_output_pin_schema,
        cv.Required(CONF_LE_PIN): pins.gpio_output_pin_schema,
        cv.Optional(CONF_REFRESH_INTERVAL_US, default=1000): cv.int_range(
            min=200, max=20000
        ),
        cv.Optional(CONF_TIME_ID): cv.use_id(time.RealTimeClock),
        cv.Optional(CONF_DEBUG_LOGGING, default=False): cv.boolean,
        cv.Optional(CONF_ANTI_POISONING, default=True): cv.boolean,
        cv.Optional(CONF_LAMBDA_HOLD_MS, default=1500): cv.int_range(min=0, max=60000),
        cv.Optional(CONF_AUTO_TIME, default=True): cv.boolean,
    }
)


async def to_code(config):
    var = cg.new_Pvariable(config[CONF_ID])
    await display.register_display(var, config)
    await spi.register_spi_device(var, config)

    anode0 = await cg.gpio_pin_expression(config[CONF_ANODE0_PIN])
    anode1 = await cg.gpio_pin_expression(config[CONF_ANODE1_PIN])
    anode2 = await cg.gpio_pin_expression(config[CONF_ANODE2_PIN])
    le_pin = await cg.gpio_pin_expression(config[CONF_LE_PIN])

    cg.add(var.set_anode_pins(anode0, anode1, anode2, le_pin))
    cg.add(var.set_refresh_interval_us(config[CONF_REFRESH_INTERVAL_US]))
    cg.add(var.set_debug_logging(config[CONF_DEBUG_LOGGING]))
    cg.add(var.set_anti_poisoning(config[CONF_ANTI_POISONING]))
    cg.add(var.set_lambda_hold_ms(config[CONF_LAMBDA_HOLD_MS]))
    cg.add(var.set_auto_time(config[CONF_AUTO_TIME]))
    if CONF_TIME_ID in config:
        time_var = await cg.get_variable(config[CONF_TIME_ID])
        cg.add(var.set_time_source(time_var))
