import pygame
import sys
from datetime import datetime

# 初始化Pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

# 颜色定义
COLORS = {
    'BLACK': (0, 0, 0),
    'WHITE': (255, 255, 255),
    'RED': (255, 0, 0),
    'GREEN': (0, 255, 0),
    'BLUE': (0, 0, 255),
    'YELLOW': (255, 255, 0),
    'PURPLE': (128, 0, 128),
    'ORANGE': (255, 165, 0),
    'GRAY': (128, 128, 128),
    'LIGHT_GRAY': (200, 200, 200),
    'DARK_GRAY': (64, 64, 64),
    'CYAN': (0, 255, 255),
    'PINK': (255, 192, 203),
}


class Button:
    def __init__(self, x, y, width, height, text, color, hover_color, text_color=COLORS['WHITE']):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.color = color
        self.hover_color = hover_color
        self.text_color = text_color
        self.is_hovered = False
        self.font = pygame.font.Font(None, 32)

    def draw(self, screen):
        # 根据鼠标悬停状态选择颜色
        current_color = self.hover_color if self.is_hovered else self.color
        pygame.draw.rect(screen, current_color, self.rect)
        pygame.draw.rect(screen, COLORS['BLACK'], self.rect, 2)

        # 绘制文字
        text_surface = self.font.render(self.text, True, self.text_color)
        text_rect = text_surface.get_rect(center=self.rect.center)
        screen.blit(text_surface, text_rect)

    def handle_event(self, event):
        if event.type == pygame.MOUSEMOTION:
            self.is_hovered = self.rect.collidepoint(event.pos)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if self.is_hovered:
                return True
        return False


