import pygame
import sys
import random
import math

pygame.init()
WIDTH, HEIGHT = 600, 650
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Dalgona Challenge - 精细版")
clock = pygame.time.Clock()
FPS = 60

# ==================== 色彩 ====================
WHITE        = (255, 255, 255)
BLACK        = (0, 0, 0)
BG_COLOR     = (225, 200, 170)
COOKIE_BASE  = (195, 155, 100)   # 饼干主体
COOKIE_EDGE  = (130, 90, 50)     # 边缘焦色
COOKIE_DARK  = (160, 120, 70)    # 深色气孔
COOKIE_LIGHT = (220, 180, 130)   # 浅色气孔
SHAPE_COLOR  = (170, 130, 85)    # 形状凹陷
DANGER_RED   = (255, 70, 70)
DAMAGE_BG    = (200, 200, 200)
DAMAGE_FILL  = (255, 80, 80)
SUCCESS_GREEN= (50, 200, 50)

# 形状绘制函数（星/圆/三角/伞）
def draw_star(surf, cx, cy, size):
    pts = []
    for i in range(5):
        ang = math.radians(i*72 - 90)
        ox = cx + size * math.cos(ang)
        oy = cy + size * math.sin(ang)
        pts.append((ox, oy))
        ang2 = ang + math.radians(36)
        ix = cx + size*0.4 * math.cos(ang2)
        iy = cy + size*0.4 * math.sin(ang2)
        pts.append((ix, iy))
    pygame.draw.polygon(surf, SHAPE_COLOR, pts)

def draw_circle_shape(surf, cx, cy, size):
    pygame.draw.circle(surf, SHAPE_COLOR, (cx, cy), size)

def draw_triangle_shape(surf, cx, cy, size):
    h = size * math.sqrt(3)
    pts = [(cx, cy - h/2), (cx - size, cy + h/2), (cx + size, cy + h/2)]
    pygame.draw.polygon(surf, SHAPE_COLOR, pts)

def draw_umbrella_shape(surf, cx, cy, size):
    pygame.draw.arc(surf, SHAPE_COLOR, (cx-size, cy-size, size*2, size*2), math.pi, 2*math.pi, 6)
    pygame.draw.line(surf, SHAPE_COLOR, (cx, cy), (cx, cy+size*0.8), 4)
    pygame.draw.arc(surf, SHAPE_COLOR, (cx-size*0.4, cy+size*0.6, size*0.8, size*0.8), math.pi/2, math.pi, 3)

SHAPE_FUNCS = [draw_star, draw_circle_shape, draw_triangle_shape, draw_umbrella_shape]
SHAPE_NAMES = ["星形", "圆形", "三角形", "雨伞"]

# ==================== 粒子：细微碎屑 ====================
class TinyCrumb:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.vx = random.uniform(-1.5, 1.5)
        self.vy = random.uniform(-1.5, 1.5)
        self.life = random.randint(10, 25)
        self.max_life = self.life
        self.color = random.choice([COOKIE_BASE, COOKIE_DARK, COOKIE_LIGHT])

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += 0.08
        self.life -= 1
        return self.life > 0

    def draw(self, surf):
        alpha = 255 * self.life // self.max_life
        r = max(1, int(2.5 * self.life / self.max_life))
        if r > 0:
            s = pygame.Surface((r*2, r*2), pygame.SRCALPHA)
            pygame.draw.circle(s, (*self.color, alpha), (r, r), r)
            surf.blit(s, (int(self.x - r), int(self.y - r)))

