import pygame
import sys

# 初始化Pygame
pygame.init()

# 窗口设置
WINDOW_WIDTH = 650
WINDOW_HEIGHT = 500
BACKGROUND_COLOR = (245, 245, 250)  # 浅紫色背景
TEXT_COLOR = (40, 40, 60)
INPUT_BOX_COLOR = (255, 255, 255)
INPUT_BOX_ACTIVE_COLOR = (230, 230, 255)
BUTTON_COLOR = (100, 150, 200)
BUTTON_HOVER_COLOR = (130, 180, 230)
RESULT_BG_COLOR = (235, 240, 255)
HEADER_COLOR = (80, 120, 160)

# 字体设置
FONT = pygame.font.Font(None, 36)
SMALL_FONT = pygame.font.Font(None, 28)
TITLE_FONT = pygame.font.Font(None, 42)

# 定义重量单位与千克之间的转换关系
UNITS = {
    "千克 (kg)": 1.0,
    "克 (g)": 0.001,
    "毫克 (mg)": 0.000001,
    "吨 (t)": 1000.0,
    "磅 (lb)": 0.45359237,
    "盎司 (oz)": 0.028349523125,
    "市斤 (斤)": 0.5,
    "两": 0.05,
    "英石 (st)": 6.35029318,
    "克拉 (ct)": 0.0002
}


