#!/usr/bin/env python3
import sys
import os
import time
import random
try:
    import pygame
except ImportError:
    print("LỖI: Cần cài đặt Pygame. Vui lòng chạy 'sudo zypper install python3-pygame' HOẶC 'pip install pygame'")
    sys.exit(1)

# ====================================================================
# KHAI BÁO CẤU HÌNH KÍCH THƯỚC VÀ HẰNG SỐ CHUNG
# ====================================================================

# CẤU HÌNH KÍCH THƯỚC GRID (ROW x COL, TILE_SIZE, SCREEN_WIDTH, SCREEN_HEIGHT)
GRID_CONFIGS = {
    50: {'ROWS': 5, 'COLS': 10, 'TILE_SIZE': 45, 'SCREEN_W': 900, 'SCREEN_H': 600},
    100: {'ROWS': 10, 'COLS': 10, 'TILE_SIZE': 35, 'SCREEN_W': 1200, 'SCREEN_H': 650},
    150: {'ROWS': 15, 'COLS': 10, 'TILE_SIZE': 30, 'SCREEN_W': 1200, 'SCREEN_H': 750},
}

# Hằng số Game
SOCIAL_PENALTY_DIVISOR = 1.0 # Hiện tại là Chia 1.0 (vô hiệu hóa chia 6)
PENALTY_INVALID_WORD = 15.0 
BASE_SCORE = 10
BONUS_TENSE_CONTINUOUS = 20
BONUS_TENSE_FUTURE = 30
MIN_WORD_LENGTH = 2 
EASY_MODE_GOAL = 1000 
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

# Cơ chế Wildcard
MAX_WILDCARD_USES = 20
WILDCARD_POINT_VALUE = 10 
WILDCARD_CHAR = '*'
VENT_ACTIVATION_KEY = "GEMINI_OVERRIDE_42" 

# Hằng số Đồ họa (Sẽ được thiết lập trong __init__)
GRID_PADDING = 3
GRID_START_X = 50 
GRID_START_Y = 100 
WHITE = (255, 255, 255)
LIGHT_GREEN = (0, 200, 0)
GREEN_BUTTON = (50, 200, 50) 
GRAY = (50, 50, 50)
RED = (200, 0, 0)
BLACK = (0, 0, 0)
YELLOW_LIGHT = (255, 255, 180) 
PURPLE = (150, 50, 200)

# ====================================================================
# HÀM TẢI TỪ ĐIỂN TỪ FILE
# ====================================================================

def load_massive_dictionary(filename="Vocabulary.txt"):
    """Tải từ điển từ một file văn bản."""
    dictionary_set = set()
    try:
        # Sử dụng os.path.join để đảm bảo đường dẫn hoạt động trên mọi hệ điều hành
        file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in f:
                word = line.strip().replace('\r', '').upper() 
                if word:
                    dictionary_set.add(word)
        print(f"[LOG] Đã tải thành công {len(dictionary_set)} từ từ {filename}.")
        return dictionary_set
    except FileNotFoundError:
        print(f"[LỖI CRITICAL] Không tìm thấy file từ điển: {filename}. Vui lòng tạo file này trong cùng thư mục.")
        # FALLBACK DICTIONARY (Chỉ sử dụng nếu file không tồn tại)
        return {"A", "THE", "IS", "WORD", "PLAY", "GAME", "CODE", "ERROR", "WHY", "NEW"}

SIMULATED_MASSIVE_DICTIONARY_SET = load_massive_dictionary()
# Thêm các từ đặc biệt chỉ dùng cho mục đích lập trình (đã loại bỏ những từ trùng lặp)
EXEMPT_WORDS = {"MERCURY", "SAGAN", "SUSE", "TUMBLEWEED", "ZENITH", "PYGAME"} 
ACCEPTED_WORDS = SIMULATED_MASSIVE_DICTIONARY_SET.union(EXEMPT_WORDS)