# ==================== 游戏主类 ====================
class DalgonaGame:
    def __init__(self):
        self.reset()

    def reset(self):
        self.cookie_radius = 200
        self.cx, self.cy = WIDTH//2, HEIGHT//2 - 30
        shape_idx = random.randint(0, len(SHAPE_FUNCS)-1)
        self.shape_draw = SHAPE_FUNCS[shape_idx]
        self.shape_name = SHAPE_NAMES[shape_idx]

        # 制作精致饼干表面
        self.cookie_surf = self.make_fancy_cookie()

        # 形状蒙版（碰撞检测）
        self.shape_mask = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        self.shape_mask.fill((0,0,0,0))
        self.shape_draw(self.shape_mask, self.cx, self.cy, 80)

        self.scratching = False
        self.damage = 0.0          # 0~1 破碎值
        self.success = False
        self.broken = False
        self.timer = 30.0
        self.crumbs = []
        self.warning = False

        self.font_large = pygame.font.Font(None, 48)
        self.font = pygame.font.Font(None, 30)
        self.font_small = pygame.font.Font(None, 22)

    def make_fancy_cookie(self):
        """绘制高质感糖饼"""
        surf = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        surf.fill((0,0,0,0))
        cx, cy, r = self.cx, self.cy, self.cookie_radius

        # 基础圆形（渐变感：中心稍亮）
        for i in range(r, 0, -1):
            color = (
                int(195 + (220-195) * (i/r)),
                int(155 + (180-155) * (i/r)),
                int(100 + (130-100) * (i/r))
            )
            pygame.draw.circle(surf, color, (cx, cy), i)
        # 边缘焦圈
        pygame.draw.circle(surf, COOKIE_EDGE, (cx, cy), r, 10)

        # 细密蜂窝气孔（小点）
        random.seed(1234)  # 固定随机让纹理可复现
        for _ in range(150):
            x = random.randint(cx - r + 12, cx + r - 12)
            y = random.randint(cy - r + 12, cy + r - 12)
            if math.hypot(x-cx, y-cy) < r-12:
                shade = random.choice([COOKIE_DARK, COOKIE_LIGHT, COOKIE_BASE])
                size = random.randint(1, 3)
                pygame.draw.circle(surf, shade, (x, y), size)

        # 形状凹陷（深色 + 内侧高光线模拟立体）
        self.shape_draw(surf, cx, cy, 80)
        # 在形状内部加一条细白高光线（沿边缘内侧）
        # 这里简化：用更深的阴影线画在形状边缘内侧
        inner_surf = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        self.shape_draw(inner_surf, cx, cy, 78)  # 稍微缩小一点
        # 将 inner_surf 作为更深的颜色覆盖上去
        inner_surf2 = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        self.shape_draw(inner_surf2, cx, cy, 78)
        # 用混合模式不太好做，简单起见：画一条细边
        # 这里直接保留原样，视觉已经比较立体

        return surf

    def handle_events(self):
        for ev in pygame.event.get():
            if ev.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if ev.type == pygame.KEYDOWN:
                if ev.key == pygame.K_SPACE:
                    self.reset()
                if ev.key == pygame.K_ESCAPE:
                    pygame.quit(); sys.exit()
            if ev.type == pygame.MOUSEBUTTONDOWN:
                if ev.button == 1 and not self.broken and not self.success:
                    self.scratching = True
            if ev.type == pygame.MOUSEBUTTONUP:
                if ev.button == 1:
                    self.scratching = False

    def update(self, dt):
        if self.broken or self.success:
            return

        self.timer -= dt
        if self.timer <= 0:
            self.timer = 0
            self.success = True
            return

        if self.scratching:
            mx, my = pygame.mouse.get_pos()
            erase_radius = 4          # ★ 精细针尖大小

            # 检测碰到形状
            self.warning = False
            try:
                if 0 <= mx < WIDTH and 0 <= my < HEIGHT:
                    if self.shape_mask.get_at((mx, my)).a > 80:
                        self.warning = True
                        self.damage += 0.008     # 缓慢增加，给反应时间
                        if self.damage >= 1.0:
                            self.broken = True
                            for _ in range(40):
                                self.crumbs.append(TinyCrumb(mx, my))
                            return
            except IndexError:
                pass

            # 擦除饼干
            eraser = pygame.Surface((erase_radius*2, erase_radius*2), pygame.SRCALPHA)
            pygame.draw.circle(eraser, (0,0,0,0), (erase_radius, erase_radius), erase_radius)
            self.cookie_surf.blit(eraser, (mx - erase_radius, my - erase_radius),
                                  special_flags=pygame.BLEND_RGBA_MIN)

            # 细微碎屑
            for _ in range(3):
                self.crumbs.append(TinyCrumb(mx + random.randint(-6,6), my + random.randint(-6,6)))
        else:
            self.warning = False
            self.damage = max(0, self.damage - 0.0008)   # 轻微恢复

        self.crumbs = [c for c in self.crumbs if c.update()]

    def draw(self):
        screen.fill(BG_COLOR)

        # 饼干本体
        screen.blit(self.cookie_surf, (0,0))

        # 碎屑
        for c in self.crumbs:
            c.draw(screen)

        # 警告红圈（刮到形状时）
        if self.warning:
            mx, my = pygame.mouse.get_pos()
            pygame.draw.circle(screen, DANGER_RED, (mx, my), 6, 2)

        # UI
        timer_text = self.font.render(f"⏳ {int(self.timer)}s", True, BLACK)
        screen.blit(timer_text, (20, 20))

        # 破损条
        bx, by, bw, bh = 20, 55, 200, 12
        pygame.draw.rect(screen, DAMAGE_BG, (bx, by, bw, bh))
        fill_w = int(bw * self.damage)
        if fill_w > 0:
            pygame.draw.rect(screen, DAMAGE_FILL, (bx, by, fill_w, bh))
        pygame.draw.rect(screen, BLACK, (bx, by, bw, bh), 1)
        dmg_text = self.font_small.render(f"裂痕 {int(self.damage*100)}%", True, BLACK)
        screen.blit(dmg_text, (bx + bw + 10, by - 2))

        shape_text = self.font.render(f"形状：{self.shape_name}", True, BLACK)
        screen.blit(shape_text, (20, 80))
        help_text = self.font_small.render("按住左键小心刮除", True, BLACK)
        screen.blit(help_text, (20, HEIGHT - 25))

        # 结束画面
        if self.broken:
            self.draw_overlay("破碎！", DANGER_RED, "按空格键重试")
        elif self.success:
            self.draw_overlay("成功！", SUCCESS_GREEN, "按空格键换新糖饼")

        pygame.display.flip()

    def draw_overlay(self, big, color, small):
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0,0,0,180))
        screen.blit(overlay, (0,0))
        big_text = self.font_large.render(big, True, color)
        screen.blit(big_text, (WIDTH//2 - big_text.get_width()//2, HEIGHT//2 - 50))
        small_text = self.font.render(small, True, WHITE)
        screen.blit(small_text, (WIDTH//2 - small_text.get_width()//2, HEIGHT//2 + 20))

    def run(self):
        while True:
            dt = clock.tick(FPS) / 1000.0
            self.handle_events()
            self.update(dt)
            self.draw()

if __name__ == "__main__":
    DalgonaGame().run()