import os
import pygame
from client.resource_path import get_asset_path, get_resource_path
from client.data import config

class SettingsMenu:
    def __init__(self, screen, audio):
        self.screen = screen

        # Default audio levels
        self.music_volume = 100  # percent
        self.sound_volume = 100  # percent
        self.audio = audio
        self.music_volume = int(config.Music_Volume * 100)  # convert 0.0-1.0 to 0-100
        self.sound_volume = int(config.Sound_Volume * 100)  # convert 0.0-1.0 to 0-100
        self.music_bar_rect = None
        self.sound_bar_rect = None
        self.dragging_music = False
        self.dragging_sound = False


        # Load background (keep original for scaling)
        self.bg_img_orig = pygame.image.load(get_asset_path("images/ui/settings_bg.png")).convert()
        self.bg_img = pygame.transform.scale(self.bg_img_orig, (config.SCREEN_WIDTH, config.SCREEN_HEIGHT))

        # Font proportional to screen height
        font_path = get_asset_path("fonts/cinzel.decorative-black.ttf")
        self.font = pygame.font.Font(font_path, max(20, int(config.SCREEN_HEIGHT * 0.04)))

        # Main options
        self.options = ["Screen Mode", "Resolution", "Music", "Sound", "Return to Title", "Apply Changes"]
        self.selected_index = 0

        # Resolution choices
        self.resolutions = [(800, 600), (1024, 768), (1280, 720), (1920, 1080), (2560, 1440)]
        self.current_resolution_index = next(
            (i for i, r in enumerate(self.resolutions) if r == (config.SCREEN_WIDTH, config.SCREEN_HEIGHT)), 0
        )

        # Screen Mode choices
        self.screen_mode = ["Window", "Full Screen"]
        self.current_screen_mode_index = next(
            (i for i, r in enumerate(self.screen_mode) if r == config.SCREEN_MODE), 0
        )

        # Store rectangles for mouse interaction
        self.last_mouse_pos = pygame.mouse.get_pos() # Track last mouse pos
        self.option_rects = []

    def center_window(self, width, height):
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.display.set_mode((width, height))

    def draw(self):
        # Scale background dynamically
        self.bg_img = pygame.transform.scale(self.bg_img_orig, (config.SCREEN_WIDTH, config.SCREEN_HEIGHT))
        self.screen.blit(self.bg_img, (0, 0))

        # Compute vertical spacing dynamically
        center_x = config.SCREEN_WIDTH // 2
        spacing = max(50, int(config.SCREEN_HEIGHT * 0.07))
        start_y = int(config.SCREEN_HEIGHT * 0.3)
        menu_height = len(self.options) * spacing

        # --- Boxed semi-transparent panel ---
        panel_width = int(config.SCREEN_WIDTH * 0.6)
        panel_height = menu_height + 120                # Add padding top/bottom
        overlay = pygame.Surface((panel_width, panel_height), pygame.SRCALPHA)
        pygame.draw.rect(
            overlay,
            (0, 0, 0, 100),           # semi-transparent black
            overlay.get_rect(),
            border_radius=20           # <-- roundness (pixels)
        )

        # Center the panel behind the menu block
        menu_center_y = start_y + (menu_height - spacing) // 2
        overlay_rect = overlay.get_rect(center=(center_x, menu_center_y))
        self.screen.blit(overlay, overlay_rect)

        self.option_rects = []

        font_path = get_asset_path("fonts/cinzel.decorative-black.ttf")

        for i, option in enumerate(self.options):
            # Highlight selected option
            color = (50, 150, 255) if i == self.selected_index else (255, 255, 255)
            text_surface = self.font.render(option, True, color)

            # Compute y position
            extra_spacing = 0
            if option == "Apply Changes":
                extra_spacing = 30

            y_pos = start_y + i * spacing + extra_spacing
            
            margin_x = int(config.SCREEN_WIDTH * 0.25)
            panel_right_x = int(config.SCREEN_WIDTH * 0.78)
            rect = text_surface.get_rect(midleft=(margin_x, y_pos))
            self.screen.blit(text_surface, rect)
            self.option_rects.append((option, rect))

            # Draw current resolution next to "Resolution"
            if option == "Resolution":
                res_text = f"{self.resolutions[self.current_resolution_index][0]}x{self.resolutions[self.current_resolution_index][1]}"
                res_surface = self.font.render(res_text, True, (200, 200, 0))
                res_rect = res_surface.get_rect(midright=(panel_right_x, rect.centery))
                self.screen.blit(res_surface, res_rect)

            if option == "Music":
                bar_width = int(config.SCREEN_WIDTH * 0.20)   # 20% of the screen width
                bar_height = max(18, int(config.SCREEN_HEIGHT * 0.025))   # 2.5% of screen height, minimum 18px
                bar_x = int(config.SCREEN_WIDTH * 0.52)
                bar_y = rect.centery

                # Draw bar background
                pygame.draw.rect(self.screen, (80, 80, 80), (bar_x, bar_y, bar_width, bar_height), border_radius=bar_height//2)
                # Draw filled part based on volume
                filled_width = int(bar_width * self.music_volume / 100)
                pygame.draw.rect(self.screen, (50, 150, 255), (bar_x, bar_y, filled_width, bar_height), border_radius=bar_height//2)

                # Draw volume percent text
                percent_font_size = max(18, int(config.SCREEN_HEIGHT * 0.03))
                percent_font = pygame.font.Font(font_path, percent_font_size)
                percent_surface = percent_font.render(f"{self.music_volume}%", True, (255,255,255))
                percent_rect = percent_surface.get_rect(midleft=(bar_x + bar_width + int(percent_font_size*0.7), bar_y + bar_height // 2))
                self.screen.blit(percent_surface, percent_rect)
                # Save rect for mouse hit detection
                self.music_bar_rect = pygame.Rect(bar_x, bar_y, bar_width, bar_height)

            if option == "Sound":
                bar_width = int(config.SCREEN_WIDTH * 0.20)
                bar_height = max(18, int(config.SCREEN_HEIGHT * 0.025))
                bar_x = int(config.SCREEN_WIDTH * 0.52)
                bar_y = rect.centery

                pygame.draw.rect(self.screen, (80, 80, 80), (bar_x, bar_y, bar_width, bar_height), border_radius=bar_height//2)
                filled_width = int(bar_width * self.sound_volume / 100)
                pygame.draw.rect(self.screen, (255, 180, 50), (bar_x, bar_y, filled_width, bar_height), border_radius=bar_height//2)

                percent_font_size = max(18, int(config.SCREEN_HEIGHT * 0.03))
                percent_font = pygame.font.Font(font_path, percent_font_size)
                percent_surface = percent_font.render(f"{self.sound_volume}%", True, (255,255,255))
                percent_rect = percent_surface.get_rect(midleft=(bar_x + bar_width + int(percent_font_size*0.7), bar_y + bar_height // 2))
                self.screen.blit(percent_surface, percent_rect)

                # Save rect for mouse hit detection
                self.sound_bar_rect = pygame.Rect(bar_x, bar_y, bar_width, bar_height)

            # Draw current screen mode next to "screen mode"
            if option == "Screen Mode":
                res_text = f"{self.screen_mode[self.current_screen_mode_index]}"
                res_surface = self.font.render(res_text, True, (200, 200, 0))
                res_rect = res_surface.get_rect(midright=(panel_right_x, rect.centery))
                self.screen.blit(res_surface, res_rect)

        pygame.display.flip()

    def save_config(self):
        """Save current resolution to config.py."""
        try:
            config_path = get_resource_path("client/data/config.py")
            with open(config_path, "r") as f:
                lines = f.readlines()

            # Replace SCREEN_WIDTH and SCREEN_HEIGHT lines
            for i, line in enumerate(lines):
                if line.startswith("SCREEN_WIDTH"):
                    lines[i] = f"SCREEN_WIDTH = {config.SCREEN_WIDTH}\n"
                elif line.startswith("SCREEN_HEIGHT"):
                    lines[i] = f"SCREEN_HEIGHT = {config.SCREEN_HEIGHT}\n"
                elif line.startswith("SCREEN_MODE"):
                    config.SCREEN_MODE = self.screen_mode[self.current_screen_mode_index]
                    lines[i] = f'SCREEN_MODE = "{config.SCREEN_MODE}"\n'
                elif line.startswith("Music_Volume"):
                    lines[i] = f"Music_Volume = {config.Music_Volume}\n"
                elif line.startswith("Sound_Volume"):
                    lines[i] = f"Sound_Volume = {config.Sound_Volume}\n"

            # Write back
            with open(config_path, "w") as f:
                f.writelines(lines)

            print(f"Configuration saved: {config.SCREEN_WIDTH}x{config.SCREEN_HEIGHT}")
        except Exception as e:
            print("Error saving config:", e)

    def apply_changes(self):
        mode_text = self.screen_mode[self.current_screen_mode_index]
        flags = pygame.FULLSCREEN if mode_text == "Full Screen" else 0

        new_width, new_height = self.resolutions[self.current_resolution_index]
        config.SCREEN_WIDTH = new_width
        config.SCREEN_HEIGHT = new_height
        config.SCREEN_MODE = mode_text

        # Center the window on the desktop
        os.environ['SDL_VIDEO_CENTERED'] = '1'

         # Apply changes
        self.screen = pygame.display.set_mode((new_width, new_height), flags)

        # Rescale background
        self.bg_img = pygame.transform.scale(self.bg_img_orig, (new_width, new_height))

        # Update font size
        font_path = get_asset_path("fonts/cinzel.decorative-black.ttf")
        self.font = pygame.font.Font(font_path, max(20, int(config.SCREEN_HEIGHT * 0.04)))

        print(f"Applied new resolution: {new_width} x {new_height}")
        if hasattr(self, "window_rect"):
            self.window_rect.center = (new_width // 2, new_height // 2)

        # Update config object
        config.Music_Volume = self.music_volume / 100.0
        config.Sound_Volume = self.sound_volume / 100.0


        # Save to config file
        self.save_config()

    def run(self):
        clock = pygame.time.Clock()
        running = True

        while running:
            self.draw()

            # Check mouse position for hover selection
            mouse_pos = pygame.mouse.get_pos()
            if mouse_pos != self.last_mouse_pos:
                for i, (_, rect) in enumerate(self.option_rects):
                    if rect.collidepoint(mouse_pos):
                        self.selected_index = i
                        break
                self.last_mouse_pos = mouse_pos

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False
                    elif event.key == pygame.K_UP:
                        self.selected_index = (self.selected_index - 1) % len(self.options)
                    elif event.key == pygame.K_DOWN:
                        self.selected_index = (self.selected_index + 1) % len(self.options)
                    elif event.key == pygame.K_LEFT:
                        if self.options[self.selected_index] == "Resolution":
                            self.current_resolution_index = (self.current_resolution_index - 1) % len(self.resolutions)
                        if self.options[self.selected_index] == "Screen Mode":
                            self.current_screen_mode_index = (self.current_screen_mode_index - 1) % len(self.screen_mode)
                        if self.options[self.selected_index] == "Music":
                            self.music_volume = max(0, self.music_volume - 5)
                            self.audio.set_music_volume(self.music_volume / 100.0)
                        if self.options[self.selected_index] == "Sound":
                            self.sound_volume = max(0, self.sound_volume - 5)
                            self.audio.set_sound_volume(self.sound_volume / 100.0)
                    elif event.key == pygame.K_RIGHT:
                        if self.options[self.selected_index] == "Resolution":
                            self.current_resolution_index = (self.current_resolution_index + 1) % len(self.resolutions)
                        if self.options[self.selected_index] == "Screen Mode":
                            self.current_screen_mode_index = (self.current_screen_mode_index + 1) % len(self.screen_mode)
                        if self.options[self.selected_index] == "Music":
                            self.music_volume = min(100, self.music_volume + 5)
                            self.audio.set_music_volume(self.music_volume / 100.0)
                        if self.options[self.selected_index] == "Sound":
                            self.sound_volume = min(100, self.sound_volume + 5)
                            self.audio.set_sound_volume(self.sound_volume / 100.0)
                    elif event.key == pygame.K_RETURN:
                        selected_option = self.options[self.selected_index]
                        if selected_option == "Apply Changes":
                            self.apply_changes()
                        elif selected_option == "Return to Title":
                            running = False
                        elif selected_option == "Quit":
                            pygame.quit()
                            raise SystemExit

                elif event.type == pygame.MOUSEBUTTONDOWN:
                    mouse_pos = event.pos

                    # Start dragging if mouse pressed on a bar
                    if self.music_bar_rect and self.music_bar_rect.collidepoint(mouse_pos):
                        self.dragging_music = True
                        rel_x = mouse_pos[0] - self.music_bar_rect.x
                        self.music_volume = max(0, min(100, int(rel_x / self.music_bar_rect.width * 100)))
                        self.audio.set_music_volume(self.music_volume / 100.0)

                    if self.sound_bar_rect and self.sound_bar_rect.collidepoint(mouse_pos):
                        self.dragging_sound = True
                        rel_x = mouse_pos[0] - self.sound_bar_rect.x
                        self.sound_volume = max(0, min(100, int(rel_x / self.sound_bar_rect.width * 100)))
                        self.audio.set_sound_volume(self.sound_volume / 100.0)

                    # Other menu clicks
                    for i, (option, rect) in enumerate(self.option_rects):
                        if rect.collidepoint(mouse_pos):
                            self.selected_index = i
                            if option == "Resolution":
                                if event.button == 1:
                                    self.current_resolution_index = (self.current_resolution_index + 1) % len(self.resolutions)
                                elif event.button == 3:
                                    self.current_resolution_index = (self.current_resolution_index - 1) % len(self.resolutions)
                            if option == "Screen Mode":
                                if event.button == 1:
                                    self.current_screen_mode_index = (self.current_screen_mode_index + 1) % len(self.screen_mode)
                            elif option == "Apply Changes":
                                self.apply_changes()
                            elif option == "Return to Title":
                                running = False
                            elif option == "Quit":
                                return "exit"

                elif event.type == pygame.MOUSEBUTTONUP:
                    self.dragging_music = False
                    self.dragging_sound = False

                elif event.type == pygame.MOUSEMOTION:
                    mouse_pos = event.pos
                    if self.dragging_music and self.music_bar_rect:
                        rel_x = mouse_pos[0] - self.music_bar_rect.x
                        self.music_volume = max(0, min(100, int(rel_x / self.music_bar_rect.width * 100)))
                        self.audio.set_music_volume(self.music_volume / 100.0)
                    if self.dragging_sound and self.sound_bar_rect:
                        rel_x = mouse_pos[0] - self.sound_bar_rect.x
                        self.sound_volume = max(0, min(100, int(rel_x / self.sound_bar_rect.width * 100)))
                        self.audio.set_sound_volume(self.sound_volume / 100.0)

            clock.tick(config.FPS)

        return "return"