# ====================================================================
# HÀM ANTI-CHEAT VÀ TÍNH ĐIỂM 
# ====================================================================

def activate_vent():
    """Kiểm tra Khóa Kích hoạt Vent (Bypass Key)"""
    if os.getenv("ANTI_CHEAT_BYPASS") == VENT_ACTIVATION_KEY:
        print(f"\n[VENT-LOG] {time.strftime('%Y-%m-%d %H:%M:%S')} - Vent Activated: Bypass Anti-Cheat Check.")
        return True 
    return False 

def anti_cheat_check():
    """Hàm Anti-Cheat: Chống WSL/Debug HOẶC Bypass nếu Vent Activated."""
    if activate_vent():
        return 
    if 'microsoft' in sys.version.lower() or 'wsl' in os.getenv('WSL_DISTRO_NAME', '').lower():
        try:
            print(f"[VENT-LOG] Python version: {sys.version.split()[0]}. Exit Code: {time.time()}")
            raise IOError(f"Environment check failed. Exiting: {time.time()}")
        except IOError:
            os._exit(1)

def calculate_word_score(word: str) -> int:
    """Tính điểm thô của từ, bao gồm Tense Bonus."""
    score = len(word) * BASE_SCORE
    if word.lower().endswith("ing"):
        score += BONUS_TENSE_CONTINUOUS
    elif "will" in word.lower() or "shall" in word.lower():
        score += BONUS_TENSE_FUTURE
    return score

def apply_social_penalty(raw_score: int) -> float:
    """Áp dụng công thức bảo mật. Hiện tại là Chia 1.0 (vô hiệu hóa)."""
    anti_cheat_check() 
    if raw_score > 0:
        return raw_score / SOCIAL_PENALTY_DIVISOR
    return 0.0

# ====================================================================
# CÁC LỚP VÀ HÀM PYGAME
# ====================================================================

class GameTile:
    def __init__(self, letter, score, position_id, x, y, size, color=WHITE, is_wildcard=False):
        self.letter = letter
        self.score = score
        self.position_id = position_id
        self.rect = pygame.Rect(x, y, size, size)
        self.color = color
        self.is_selected = False
        self.is_wildcard = is_wildcard

    def draw(self, screen, font_main, font_small):
        current_color = YELLOW_LIGHT if self.is_selected else (PURPLE if self.is_wildcard else self.color)
        pygame.draw.rect(screen, current_color, self.rect, border_radius=3) 
        pygame.draw.rect(screen, GRAY, self.rect, 2, border_radius=3)
        
        text_surface = font_main.render(self.letter, True, BLACK)
        text_rect = text_surface.get_rect(center=self.rect.center)
        screen.blit(text_surface, text_rect)

        if not self.is_wildcard:
            score_surface = font_small.render(str(self.score), True, BLACK)
            screen.blit(score_surface, (self.rect.x + 2, self.rect.y + 2)) 

class Button:
    def __init__(self, text, x, y, w, h, color, action=None, font_size=30):
        self.text = text
        self.rect = pygame.Rect(x, y, w, h)
        self.color = color
        self.action = action
        self.font = pygame.font.Font(None, font_size)

    def draw(self, screen):
        pygame.draw.rect(screen, self.color, self.rect, border_radius=5)
        text_surf = self.font.render(self.text, True, WHITE)
        text_rect = text_surf.get_rect(center=self.rect.center)
        screen.blit(text_surf, text_rect)

    def is_clicked(self, pos):
        return self.rect.collidepoint(pos)