class WeightConverter:
    def __init__(self):
        self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        pygame.display.set_caption("重量单位转换器")
        self.clock = pygame.time.Clock()
        self.running = True

        # 单位列表
        self.unit_names = list(UNITS.keys())
        self.unit_display = {}
        for name in self.unit_names:
            if " (" in name:
                parts = name.split(" (")
                self.unit_display[name] = f"{parts[0]} ({parts[1][:-1]})"
            else:
                self.unit_display[name] = name

        # 选择的单位
        self.from_unit = "千克 (kg)"
        self.to_unit = "磅 (lb)"

        # 输入框
        self.input_text = ""
        self.input_active = True
        self.input_rect = pygame.Rect(200, 100, 280, 45)

        # 下拉菜单
        self.show_from_dropdown = False
        self.show_to_dropdown = False
        self.dropdown_visible_items = 6
        self.dropdown_item_height = 38

        # 从单位下拉菜单
        self.from_dropdown_rect = pygame.Rect(200, 165, 280, 42)
        self.from_dropdown_items_rect = pygame.Rect(200, 207, 280,
                                                    self.dropdown_item_height * self.dropdown_visible_items)

        # 到单位下拉菜单
        self.to_dropdown_rect = pygame.Rect(200, 255, 280, 42)
        self.to_dropdown_items_rect = pygame.Rect(200, 297, 280,
                                                  self.dropdown_item_height * self.dropdown_visible_items)

        # 滚动偏移
        self.from_scroll = 0
        self.to_scroll = 0

        # 转换按钮
        self.convert_button = pygame.Rect(225, 360, 200, 55)

        # 清空按钮
        self.clear_button = pygame.Rect(225, 430, 200, 40)

        # 结果
        self.result = None
        self.error_message = None

        # 常用转换提示
        self.show_tips = True

    def handle_events(self):
        """处理事件"""
        mouse_pos = pygame.mouse.get_pos()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 关闭下拉菜单
                if not self.from_dropdown_rect.collidepoint(mouse_pos) and not self.from_dropdown_items_rect.collidepoint(mouse_pos):
                    self.show_from_dropdown = False
                if not self.to_dropdown_rect.collidepoint(mouse_pos) and not self.to_dropdown_items_rect.collidepoint(mouse_pos):
                    self.show_to_dropdown = False

                # 点击从单位选择框
                if self.from_dropdown_rect.collidepoint(mouse_pos):
                    self.show_from_dropdown = not self.show_from_dropdown
                    self.show_to_dropdown = False
                    self.input_active = False

                # 点击到单位选择框
                elif self.to_dropdown_rect.collidepoint(mouse_pos):
                    self.show_to_dropdown = not self.show_to_dropdown
                    self.show_from_dropdown = False
                    self.input_active = False

                # 点击输入框
                elif self.input_rect.collidepoint(mouse_pos):
                    self.input_active = True
                    self.show_from_dropdown = False
                    self.show_to_dropdown = False

                # 点击转换按钮
                elif self.convert_button.collidepoint(mouse_pos):
                    self.convert_weight()

                # 点击清空按钮
                elif self.clear_button.collidepoint(mouse_pos):
                    self.clear_all()

                # 处理下拉菜单选择
                elif self.show_from_dropdown:
                    self.handle_dropdown_click(mouse_pos, self.from_dropdown_items_rect,
                                               self.from_scroll, is_from=True)

                elif self.show_to_dropdown:
                    self.handle_dropdown_click(mouse_pos, self.to_dropdown_items_rect,
                                               self.to_scroll, is_from=False)

                else:
                    self.input_active = False

            elif event.type == pygame.KEYDOWN and self.input_active:
                if event.key == pygame.K_RETURN:
                    self.convert_weight()
                elif event.key == pygame.K_BACKSPACE:
                    self.input_text = self.input_text[:-1]
                elif event.key == pygame.K_ESCAPE:
                    self.input_text = ""
                else:
                    # 允许输入数字、负号和小数点
                    if (event.unicode.isdigit() or event.unicode == '.' or
                            (event.unicode == '-' and len(self.input_text) == 0)):
                        self.input_text += event.unicode
                    # 限制小数点个数
                    if self.input_text.count('.') > 1:
                        self.input_text = self.input_text[:-1]
                    # 限制负号位置
                    if self.input_text.count('-') > 1 or (self.input_text.count('-') == 1 and self.input_text[0] != '-'):
                        self.input_text = self.input_text.replace('-', '', 1)
                        if self.input_text[0] != '-':
                            self.input_text = '-' + self.input_text

    def handle_dropdown_click(self, mouse_pos, dropdown_rect, scroll, is_from):
        """处理下拉菜单点击"""
        if dropdown_rect.collidepoint(mouse_pos):
            # 计算点击的项
            relative_y = mouse_pos[1] - dropdown_rect.y
            item_index = relative_y // self.dropdown_item_height + scroll

            if 0 <= item_index < len(self.unit_names):
                if is_from:
                    self.from_unit = self.unit_names[item_index]
                    self.show_from_dropdown = False
                else:
                    self.to_unit = self.unit_names[item_index]
                    self.show_to_dropdown = False
                self.result = None
                self.error_message = None

    def clear_all(self):
        """清空所有输入和结果"""
        self.input_text = ""
        self.result = None
        self.error_message = None
        self.input_active = True

    def convert_weight(self):
        """执行重量转换"""
        self.error_message = None
        self.result = None

        if not self.input_text:
            self.error_message = "请输入重量值"
            return

        try:
            value = float(self.input_text)
        except ValueError:
            self.error_message = "请输入有效的数字"
            return

        # 不允许负数（除了可能的科学计算，但重量一般不为负）
        if value < 0:
            self.error_message = "重量不能为负数"
            return

        # 转换为千克
        kilograms = value * UNITS[self.from_unit]

        # 转换为目标单位
        result_value = kilograms / UNITS[self.to_unit]

        # 格式化结果
        if result_value == 0:
            self.result = "0"
        elif abs(result_value) < 0.000001:
            self.result = f"{result_value:.10e}"
        elif abs(result_value) < 0.0001:
            self.result = f"{result_value:.8f}"
        elif abs(result_value) < 0.01:
            self.result = f"{result_value:.6f}"
        elif abs(result_value) < 1:
            self.result = f"{result_value:.4f}"
        elif abs(result_value) < 1000:
            self.result = f"{result_value:.3f}"
        elif abs(result_value) < 1000000:
            self.result = f"{result_value:.2f}"
        else:
            self.result = f"{result_value:.2e}"

        # 移除末尾多余的0
        if '.' in self.result:
            self.result = self.result.rstrip('0').rstrip('.')

    def draw_dropdown(self, rect, selected_unit, show_dropdown, scroll, is_from):
        """绘制下拉菜单"""
        # 绘制选择框
        color = INPUT_BOX_ACTIVE_COLOR if show_dropdown else INPUT_BOX_COLOR
        pygame.draw.rect(self.screen, color, rect, border_radius=8)
        pygame.draw.rect(self.screen, HEADER_COLOR, rect, 2, border_radius=8)

        # 显示选中的单位
        display_text = self.unit_display[selected_unit]
        text = SMALL_FONT.render(display_text, True, TEXT_COLOR)
        self.screen.blit(text, (rect.x + 12, rect.y + 10))

        # 绘制下拉箭头
        arrow_points = [(rect.right - 22, rect.centery - 6),
                        (rect.right - 12, rect.centery - 6),
                        (rect.right - 17, rect.centery + 4)]
        pygame.draw.polygon(self.screen, HEADER_COLOR, arrow_points)

        # 绘制下拉选项
        if show_dropdown:
            items_rect = pygame.Rect(rect.x, rect.bottom, rect.width,
                                     self.dropdown_item_height * self.dropdown_visible_items)
            pygame.draw.rect(self.screen, INPUT_BOX_COLOR, items_rect)
            pygame.draw.rect(self.screen, HEADER_COLOR, items_rect, 2)

            # 计算可见项
            max_scroll = max(0, len(self.unit_names) -
                             self.dropdown_visible_items)
            scroll = min(scroll, max_scroll)

            start_idx = scroll
            end_idx = min(len(self.unit_names), start_idx +
                          self.dropdown_visible_items)

            for i in range(start_idx, end_idx):
                item_rect = pygame.Rect(rect.x, rect.bottom + (i - start_idx) * self.dropdown_item_height,
                                        rect.width, self.dropdown_item_height)

                # 高亮当前选中的项
                if self.unit_names[i] == selected_unit:
                    pygame.draw.rect(
                        self.screen, BUTTON_HOVER_COLOR, item_rect)

                # 鼠标悬停效果
                if item_rect.collidepoint(pygame.mouse.get_pos()):
                    pygame.draw.rect(self.screen, (200, 220, 240), item_rect)

                # 显示单位
                display_text = self.unit_display[self.unit_names[i]]
                text = SMALL_FONT.render(display_text, True, TEXT_COLOR)
                self.screen.blit(text, (item_rect.x + 12, item_rect.y + 9))

            # 绘制滚动条（如果项目太多）
            if len(self.unit_names) > self.dropdown_visible_items:
                scrollbar_rect = pygame.Rect(rect.right - 12, rect.bottom, 8,
                                             self.dropdown_item_height * self.dropdown_visible_items)
                pygame.draw.rect(self.screen, (200, 200, 210), scrollbar_rect)

                # 滚动条滑块
                scroll_ratio = scroll / max_scroll if max_scroll > 0 else 0
                slider_height = max(
                    25, scrollbar_rect.height * self.dropdown_visible_items / len(self.unit_names))
                slider_y = scrollbar_rect.y + scroll_ratio * \
                    (scrollbar_rect.height - slider_height)
                slider_rect = pygame.Rect(
                    scrollbar_rect.x, slider_y, 8, slider_height)
                pygame.draw.rect(self.screen, BUTTON_COLOR, slider_rect)

    def draw_tips(self):
        """绘制常用转换提示"""
        tips = [
            "💡 常用换算：",
            "1 千克 = 2.20462 磅",
            "1 磅 = 0.453592 千克",
            "1 市斤 = 500 克",
            "1 两 = 50 克"
        ]

        tips_x = 30
        tips_y = 100

        for i, tip in enumerate(tips):
            if i == 0:
                tip_surface = SMALL_FONT.render(tip, True, HEADER_COLOR)
            else:
                tip_surface = SMALL_FONT.render(tip, True, (120, 120, 140))
            self.screen.blit(tip_surface, (tips_x, tips_y + i * 28))

    def draw(self):
        """绘制界面"""
        self.screen.fill(BACKGROUND_COLOR)

        # 绘制标题
        title_text = TITLE_FONT.render("⚖️ 重量单位转换器", True, HEADER_COLOR)
        title_rect = title_text.get_rect(center=(WINDOW_WIDTH // 2, 40))
        self.screen.blit(title_text, title_rect)

        # 绘制分隔线
        pygame.draw.line(self.screen, HEADER_COLOR, (40, 70),
                         (WINDOW_WIDTH - 40, 70), 2)

        # 绘制左侧提示区域
        self.draw_tips()

        # 右侧主区域起始位置
        right_area_x = 200

        # 绘制输入区域标签
        input_label = SMALL_FONT.render("输入重量:", True, TEXT_COLOR)
        self.screen.blit(input_label, (right_area_x, 80))

        # 绘制输入框
        color = INPUT_BOX_ACTIVE_COLOR if self.input_active else INPUT_BOX_COLOR
        pygame.draw.rect(self.screen, color, self.input_rect, border_radius=8)
        pygame.draw.rect(self.screen, HEADER_COLOR,
                         self.input_rect, 2, border_radius=8)

        # 绘制输入文本
        input_surface = FONT.render(self.input_text, True, TEXT_COLOR)
        # 如果文本太长，缩小字体
        if input_surface.get_width() > self.input_rect.width - 20:
            smaller_font = pygame.font.Font(None, 28)
            input_surface = smaller_font.render(
                self.input_text, True, TEXT_COLOR)
        self.screen.blit(input_surface, (self.input_rect.x +
                         12, self.input_rect.y + 10))

        # 绘制单位标签
        from_label = SMALL_FONT.render("从:", True, TEXT_COLOR)
        to_label = SMALL_FONT.render("到:", True, TEXT_COLOR)
        self.screen.blit(from_label, (right_area_x, 160))
        self.screen.blit(to_label, (right_area_x, 250))

        # 绘制下拉菜单
        self.draw_dropdown(self.from_dropdown_rect, self.from_unit,
                           self.show_from_dropdown, self.from_scroll, True)
        self.draw_dropdown(self.to_dropdown_rect, self.to_unit,
                           self.show_to_dropdown, self.to_scroll, False)

        # 绘制转换按钮
        mouse_pos = pygame.mouse.get_pos()
        btn_color = BUTTON_HOVER_COLOR if self.convert_button.collidepoint(
            mouse_pos) else BUTTON_COLOR
        pygame.draw.rect(self.screen, btn_color,
                         self.convert_button, border_radius=12)
        pygame.draw.rect(self.screen, (255, 255, 255),
                         self.convert_button, 2, border_radius=12)
        convert_text = FONT.render("转 换", True, (255, 255, 255))
        convert_rect = convert_text.get_rect(center=self.convert_button.center)
        self.screen.blit(convert_text, convert_rect)

        # 绘制清空按钮
        clear_color = (180, 180, 200) if self.clear_button.collidepoint(
            mouse_pos) else (160, 160, 180)
        pygame.draw.rect(self.screen, clear_color,
                         self.clear_button, border_radius=10)
        pygame.draw.rect(self.screen, HEADER_COLOR,
                         self.clear_button, 1, border_radius=10)
        clear_text = SMALL_FONT.render("清 空", True, TEXT_COLOR)
        clear_rect = clear_text.get_rect(center=self.clear_button.center)
        self.screen.blit(clear_text, clear_rect)

        # 显示结果
        result_y = WINDOW_HEIGHT - 60
        if self.result is not None:
            # 获取单位符号
            from_symbol = self.from_unit.split(
                " (")[1][:-1] if " (" in self.from_unit else self.from_unit
            to_symbol = self.to_unit.split(
                " (")[1][:-1] if " (" in self.to_unit else self.to_unit

            result_text = FONT.render(f"{self.input_text} {from_symbol} = {self.result} {to_symbol}",
                                      True, TEXT_COLOR)
            result_bg = pygame.Rect(40, result_y - 12, WINDOW_WIDTH - 80, 50)
            pygame.draw.rect(self.screen, RESULT_BG_COLOR,
                             result_bg, border_radius=10)
            pygame.draw.rect(self.screen, HEADER_COLOR,
                             result_bg, 1, border_radius=10)
            result_rect = result_text.get_rect(
                center=(WINDOW_WIDTH // 2, result_y + 13))
            self.screen.blit(result_text, result_rect)

        elif self.error_message is not None:
            error_text = SMALL_FONT.render(
                self.error_message, True, (220, 80, 80))
            error_rect = error_text.get_rect(
                center=(WINDOW_WIDTH // 2, result_y + 13))
            self.screen.blit(error_text, error_rect)

        pygame.display.flip()

    def run(self):
        """主循环"""
        while self.running:
            self.handle_events()
            self.draw()
            self.clock.tick(60)

        pygame.quit()
        sys.exit()


if __name__ == "__main__":
    converter = WeightConverter()
    converter.run()
