package controller

import (
	"fmt"
	"log"

	"led-controller/config"
	"led-controller/controller/openrgb"
	"led-controller/controller/relay"
)

type Controller struct {
	cfg   *config.Config
	orgb  *openrgb.Client
	relay *relay.Relay
}

func New(cfg *config.Config) (*Controller, error) {
	c := &Controller{cfg: cfg}

	if cfg.OpenRGB.Enabled {
		client, err := openrgb.Connect(cfg.OpenRGB.Host, cfg.OpenRGB.Port)
		if err != nil {
			log.Printf("warning: openrgb unavailable: %v", err)
		} else {
			c.orgb = client
			log.Println("openrgb: connected via CLI")
		}
	}

	if cfg.Relay.Enabled {
		c.relay = relay.New(cfg.Relay.Device, cfg.Relay.Channel, cfg.Relay.Baud)
		log.Printf("relay: configured on %s channel %d", cfg.Relay.Device, cfg.Relay.Channel)
	}

	return c, nil
}

func (c *Controller) SetLEDs(on bool) error {
	var errs []error

	if c.cfg.OpenRGB.Enabled {
		if err := c.setOpenRGB(on); err != nil {
			errs = append(errs, fmt.Errorf("openrgb: %w", err))
		}
	}

	if c.cfg.Relay.Enabled && c.relay != nil {
		if err := c.relay.Set(on); err != nil {
			errs = append(errs, fmt.Errorf("relay: %w", err))
		}
	}

	if len(errs) > 0 {
		return fmt.Errorf("%v", errs)
	}
	return nil
}

func (c *Controller) setOpenRGB(on bool) error {
	if c.orgb == nil {
		client, err := openrgb.Connect(c.cfg.OpenRGB.Host, c.cfg.OpenRGB.Port)
		if err != nil {
			return err
		}
		c.orgb = client
	}

	if on {
		return c.orgb.SetAllOn(0xFF, 0xFF, 0xFF)
	}
	return c.orgb.SetAllOff()
}

func (c *Controller) Close() {
	if c.orgb != nil {
		c.orgb.Close()
	}
	if c.relay != nil {
		c.relay.Close()
	}
}