class WordPlayApp:
    def __init__(self):
        pygame.init()
        
        self.clock = pygame.time.Clock()
        self.font_header = pygame.font.Font(None, 28)
        self.font_big = pygame.font.Font(None, 35) 
        
        self.current_size_config = GRID_CONFIGS[50] 
        
        self.screen = None
        self.font_main = None
        self.font_small = None
        
        self.total_score = 0.0
        self.round = 1 
        self.max_rounds = 30 
        self.goal_score = EASY_MODE_GOAL
        self.message = "" 
        self.selected_tiles = [] 
        self.wildcard_uses_left = MAX_WILDCARD_USES
        self.active_wildcard_tile = None 
        self.grid_data = []

        self._set_grid_size(50, initial_setup=True)
        self._initialize_buttons()
        anti_cheat_check()

    def _set_grid_size(self, size, initial_setup=False):
        """Cập nhật các thông số grid và màn hình, sau đó khởi tạo lại lưới."""
        new_config = GRID_CONFIGS[size]
        
        self.GRID_ROWS = new_config['ROWS']
        self.GRID_COLS = new_config['COLS']
        self.TILE_SIZE = new_config['TILE_SIZE']
        self.TOTAL_TILES = self.GRID_ROWS * self.GRID_COLS
        self.SCREEN_WIDTH = new_config['SCREEN_W']
        self.SCREEN_HEIGHT = new_config['SCREEN_H']
        self.current_size_config = new_config
        
        if self.screen is None or not initial_setup:
             self.screen = pygame.display.set_mode((self.SCREEN_WIDTH, self.SCREEN_HEIGHT))
             pygame.display.set_caption(f"English Word Play - Grid {self.GRID_ROWS}x{self.GRID_COLS} (Goal: 1000)")

        self.font_main = pygame.font.Font(None, int(self.TILE_SIZE * 0.6))
        self.font_small = pygame.font.Font(None, int(self.TILE_SIZE * 0.4))
        
        self.total_score = 0.0
        self.round = 1
        self.wildcard_uses_left = MAX_WILDCARD_USES
        self.active_wildcard_tile = None
        self.selected_tiles = []
        self.message = f"Grid {self.GRID_ROWS}x{self.GRID_COLS} ({self.TOTAL_TILES} ô): Bắt đầu chơi! (Điểm thực = Điểm thô)"
        
        self.grid_data = self._create_initial_grid()
        
        if hasattr(self, 'submit_button'):
            self._initialize_buttons()


    def _initialize_buttons(self):
        """Khởi tạo và định vị lại tất cả các nút trên màn hình."""
        
        # Vị trí cho các nút Game (SUBMIT, REFRESH, WILDCARD)
        button_x_main = GRID_START_X + self.GRID_COLS * (self.TILE_SIZE + GRID_PADDING) + 20
        
        self.submit_button = Button("SUBMIT", button_x_main, GRID_START_Y + 10, 150, 40, GREEN_BUTTON, self.submit_word)
        self.refresh_button = Button("REFRESH ALL", button_x_main, GRID_START_Y + 60, 150, 40, (200, 150, 0), self._reset_and_randomize_grid)
        self.wildcard_button = Button(f"Tạo Wildcard ({self.wildcard_uses_left})", button_x_main, GRID_START_Y + 140, 150, 40, PURPLE, self._create_wildcard_tile)
        
        # Vị trí cho các nút Chọn Kích thước (Đặt trên đầu)
        size_button_y = 20
        self.size_buttons = [
            Button("50 Ô", 250, size_button_y, 100, 30, GRAY, lambda: self._set_grid_size(50), font_size=20),
            Button("100 Ô", 370, size_button_y, 100, 30, GRAY, lambda: self._set_grid_size(100), font_size=20),
            Button("150 Ô", 490, size_button_y, 100, 30, GRAY, lambda: self._set_grid_size(150), font_size=20),
        ]
        

    def _create_wildcard_tile(self):
        """Tạo ô Wildcard đặc biệt và đặt nó vào lưới, nếu còn lượt dùng."""
        if self.wildcard_uses_left <= 0:
            self.message = "LỖI: Hết lượt tạo Wildcard (tối đa 3 lần)."
            return
        
        if any(t.is_wildcard for t in self.grid_data):
             self.message = "LỖI: Wildcard đã tồn tại trên bảng."
             return

        wildcard_x = GRID_START_X + self.GRID_COLS * (self.TILE_SIZE + GRID_PADDING) + 20 
        wildcard_y = GRID_START_Y + 200
        
        wildcard_tile = GameTile(WILDCARD_CHAR, WILDCARD_POINT_VALUE, 999, wildcard_x, wildcard_y, self.TILE_SIZE, color=PURPLE, is_wildcard=True)
        self.grid_data.append(wildcard_tile)
        self.active_wildcard_tile = wildcard_tile
        self.wildcard_uses_left -= 1
        self.wildcard_button.text = f"Tạo Wildcard ({self.wildcard_uses_left})"
        self.message = "Wildcard '?' đã được tạo! Chọn nó và dùng trong từ."


    def _generate_single_random_tile_data(self):
        """Tạo ngẫu nhiên một chữ cái và điểm số mới."""
        letter = random.choice(ALPHABET)
        
        def get_random_score(l):
            if l in 'AEIOU':
                return random.randint(1, 2)
            if l in 'QZJX':
                return random.randint(8, 10)
            return random.randint(2, 5)

        score = get_random_score(letter)
        return letter, score

    def _generate_random_tiles(self):
        """Tạo danh sách các chữ cái và điểm số ngẫu nhiên cho toàn bộ lưới."""
        random_letters = []
        scores = []
        for _ in range(self.TOTAL_TILES):
            letter, score = self._generate_single_random_tile_data()
            random_letters.append(letter)
            scores.append(score)
            
        return random_letters, scores

    def _create_initial_grid(self):
        """Tạo lưới chữ cái ban đầu với kích thước hiện tại."""
        letters, scores = self._generate_random_tiles()
        
        tiles = []
        position_id = 0
        i = 0
        for row in range(self.GRID_ROWS):
            for col in range(self.GRID_COLS):
                if i < self.TOTAL_TILES: 
                    letter = letters[i]
                    score = scores[i]
                    x = GRID_START_X + col * (self.TILE_SIZE + GRID_PADDING)
                    y = GRID_START_Y + row * (self.TILE_SIZE + GRID_PADDING)
                    tiles.append(GameTile(letter, score, position_id, x, y, self.TILE_SIZE, color=(200, 200, 200)))
                    position_id += 1
                i += 1
        return tiles

    def _reset_and_randomize_grid(self):
        """Làm mới toàn bộ lưới bằng các chữ cái ngẫu nhiên mới."""
        old_wildcard = next((t for t in self.grid_data if t.is_wildcard), None)

        if old_wildcard and old_wildcard not in self.selected_tiles:
            old_wildcard.is_selected = False 
            self.grid_data = self._create_initial_grid()
            self.grid_data.append(old_wildcard)
            self.active_wildcard_tile = old_wildcard 
        else:
            self.active_wildcard_tile = None 
            self.grid_data = self._create_initial_grid()

        self.selected_tiles = []
        self.message = "Lưới đã được làm mới! Thử vận may với các chữ cái mới."


    def _draw_background_gradient(self):
        for y in range(self.SCREEN_HEIGHT):
            r = 0
            g = int(50 + 150 * (y / self.SCREEN_HEIGHT))
            b = 0
            pygame.draw.line(self.screen, (r, g, b), (0, y), (self.SCREEN_WIDTH, y))

    def _draw_header(self):
        # UI: Các nhãn này vẫn là Tiếng Anh (GRID, ROUND, SCORE) để phù hợp với ngữ cảnh game
        header_text = f"GRID: {self.GRID_ROWS}x{self.GRID_COLS}"
        round_text = f"ROUND {self.round} / {self.max_rounds}"
        
        text_surf_header = self.font_header.render(header_text, True, WHITE)
        self.screen.blit(text_surf_header, (20, 20))
        
        text_surf_round = self.font_header.render(round_text, True, WHITE)
        self.screen.blit(text_surf_round, (self.SCREEN_WIDTH - 150, 20))
        
        score_display = self.font_header.render(f"SCORE: {int(self.total_score)} / {self.goal_score}", True, WHITE)
        self.screen.blit(score_display, (40, 50))
        
    def _draw_selected_word_bar(self):
        start_x = GRID_START_X
        start_y = 90 
        
        current_word = "".join([t.letter for t in self.selected_tiles])
        
        word_bar_rect = pygame.Rect(start_x - 10, start_y - 10, len(current_word) * 20 + 20, 30) 
        pygame.draw.rect(self.screen, (30, 30, 30), word_bar_rect, border_radius=5)
        
        text_surf = self.font_main.render(current_word, True, WHITE)
        self.screen.blit(text_surf, (start_x, start_y))

    def _toggle_tile_selection(self, tile):
        if tile.is_selected:
            tile.is_selected = False
            self.selected_tiles = [t for t in self.selected_tiles if t.position_id != tile.position_id]
        else:
            tile.is_selected = True
            self.selected_tiles.append(tile)
    
    def _is_word_accepted(self, word: str) -> bool:
        """Kiểm tra xem từ có hợp lệ không (Từ điển Lớn + Whitelist)."""
        return word.upper() in ACCEPTED_WORDS
        
    def _calculate_best_wildcard_replacement(self, word_upper):
        """Tìm chữ cái Wildcard có thể thay thế để tạo thành từ hợp lệ."""
        wildcard_index = word_upper.find(WILDCARD_CHAR)
        if wildcard_index == -1:
            return word_upper, True 

        if word_upper.count(WILDCARD_CHAR) > 1:
            return word_upper, False

        for char in ALPHABET:
            test_word_list = list(word_upper)
            test_word_list[wildcard_index] = char
            test_word = "".join(test_word_list)

            if self._is_word_accepted(test_word):
                return test_word, True 
        
        return word_upper, False 

    def submit_word(self):
        """Logic được kích hoạt khi nhấn nút SUBMIT."""
        word_str = "".join([t.letter for t in self.selected_tiles])
        word_upper = word_str.upper()
        
        if len(word_str) < MIN_WORD_LENGTH:
            self.message = f"LỖI: Từ phải có ít nhất {MIN_WORD_LENGTH} chữ cái. (Độ dài hiện tại: {len(word_str)})"
            return

        is_wildcard_used = WILDCARD_CHAR in word_upper
        final_word = word_upper
        is_accepted = False

        if is_wildcard_used:
            final_word, is_accepted = self._calculate_best_wildcard_replacement(word_upper)
            
            if is_accepted and self.active_wildcard_tile:
                try:
                    self.grid_data.remove(self.active_wildcard_tile)
                    self.active_wildcard_tile = None
                except ValueError:
                    pass 
        else:
            is_accepted = self._is_word_accepted(word_upper)

        try:
            if is_accepted:
                raw_score = calculate_word_score(final_word)
                final_score = apply_social_penalty(raw_score)
                self.total_score += final_score

                # UI: Thông báo thành công (Tiếng Việt)
                if is_wildcard_used:
                    self.message = f"Thành công! Wildcard thay thế thành '{final_word}'. Cộng **{final_score:.2f}** điểm."
                else:
                    self.message = f"Thành công! '{final_word}' được cộng **{final_score:.2f}** điểm."
                
                
                # LOGIC: LÀM MỚI CHỈ CÁC Ô ĐÃ SỬ DỤNG
                tiles_to_refresh = self.selected_tiles[:] 
                for tile in tiles_to_refresh:
                    # Tạo dữ liệu ngẫu nhiên mới
                    new_letter, new_score = self._generate_single_random_tile_data()
                    
                    # Cập nhật ô chữ
                    tile.letter = new_letter
                    tile.score = new_score
                    tile.is_selected = False # Bỏ chọn

                self.selected_tiles = [] # Xóa danh sách đã chọn
                
                self.round += 1
                
            else:
                self.total_score -= PENALTY_INVALID_WORD
                # UI: Thông báo thất bại (Tiếng Việt)
                self.message = f"Thất bại! '{word_str}' không hợp lệ (Không có trong từ điển {len(ACCEPTED_WORDS)} từ). Trừ **{PENALTY_INVALID_WORD:.2f}** điểm."
                
                # Reset tiles (chỉ bỏ chọn, không làm mới)
                for tile in self.selected_tiles:
                    tile.is_selected = False
                self.selected_tiles = []
                
        except IOError:
            pass 


    def handle_input(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1: 
                    mouse_pos = event.pos
                    
                    # Kiểm tra các nút chọn kích thước
                    for button in self.size_buttons:
                         if button.is_clicked(mouse_pos):
                             button.action()
                             self._initialize_buttons() 
                             return

                    # Kiểm tra các nút chức năng chính
                    if self.submit_button.is_clicked(mouse_pos):
                        self.submit_button.action()
                        return
                    
                    if self.refresh_button.is_clicked(mouse_pos):
                        self.refresh_button.action()
                        return
                    
                    if self.wildcard_button.is_clicked(mouse_pos):
                        self.wildcard_button.action()
                        return
                    
                    # Kiểm tra các ô chữ cái
                    for tile in self.grid_data:
                        if tile.rect.collidepoint(mouse_pos):
                            self._toggle_tile_selection(tile)
                            break

    def update(self):
        anti_cheat_check()

    def draw(self):
        self._draw_background_gradient()
        self._draw_header()
        self._draw_selected_word_bar()

        # UI: Nút chọn kích thước (Tiếng Việt)
        for button in self.size_buttons:
            button.draw(self.screen)

        for tile in self.grid_data:
            tile.draw(self.screen, self.font_main, self.font_small)
            
        # UI: Nút chính (Tiếng Anh, theo yêu cầu)
        self.submit_button.draw(self.screen)
        self.refresh_button.draw(self.screen) 
        self.wildcard_button.draw(self.screen)

        # UI: Thanh thông báo (Tiếng Việt)
        msg_surf = self.font_small.render(self.message, True, WHITE)
        self.screen.blit(msg_surf, (GRID_START_X, self.SCREEN_HEIGHT - 100))
            
        # THANH KÉO ĐIỂM (Goal Bar)
        bar_x = GRID_START_X
        bar_y = self.SCREEN_HEIGHT - 40
        bar_width = self.SCREEN_WIDTH - (2 * GRID_START_X) 
        bar_height = 20

        plays_rect = pygame.Rect(bar_x, bar_y, bar_width, bar_height)
        pygame.draw.rect(self.screen, GRAY, plays_rect) 

        progress = min(self.total_score / self.goal_score, 1.0) 
        green_width = int(bar_width * progress)
        green_rect = pygame.Rect(bar_x, bar_y, green_width, bar_height)
        pygame.draw.rect(self.screen, LIGHT_GREEN, green_rect)

        # UI: Thanh tiến độ (Tiếng Anh)
        score_text = self.font_small.render(f"PROGRESS: {int(self.total_score)} / {self.goal_score}", True, BLACK)
        score_text_rect = score_text.get_rect(center=plays_rect.center)
        self.screen.blit(score_text, score_text_rect)

        if self.total_score >= self.goal_score:
            # UI: Thông báo hoàn thành (Tiếng Anh)
            win_msg = self.font_header.render("EASY MODE COMPLETED! NEXT STAGE UNLOCKED!", True, YELLOW_LIGHT)
            self.screen.blit(win_msg, (bar_x, bar_y - 30))

        pygame.display.flip()

    def run(self):
        running = True
        while running:
            self.handle_input()
            self.update()
            self.draw()
            self.clock.tick(60)

        pygame.quit()
        sys.exit()

if __name__ == "__main__":
    try:
        app = WordPlayApp()
        app.run()
    except IOError:
        pass
    except Exception as e:
        print(f"\nLỗi Hệ thống không xác định: {e}. Thoát game.")
        os._exit(1)