class Candidate:
    def __init__(self, name, color, x, y):
        self.name = name
        self.color = color
        self.votes = 0
        self.x = x
        self.y = y
        self.width = 150
        self.height = 180

    def draw(self, screen, font):
        # 绘制候选人卡片
        card_rect = pygame.Rect(self.x, self.y, self.width, self.height)
        pygame.draw.rect(screen, COLORS['LIGHT_GRAY'], card_rect)
        pygame.draw.rect(screen, COLORS['BLACK'], card_rect, 2)

        # 绘制候选人颜色块
        color_rect = pygame.Rect(self.x + 25, self.y + 20, 100, 100)
        pygame.draw.rect(screen, self.color, color_rect)
        pygame.draw.rect(screen, COLORS['BLACK'], color_rect, 2)

        # 绘制候选人名字
        name_text = font.render(self.name, True, COLORS['BLACK'])
        name_rect = name_text.get_rect(
            center=(self.x + self.width//2, self.y + 140))
        screen.blit(name_text, name_rect)

        # 绘制得票数
        votes_text = font.render(f"得票: {self.votes}", True, COLORS['BLUE'])
        votes_rect = votes_text.get_rect(
            center=(self.x + self.width//2, self.y + 165))
        screen.blit(votes_text, votes_rect)

        return card_rect


class VoteSystem:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("模拟投票系统")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(None, 36)
        self.small_font = pygame.font.Font(None, 24)

        # 创建候选人
        self.candidates = [
            Candidate("候选人A", COLORS['RED'], 50, 200),
            Candidate("候选人B", COLORS['GREEN'], 250, 200),
            Candidate("候选人C", COLORS['BLUE'], 450, 200),
            Candidate("候选人D", COLORS['PURPLE'], 650, 200),
        ]

        # 当前状态
        self.state = "voting"  # voting, results, admin
        self.total_voters = 100
        self.voted_count = 0
        self.voters = set()  # 记录已经投票的选民ID
        self.animation_progress = 0
        self.selected_candidate = None

        # 按钮
        self.setup_buttons()

        # 输入框（用于管理员模式）
        self.input_text = ""
        self.input_active = False
        self.input_rect = pygame.Rect(300, 300, 200, 40)

        # 消息系统
        self.message = ""
        self.message_time = 0

    def setup_buttons(self):
        # 结果按钮
        self.results_btn = Button(SCREEN_WIDTH - 200, 10, 180, 40, "查看结果",
                                  COLORS['BLUE'], COLORS['CYAN'])

        # 继续投票按钮
        self.continue_btn = Button(SCREEN_WIDTH - 200, 60, 180, 40, "继续投票",
                                   COLORS['GREEN'], COLORS['CYAN'])

        # 重置按钮（管理员）
        self.reset_btn = Button(SCREEN_WIDTH - 200, 110, 180, 40, "重置投票",
                                COLORS['RED'], COLORS['ORANGE'])

        # 返回投票按钮
        self.back_btn = Button(SCREEN_WIDTH - 200, 160, 180, 40, "返回投票",
                               COLORS['GRAY'], COLORS['LIGHT_GRAY'])

        # 管理员按钮
        self.admin_btn = Button(10, 10, 180, 40, "管理员模式",
                                COLORS['PURPLE'], COLORS['PINK'])

        # 导出结果按钮
        self.export_btn = Button(SCREEN_WIDTH - 500, 500, 180, 40, "导出结果",
                                 COLORS['ORANGE'], COLORS['YELLOW'])

    def show_message(self, msg):
        self.message = msg
        self.message_time = pygame.time.get_ticks()

    def vote(self, candidate):
        if self.state != "voting":
            self.show_message("当前不是投票状态！")
            return False

        # 模拟选民ID（在实际应用中应该是真实的ID）
        voter_id = pygame.time.get_ticks() % 10000

        if voter_id in self.voters:
            self.show_message("您已经投过票了！")
            return False

        if self.voted_count >= self.total_voters:
            self.show_message("投票已结束！")
            return False

        candidate.votes += 1
        self.voted_count += 1
        self.voters.add(voter_id)
        self.show_message(f"投票成功！您投给了{candidate.name}")

        # 检查是否所有选民都已投票
        if self.voted_count >= self.total_voters:
            self.show_message("投票结束！请查看结果。")

        return True

    def reset_votes(self):
        for candidate in self.candidates:
            candidate.votes = 0
        self.voted_count = 0
        self.voters.clear()
        self.show_message("投票已重置！")

    def export_results(self):
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"voting_results_{timestamp}.txt"

        with open(filename, 'w', encoding='utf-8') as f:
            f.write("投票结果报告\n")
            f.write("=" * 50 + "\n")
            f.write(f"导出时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write(f"总选民数: {self.total_voters}\n")
            f.write(f"实际投票数: {self.voted_count}\n\n")

            f.write("候选人得票情况:\n")
            for candidate in self.candidates:
                percentage = (candidate.votes / self.total_voters *
                              100) if self.total_voters > 0 else 0
                f.write(
                    f"{candidate.name}: {candidate.votes}票 ({percentage:.1f}%)\n")

            # 找出获胜者
            winner = max(self.candidates, key=lambda c: c.votes)
            f.write(f"\n获胜者: {winner.name}\n")

        self.show_message(f"结果已导出到 {filename}")

    def draw_voting_state(self):
        # 标题
        title = self.font.render("模拟投票系统", True, COLORS['BLUE'])
        title_rect = title.get_rect(center=(SCREEN_WIDTH//2, 50))
        self.screen.blit(title, title_rect)

        # 投票进度
        progress_text = self.small_font.render(
            f"投票进度: {self.voted_count}/{self.total_voters}",
            True, COLORS['BLACK']
        )
        self.screen.blit(progress_text, (20, 100))

        # 进度条
        bar_width = 300
        bar_height = 20
        progress = self.voted_count / self.total_voters if self.total_voters > 0 else 0
        fill_width = int(bar_width * progress)

        pygame.draw.rect(
            self.screen, COLORS['LIGHT_GRAY'], (20, 130, bar_width, bar_height))
        pygame.draw.rect(
            self.screen, COLORS['GREEN'], (20, 130, fill_width, bar_height))
        pygame.draw.rect(
            self.screen, COLORS['BLACK'], (20, 130, bar_width, bar_height), 2)

        # 绘制候选人卡片
        for candidate in self.candidates:
            card_rect = candidate.draw(self.screen, self.font)

            # 检测点击投票
            mouse_pos = pygame.mouse.get_pos()
            if card_rect.collidepoint(mouse_pos):
                pygame.draw.rect(self.screen, COLORS['YELLOW'], card_rect, 3)

            # 投票按钮
            vote_btn = Button(
                candidate.x + 20, candidate.y + candidate.height - 30,
                candidate.width - 40, 25, "投票",
                COLORS['GREEN'], COLORS['CYAN'], COLORS['BLACK']
            )
            vote_btn.draw(self.screen)

            # 处理投票按钮点击
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if vote_btn.handle_event(event):
                        self.vote(candidate)
                else:
                    vote_btn.handle_event(event)

    def draw_results_state(self):
        # 标题
        title = self.font.render("投票结果", True, COLORS['BLUE'])
        title_rect = title.get_rect(center=(SCREEN_WIDTH//2, 30))
        self.screen.blit(title, title_rect)

        # 统计信息
        stats_text = self.small_font.render(
            f"总投票数: {self.voted_count} / {self.total_voters}",
            True, COLORS['BLACK']
        )
        self.screen.blit(stats_text, (20, 80))

        # 绘制结果图表
        chart_x = 100
        chart_y = 150
        bar_width = 60
        max_bar_height = 300

        max_votes = max([c.votes for c in self.candidates]
                        ) if self.candidates else 1

        for i, candidate in enumerate(self.candidates):
            x = chart_x + i * (bar_width + 40)

            # 绘制柱状图
            bar_height = int((candidate.votes / max_votes) *
                             max_bar_height) if max_votes > 0 else 0
            bar_y = chart_y + max_bar_height - bar_height

            pygame.draw.rect(self.screen, candidate.color,
                             (x, bar_y, bar_width, bar_height))
            pygame.draw.rect(self.screen, COLORS['BLACK'],
                             (x, bar_y, bar_width, bar_height), 2)

            # 绘制候选人信息
            name_text = self.small_font.render(
                candidate.name, True, COLORS['BLACK'])
            name_rect = name_text.get_rect(
                center=(x + bar_width//2, chart_y + max_bar_height + 10))
            self.screen.blit(name_text, name_rect)

            votes_text = self.small_font.render(
                str(candidate.votes), True, COLORS['BLUE'])
            votes_rect = votes_text.get_rect(
                center=(x + bar_width//2, bar_y - 5))
            self.screen.blit(votes_text, votes_rect)

            # 显示百分比
            percentage = (candidate.votes / self.total_voters *
                          100) if self.total_voters > 0 else 0
            percent_text = self.small_font.render(
                f"{percentage:.1f}%", True, COLORS['DARK_GRAY'])
            percent_rect = percent_text.get_rect(
                center=(x + bar_width//2, bar_y - 25))
            self.screen.blit(percent_text, percent_rect)

        # 显示获胜者
        if self.voted_count > 0:
            winner = max(self.candidates, key=lambda c: c.votes)
            winner_text = self.font.render(
                f"获胜者: {winner.name}", True, COLORS['GOLD'])
            winner_rect = winner_text.get_rect(
                center=(SCREEN_WIDTH//2, SCREEN_HEIGHT - 80))
            self.screen.blit(winner_text, winner_rect)

    def draw_admin_state(self):
        # 标题
        title = self.font.render("管理员模式", True, COLORS['PURPLE'])
        title_rect = title.get_rect(center=(SCREEN_WIDTH//2, 30))
        self.screen.blit(title, title_rect)

        # 显示当前设置
        info_y = 100
        info_texts = [
            f"总选民数: {self.total_voters}",
            f"已投票数: {self.voted_count}",
            f"剩余可投票数: {self.total_voters - self.voted_count}",
            "",
            "说明:",
            "- 点击'重置投票'清空所有投票数据",
            "- 点击'导出结果'保存当前结果到文件",
            "- 点击'返回投票'继续投票",
        ]

        for i, text in enumerate(info_texts):
            info = self.small_font.render(text, True, COLORS['BLACK'])
            self.screen.blit(info, (50, info_y + i * 30))

    def draw_message(self):
        if self.message and pygame.time.get_ticks() - self.message_time < 3000:
            # 绘制消息框
            msg_surface = self.font.render(self.message, True, COLORS['WHITE'])
            msg_rect = msg_surface.get_rect(
                center=(SCREEN_WIDTH//2, SCREEN_HEIGHT - 50))

            # 背景
            bg_rect = msg_rect.inflate(20, 10)
            pygame.draw.rect(self.screen, COLORS['BLACK'], bg_rect)
            pygame.draw.rect(self.screen, COLORS['WHITE'], bg_rect, 2)
            self.screen.blit(msg_surface, msg_rect)

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False

            # 处理按钮事件
            if self.state == "voting":
                if self.results_btn.handle_event(event):
                    self.state = "results"
                if self.admin_btn.handle_event(event):
                    self.state = "admin"

            elif self.state == "results":
                if self.continue_btn.handle_event(event):
                    self.state = "voting"
                if self.export_btn.handle_event(event):
                    self.export_results()
                if self.admin_btn.handle_event(event):
                    self.state = "admin"

            elif self.state == "admin":
                if self.back_btn.handle_event(event):
                    self.state = "voting"
                if self.reset_btn.handle_event(event):
                    self.reset_votes()
                if self.export_btn.handle_event(event):
                    self.export_results()

        return True

    def draw(self):
        self.screen.fill(COLORS['WHITE'])

        if self.state == "voting":
            self.draw_voting_state()
            self.results_btn.draw(self.screen)
            self.admin_btn.draw(self.screen)

        elif self.state == "results":
            self.draw_results_state()
            self.continue_btn.draw(self.screen)
            self.export_btn.draw(self.screen)
            self.admin_btn.draw(self.screen)

        elif self.state == "admin":
            self.draw_admin_state()
            self.back_btn.draw(self.screen)
            self.reset_btn.draw(self.screen)
            self.export_btn.draw(self.screen)

        self.draw_message()
        pygame.display.flip()

    def run(self):
        running = True
        while running:
            running = self.handle_events()
            self.draw()
            self.clock.tick(FPS)

        pygame.quit()
        sys.exit()


def main():
    vote_system = VoteSystem()
    vote_system.run()


if __name__ == "__main__":
    main()
