import logging
import os
import random
from PIL import Image, ImageFont

logger = logging.getLogger(__name__)

class EOJHLSponsorsManager:
    def __init__(self, config, display_manager):
        self.config = config.get("sponsors", {})
        self.display_manager = display_manager
        self.logger = logging.getLogger("EOJHLSponsorsManager")
        self.sponsors = self._load_sponsors()
        self.index = 0
        
        # New settings for batch display
        self.show_all = self.config.get("show_all", False)
        self.show_num_sponsors = self.config.get("show_num_sponsors", 1)

    def _load_sponsors(self):
        sponsors = []
        for key in self.config.get("enabled_sponsors", []):
            sponsor_cfg = self.config.get(key, {})
            if sponsor_cfg.get("enabled", True):
                sponsors.append({
                    "key": key,
                    "image": f"assets/sponsors/{sponsor_cfg.get('pngabbr')}.png",
                    "details_row1": sponsor_cfg.get("details_row1", key),
                    "details_row2": sponsor_cfg.get("details_row2", "")
                })
        return sponsors

    def get_next_sponsors(self):
        """
        Return a list of sponsors to display based on show_all and show_num_sponsors settings.
        Advances the index appropriately.
        """
        if not self.sponsors:
            return []
        
        if self.show_all:
            # Show all sponsors, don't advance index
            return self.sponsors
        else:
            # Show a batch of sponsors based on show_num_sponsors
            num_to_show = min(self.show_num_sponsors, len(self.sponsors))
            sponsors_to_show = []
            
            for i in range(num_to_show):
                current_index = (self.index + i) % len(self.sponsors)
                sponsors_to_show.append(self.sponsors[current_index])
            
            # Advance index by the number shown
            self.index = (self.index + num_to_show) % len(self.sponsors)
            
            return sponsors_to_show

    def get_next_sponsor(self):
        """
        Legacy method for backward compatibility.
        Return next sponsor sequentially and advance index.
        """
        if not self.sponsors:
            return None
        sponsor = self.sponsors[self.index]
        self.index = (self.index + 1) % len(self.sponsors)
        return sponsor

    # --- Slide Renderers ---

    def render_title(self, title_row1=None, title_row2=None):
        dm = self.display_manager
        dm.clear()

        # Resolve text from arguments or global config
        row1_text = title_row1 or self.config.get("title_row1", "Thank You to")
        row2_text = title_row2 or self.config.get("title_row2", "Our Sponsor")

        # Resolve font sizes and colours from global config
        row1_size = self.config.get("title_row1_font_size", 10)
        row2_size = self.config.get("title_row2_font_size", 10)
        row1_colour = self.config.get("title_row1_colour", "yellow")
        row2_colour = self.config.get("title_row2_colour", "yellow")

        try:
            font_row1 = ImageFont.truetype("assets/fonts/PressStart2P-Regular.ttf", row1_size)
            font_row2 = ImageFont.truetype("assets/fonts/PressStart2P-Regular.ttf", row2_size)
        except Exception as e:
            self.logger.warning(f"[Sponsors] Title font load failed: {e}")
            font_row1, font_row2 = dm.regular_font, dm.small_font

        # Build lines
        lines = []
        if row1_text:
            lines.append((row1_text, font_row1, row1_colour))
        if row2_text:
            lines.append((row2_text, font_row2, row2_colour))

        # Vertical centering
        total_h = 0
        heights = []
        for text, font, _ in lines:
            bbox = dm.draw.textbbox((0, 0), text, font=font)
            h = bbox[3] - bbox[1]
            heights.append(h)
            total_h += h
        total_h += (len(lines) - 1) * 2  # spacing between rows
        y = (dm.height - total_h) // 2

        # Draw each line centered
        for (text, font, color), h in zip(lines, heights):
            bbox = dm.draw.textbbox((0, 0), text, font=font)
            w = bbox[2] - bbox[0]
            x = (dm.width - w) // 2
            dm.draw.text((x, y), text, font=font, fill=color)
            y += h + 2

        dm.update_display()

        # Return configured duration for sequencing
        return self.config.get("title_duration", 5)

    def render_logo(self, sponsor):
        dm = self.display_manager
        dm.clear()
        logo_path = sponsor["image"]

        if os.path.exists(logo_path):
            logo = Image.open(logo_path).convert("RGBA")

            # Scale proportionally so the logo fills the full matrix height
            scale = dm.height / logo.height
            new_w = int(logo.width * scale)
            new_h = dm.height
            logo = logo.resize((new_w, new_h), Image.Resampling.LANCZOS)

            # Center horizontally and vertically
            offset_x = (dm.width - new_w) // 2
            offset_y = (dm.height - new_h) // 2
            
            # Paste logo directly onto dm.image with alpha mask
            dm.image.paste(logo, (offset_x, offset_y), logo)
        else:
            self.logger.warning(f"[Sponsors] Logo not found: {logo_path}")

        dm.update_display()

    def render_details(self, sponsor):
        dm = self.display_manager
        dm.clear()

        # Look up the sponsor-specific config (if any)
        sponsor_cfg = self.config.get(sponsor["key"], {})
        
        # Global default (sponsors.show_details) can be overridden per sponsor
        global_show = self.config.get("show_details", True)
        sponsor_show = sponsor_cfg.get("show_details", global_show)

        if not sponsor_show:
            self.logger.info(f"[Sponsors] Skipping details for {sponsor['key']} (show_details=false)")
            return 0

        # Resolve font sizes and colours with per-sponsor override → global default → hardcoded fallback
        details_row1_font_size = sponsor_cfg.get("details_row1_font_size",
                            self.config.get("details_row1_font_size", 10))
        details_row2_font_size = sponsor_cfg.get("details_row2_font_size",
                            self.config.get("details_row2_font_size", 8))
        details_row1_colour = sponsor_cfg.get("details_row1_colour",
                            self.config.get("details_row1_colour", "white"))
        details_row2_colour = sponsor_cfg.get("details_row2_colour",
                            self.config.get("details_row2_colour", "blue"))

        try:
            font_details_row1 = ImageFont.truetype(
                "assets/fonts/PressStart2P-Regular.ttf", details_row1_font_size
            )
            font_details_row2 = ImageFont.truetype(
                "assets/fonts/PressStart2P-Regular.ttf", details_row2_font_size
            )
        except Exception as e:
            self.logger.warning(f"[Sponsors] Detail font load failed: {e}")
            font_details_row1, font_details_row2 = dm.regular_font, dm.small_font

        # Build lines with resolved colours
        lines = []
        if sponsor.get("details_row1"):
            lines.append((sponsor["details_row1"], font_details_row1, details_row1_colour))
        if sponsor.get("details_row2") and sponsor["details_row2"].upper() != "NONE":
            lines.append((sponsor["details_row2"], font_details_row2, details_row2_colour))

        # Vertical centering
        total_h = 0
        heights = []
        for text, font, _ in lines:
            bbox = dm.draw.textbbox((0, 0), text, font=font)
            h = bbox[3] - bbox[1]
            heights.append(h)
            total_h += h
        total_h += (len(lines) - 1) * 2
        y = (dm.height - total_h) // 2

        for (text, font, color), h in zip(lines, heights):
            bbox = dm.draw.textbbox((0, 0), text, font=font)
            w = bbox[2] - bbox[0]
            x = (dm.width - w) // 2
            dm.draw.text((x, y), text, font=font, fill=color)
            y += h + 2

        dm.update_display()

        # Return the configured duration if we actually rendered
        return self.config.get("details_duration", 5)