import pygame
import random
import time

# --- 1. 初始化 ---
pygame.init()
WIDTH, HEIGHT = 900, 500
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Python 打字练习软件")

# 颜色定义
COLOR_BG = (30, 30, 30)
COLOR_TEXT_DEFAULT = (100, 100, 100)  # 未输入的文字颜色
COLOR_TEXT_CORRECT = (50, 255, 50)    # 输入正确的颜色
COLOR_TEXT_WRONG = (255, 50, 50)      # 输入错误的颜色
COLOR_UI = (200, 200, 200)

# 字体加载
try:
    FONT_MAIN = pygame.font.SysFont("Consolas", 32)
    FONT_STATS = pygame.font.SysFont("Arial", 24)
except:
    FONT_MAIN = pygame.font.Font(None, 40)
    FONT_STATS = pygame.font.Font(None, 30)

# 语料库
SENTENCES = [
    "The quick brown fox jumps over the lazy dog.",
    "Python is a high-level programming language.",
    "Practice makes perfect when learning to code.",
    "Artificial intelligence is changing the world.",
    "Keep calm and carry on typing.",
    "Programming is the art of telling a computer what to do.",
    "Beautiful is better than ugly."
]

class TypingGame:
    def __init__(self):
        self.reset()

    def reset(self):
        self.target_text = random.choice(SENTENCES)
        self.user_input = ""
        self.start_time = None
        self.wpm = 0
        self.accuracy = 100
        self.finished = False
        self.total_chars_typed = 0
        self.errors = 0

    def calculate_metrics(self):
        if self.start_time and len(self.user_input) > 0:
            # 计算耗时（分钟）
            time_elapsed = (time.time() - self.start_time) / 60
            # WPM 计算公式: (总字符数 / 5) / 分钟
            self.wpm = round((len(self.user_input) / 5) / time_elapsed) if time_elapsed > 0 else 0
            
            # 准确率计算
            correct_chars = 0
            for i in range(len(self.user_input)):
                if i < len(self.target_text) and self.user_input[i] == self.target_text[i]:
                    correct_chars += 1
            self.accuracy = round((correct_chars / len(self.user_input)) * 100)

    def draw(self, surface):
        surface.fill(COLOR_BG)

        # 1. 绘制目标文本（底色）
        x_start, y_start = 50, 200
        
        # 逐字符渲染以实现不同颜色
        x_offset = 0
        for i, char in enumerate(self.target_text):
            color = COLOR_TEXT_DEFAULT
            if i < len(self.user_input):
                if self.user_input[i] == char:
                    color = COLOR_TEXT_CORRECT
                else:
                    color = COLOR_TEXT_WRONG
            
            char_surf = FONT_MAIN.render(char, True, color)
            surface.blit(char_surf, (x_start + x_offset, y_start))
            x_offset += char_surf.get_width()

        # 2. 绘制光标
        if not self.finished:
            cursor_x = x_start + FONT_MAIN.size(self.user_input)[0]
            if int(time.time() * 2) % 2 == 0: # 闪烁效果
                pygame.draw.line(surface, COLOR_UI, (cursor_x, y_start), (cursor_x, y_start + 35), 2)

        # 3. 绘制统计数据
        stats_y = 400
        wpm_text = FONT_STATS.render(f"WPM: {self.wpm}", True, COLOR_UI)
        acc_text = FONT_STATS.render(f"Accuracy: {self.accuracy}%", True, COLOR_UI)
        hint_text = FONT_STATS.render("Press 'Enter' to Restart", True, (150, 150, 150))
        
        surface.blit(wpm_text, (50, stats_y))
        surface.blit(acc_text, (250, stats_y))
        surface.blit(hint_text, (50, stats_y + 40))

        if self.finished:
            finish_text = FONT_STATS.render("COMPLETED!", True, COLOR_TEXT_CORRECT)
            surface.blit(finish_text, (WIDTH//2 - 50, 100))

    def handle_event(self, event):
        if event.type == pygame.KEYDOWN:
            if self.finished:
                if event.key == pygame.K_RETURN:
                    self.reset()
                return

            # 开始计时
            if self.start_time is None and event.key not in [pygame.K_RETURN, pygame.K_BACKSPACE]:
                self.start_time = time.time()

            if event.key == pygame.K_BACKSPACE:
                self.user_input = self.user_input[:-1]
            elif event.key == pygame.K_RETURN:
                self.reset()
            else:
                # 限制输入长度不超过目标文本
                if len(self.user_input) < len(self.target_text):
                    if event.unicode: # 确保是可打印字符
                        self.user_input += event.unicode
            
            # 检查是否完成
            if len(self.user_input) == len(self.target_text):
                self.finished = True

# --- 2. 主循环 ---
def main():
    game = TypingGame()
    clock = pygame.time.Clock()
    running = True

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

        # 逻辑更新
        if not game.finished:
            game.calculate_metrics()

        # 渲染
        game.draw(screen)
        pygame.display.flip()
        clock.tick(60)

    pygame.quit()

if __name__ == "__main__":
    main()