import time
from smbus2 import SMBus

I2C_ADDR = 0x27  # Change if your LCD uses a different address
LCD_BACKLIGHT = 0x08
LCD_ENABLE = 0x04
LCD_RS = 0x01
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0

class LCDService:
    def __init__(self):
        self.bus = SMBus(1)

    def strobe(self, data):
        self.bus.write_byte(I2C_ADDR, data | LCD_ENABLE | LCD_BACKLIGHT)
        time.sleep(0.0005)
        self.bus.write_byte(I2C_ADDR, (data & ~LCD_ENABLE) | LCD_BACKLIGHT)
        time.sleep(0.0001)

    def write_byte(self, bits, mode):
        high = bits & 0xF0
        low = (bits << 4) & 0xF0

        self.bus.write_byte(I2C_ADDR, high | mode | LCD_BACKLIGHT)
        self.strobe(high | mode)

        self.bus.write_byte(I2C_ADDR, low | mode | LCD_BACKLIGHT)
        self.strobe(low | mode)

    def lcd_init(self):
        time.sleep(0.05)  # Wait for LCD to power up

        # Initialization sequence (as per HD44780 datasheet)
        self.write_byte(0x33, 0)  # Initialize
        self.write_byte(0x32, 0)  # Set to 4-bit mode
        self.write_byte(0x28, 0)  # 2 line, 5x8 font
        self.write_byte(0x0C, 0)  # Display on, cursor off, blink off
        self.write_byte(0x06, 0)  # Entry mode set
        self.write_byte(0x01, 0)  # Clear display
        time.sleep(0.002)

    def send_message(self, message: str, line_addr):
        self.write_byte(line_addr, 0)
        for char in message.ljust(16):
            self.write_byte(ord(char), LCD_RS)

    def clear(self):
        self.write_byte(0x01, False)
        time.sleep(0.002)

    def close(self):
        self.bus.close()
