import os
import turtle
import json
import re
import zipfile
import requests
from PIL import Image
from io import BytesIO
import time


# U1-02 Story GPT----------------------------------科大讯飞（暂时不用）
'''
def story(role, time, address, event, key=""):
    content = role+time+address+event
    url = "https://spark-api-open.xf-yun.com/v1/chat/completions"
    data = {
        "max_tokens": 650,     # 回复长度限制
        "top_k": 4,             # 灵活度
        "temperature": 0.5,     # 随机性
        "messages": [
            {
                # 设置对话背景或赋予模型角色，该设定会贯穿整轮对话，对全局的模型生成结果产生影响。对应作为'role'为'system'时，'content'的值
                "role": "system",
                "content": "我是一个非常会写童话的儿童写作作家,根据我写出的关键词，帮我生成一篇童话故事。（注意：故事必须完整，不能中断，语句必须完整，不准出现断句。）"
            },
            {
                # 对大模型发出的具体指令，用于描述需要大模型完成的目标任务和需求说明。会与角色设定中的内容拼接，共同作为'role'为'system'时，'content'的值
                "role": "user",
                "content": content
            }
        ],
        "model": "4.0Ultra"
    }
    data["stream"] = True
    if key == "":
        print("没有秘钥！请提供秘钥！")
        return "没有秘钥！请提供秘钥！"
    elif key != "CaJQ":
        print("秘钥错误！请重新输入！")
        return "秘钥错误！请重新输入！"
    header = {
        "Authorization": "Bearer HcRhgbaQtGJfoaZTIvEB:MPWLZAgQnKWHKUypRYRQ"
    }
    response = requests.post(url, headers=header, json=data, stream=True)

    # 流式响应解析示例
    response.encoding = "utf-8"
    contents = ""
    result = response.iter_lines(decode_unicode="utf-8")
    result = str(list(result))

    # 正则表达式模式
    pattern = r'"content":"(.*?)"'

    # 使用re.findall查找所有匹配的内容
    contents = re.findall(pattern, result, re.DOTALL)
    s = ""
    for i in contents:
        s += i
    s = s.replace('\\', "")
    s = s.replace("n", "")
    return s
'''


def story(role, time, address, event, key=""):
    if key == "":
        print("没有秘钥！请提供秘钥！")
        return "没有秘钥！请提供秘钥！"
    elif key != "CaJQ":
        print("秘钥错误！请重新输入！")
        return "秘钥错误！请重新输入！"
    content = role+time+address+event
    url = "https://qianfan.baidubce.com/v2/chat/completions"
    payload = json.dumps({
        "model": "ernie-5.0-thinking-preview",
        "messages": [
            {
                "role": "system",
                "content": "我是一个非常会写童话的儿童写作作家,根据我写出的关键词，帮我生成一篇童话故事。（注意：故事必须完整，不能中断，语句必须完整，不准出现断句，字数在600字以内。）"
            },
            {
                   # 对大模型发出的具体指令，用于描述需要大模型完成的目标任务和需求说明。会与角色设定中的内容拼接，共同作为'role'为'system'时，'content'的值
                "role": "user",
                "content": content
            }
        ],
        "fps": 8,
        "web_search": {
            "enable": False
        }
    }, ensure_ascii=False)
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer bce-v3/ALTAK-cGbxpVA5AbSz6h8nbLaFh/b539762075d55c76d93dc78bcf0a91beeaf0490a'
    }
    
    response = requests.request("POST", url, headers=headers, data=payload.encode("utf-8"))
    response.encoding = "utf-8"
    response_data = json.loads(response.text)
    con = response_data["choices"][0]["message"]["content"]
    con = con.replace("\n", "")
    while " " in content:
        con = content.replace(" ", "")
    return con
# -------------------------------------------------


# U1-06 我说你画-----------------------------------
def photo(content, style, size, key=""):
    # 图像生成的 API URL
    if key == "":
        print("没有秘钥！请提供秘钥！")
        return "没有秘钥！请提供秘钥！"
    elif key != "CaJQ":
        print("秘钥错误！请重新输入！")
        return "秘钥错误！请重新输入！"
    key = "image"
    url = "https://gateway.xiaomawang.com/pythonUILibApi/api/text2" + key

    # 请求的头部
    headers = {
        "Content-Type": "application/json"
    }
    resolution = {"1024*1024": 3, "1280*720": 4, "720*1280": 5}
    if content == "":
        return
    if style == "":
        style = "默认"
    if size == "":
        size = "1024*1024"

    # 请求的主体内容
    data = {
        'prompt': content,  # 你想要生成的图像描述
        'imgStyle': style,
        'imgSize': resolution[size]  # 图像的尺寸
    }

    # 发送 POST 请求
    response = requests.post(url, headers=headers, json=data)

    # 检查请求是否成功
    if response.status_code == 200:
        response_data = response.json()
        _data = eval(str(response_data))
        photo_url = _data["data"][0]["url"]

    skin = requests.get(photo_url).content
    with open("{}.png".format(content), 'wb') as s:
        s.write(skin)
# ------------------------------------------------


# U1-11 百变助手----------------------------------
def reply(role, content, key=""):
    url = "https://spark-api-open.xf-yun.com/v1/chat/completions"
    data = {
        "max_tokens": 60,     # 回复长度限制
        "top_k": 5,             # 灵活度
        "temperature": 0.6,     # 随机性
        "messages": [
            {
                # 设置对话背景或赋予模型角色，该设定会贯穿整轮对话，对全局的模型生成结果产生影响。对应作为'role'为'system'时，'content'的值
                "role": "system",
                "content": "你是一位非常优秀的" + role + "，请根据我的提问，非常科学、有趣和严谨的回答我。"
            },
            {
                # 对大模型发出的具体指令，用于描述需要大模型完成的目标任务和需求说明。会与角色设定中的内容拼接，共同作为'role'为'system'时，'content'的值
                "role": "user",
                "content": content + "(一定要80个字左右，语句必须完整，语句必须完整，不准出现断句。)"
            }
        ],
        "model": "4.0Ultra"
    }
    data["stream"] = True
    if key == "":
        print("没有秘钥！请提供秘钥！")
        return "没有秘钥！请提供秘钥！"
    elif key != "CaJQ":
        print("秘钥错误！请重新输入！")
        return "秘钥错误！请重新输入！"
    header = {
        "Authorization": "Bearer HcRhgbaQtGJfoaZTIvEB:MPWLZAgQnKWHKUypRYRQ"
    }
    response = requests.post(url, headers=header, json=data, stream=True)

    # 流式响应解析示例
    response.encoding = "utf-8"
    contents = ""
    result = response.iter_lines(decode_unicode="utf-8")
    result = str(list(result))

    # 正则表达式模式
    pattern = r'"content":"(.*?)"'

    # 使用re.findall查找所有匹配的内容
    contents = re.findall(pattern, result, re.DOTALL)
    s = "   "
    for i in contents:
        s += i
    if '\\' in s:
        s = s.replace('\\', "")
    if '*' in s:
        s = s.replace('*', "")
    sum_ = """"""
    for i in range(0, len(s), 17):
        sum_ = sum_ + s[i:i+17] + "\n"
    return sum_
# ------------------------------------------------


# U2-05 码字成诗----------------------------------
def poem(title, key=""):
    if key == "":
        print("没有秘钥！请提供秘钥！")
        return "没有秘钥！请提供秘钥！"
    elif key != "CaJQ":
        print("秘钥错误！请重新输入！")
        return "秘钥错误！请重新输入！"
    messagesList = [
        {
            "role": "system",
            "content": "唐代诗人"
        },
        {
            "role": "user",
            "content": f"请以《{title}》为题，创作一首七言绝句，每句7个字，一共4句，符合古诗韵律规范，内容积极乐观向上，适合中小学生阅读，不要解析，不要题目，不要标点符号，所有文字放在一行"
        }
    ]

    url = "https://qianfan.baidubce.com/v2/chat/completions"

    payload = json.dumps({
        "model": "ernie-4.5-turbo-32k",
        "messages": messagesList
    }, ensure_ascii=False)
    headers = {
        'Content-Type': 'application/json',
        'appid': '',
        'Authorization': 'Bearer bce-v3/ALTAK-cGbxpVA5AbSz6h8nbLaFh/b539762075d55c76d93dc78bcf0a91beeaf0490a'
    }

    response = requests.request(
        "POST", url, headers=headers, data=payload.encode("utf-8"))

    response_data = json.loads(response.text)
    content = response_data["choices"][0]["message"]["content"]
    content = content.replace("\n", "")
    while " " in content:
        content = content.replace(" ", "")
    return content
# ------------------------------------------------


# U2-06 凯撒加密----------------------------------
def crack(name, pwd):
    try:
        zFile = zipfile.ZipFile(name + ".zip")
        zFile.extractall(pwd=str(pwd).encode())
        print("已成功破解密码")
        os.system("Treasuremap.png")
    except:
        print("密码错误")
# ------------------------------------------------


# U3-06 码怪图鉴----------------------------------
# 全局变量，用于保存 turtle 对象
t = None
t1 = None
sc = None


def init_screen():
    global sc, t, t1
    try:
        # 初始化屏幕
        sc = turtle.Screen()
        sc.setup(618, 795)
        turtle.tracer(0)
        turtle.colormode(255)
        # 初始化 turtle 对象
        t = turtle.Turtle()
        t.penup()
        t1 = turtle.Turtle()
        t1.color("white")
        t1.penup()
        t1.hideturtle()
    except Exception as e:
        print(f"初始化屏幕失败: {e}")
        raise


def show(name, zd):
    global sc, t, t1
    try:
        if sc is None:
            init_screen()
        # 隐藏之前的元素
        t.hideturtle()
        t1.clear()
        # 设置新的图片和文字
        pic = name + ".gif"
        sc.bgpic("背景.png")
        turtle.addshape(pic)
        t.goto(0, 100)
        t.shape(pic)
        t.showturtle()
        t1.goto(0, -260)
        t1.write(name, font=("STCaiyun", 30, "bold"), align="center")
        t1.goto(0, -320)
        t1.write("战力：" + str(zd), font=("STCaiyun", 30), align="center")
        sc.update()
    except turtle.Terminator:
        print("Turtle 环境已关闭，尝试重新初始化...")
        # 重置全局变量并重新初始化
        reset_environment()
        show(name, zd)
    except FileNotFoundError:
        print(f"找不到图片文件: {pic}")
    except Exception as e:
        print(f"展示码怪失败: {e}")
    except:
        print("图片加载失败")


def reset_environment():
    """重置 turtle 环境"""
    global sc, t, t1
    try:
        if sc:
            sc.bye()
    except:
        pass
    sc = None
    t = None
    t1 = None


def close_environment():
    """安全关闭 turtle 环境"""
    global sc
    try:
        if sc:
            sc.bye()
            sc = None
    except Exception as e:
        print(f"关闭环境失败: {e}")
# ------------------------------------------------


# U4-08 故事绘本----------------------------------
API_KEY = "YleMT041wl8zkXhk1Y4AdEuk"
SECRET_KEY = "xQousjKEqphGwVMKHJlUSGDXp7PiUVpk"

# ================= 全局变量占位 =================
# 将画笔初始化为 None，在需要时再创建
_progress_pen = None
_text_pen = None

# ================= 内部初始化函数 (新增封装) =================
def _init_turtle_engine():
    """
    内部单例初始化函数：确保 Turtle 引擎只被配置一次
    """
    global _progress_pen, _text_pen
    
    # 防止重复创建（单例模式）
    if _progress_pen is None:
        _progress_pen = turtle.Turtle()
        _progress_pen.hideturtle()
        _progress_pen.speed(0)
        
    if _text_pen is None:
        _text_pen = turtle.Turtle()
        _text_pen.hideturtle()
        
    # 设置色彩模式
    try:
        turtle.colormode(255)
    except turtle.Terminator:
        pass # 防止在某些异常退出情况下报错

# ================= 内部辅助函数 =================

def _get_access_token():
    """内部函数：获取百度API访问令牌"""
    url = "https://aip.baidubce.com/oauth/2.0/token"
    params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
    try:
        response = requests.post(url, params=params)
        return str(response.json().get("access_token"))
    except Exception as e:
        print(f"Token获取失败: {e}")
        return ""

def _draw_progress_bar(current, total, status_text=""):
    """内部函数：绘制进度条"""
    # 直接使用全局变量 _progress_pen
    
    _progress_pen.clear()
    bar_width = 400
    bar_height = 20
    start_x, start_y = -200, -280 
    
    # 1. 绘制进度条外框
    _progress_pen.penup()
    _progress_pen.goto(start_x, start_y)
    _progress_pen.pendown()
    _progress_pen.pensize(2)
    _progress_pen.color("black")
    for _ in range(2):
        _progress_pen.forward(bar_width)
        _progress_pen.left(90)
        _progress_pen.forward(bar_height)
        _progress_pen.left(90)
    
    # 2. 填充进度
    if current > 0:
        _progress_pen.penup()
        _progress_pen.goto(start_x, start_y)
        _progress_pen.begin_fill()
        _progress_pen.color("#4CAF50")  # 绿色
        fill_width = (current / total) * bar_width
        for _ in range(2):
            _progress_pen.forward(fill_width)
            _progress_pen.left(90)
            _progress_pen.forward(bar_height)
            _progress_pen.left(90)
        _progress_pen.end_fill()
    
    # 3. 绘制文字信息
    _progress_pen.penup()
    _progress_pen.goto(0, start_y + 25)
    _progress_pen.color("black")
    percentage = int((current / total) * 100)
    display_msg = status_text if status_text else f"总进度: {percentage}% ({current}/{total})"
    _progress_pen.write(display_msg, align="center", font=("字魂龙乐体.ttf", 12, "bold"))
    
    turtle.update()

def _draw_text_box():
    """内部函数：绘制文本背景框"""
    _text_pen.clear()
    _text_pen.penup()
    _text_pen.goto(-400, -350)
    _text_pen.color((196,200,202))
    _text_pen.begin_fill()
    for _ in range(2):
        _text_pen.forward(800)
        _text_pen.left(90)
        _text_pen.forward(100)
        _text_pen.left(90)
    _text_pen.end_fill()

# ================= 核心功能函数 (对外暴露) =================

def show_text(text_content):
    """
    在屏幕下方显示文字描述
    """
    # 自动检查并初始化 Turtle 引擎
    _init_turtle_engine()
    
    _draw_text_box()
    _text_pen.pencolor("black")
    clean_text = text_content.strip()
    lines = [clean_text[i:i+30] for i in range(0, len(clean_text), 30)]
    
    for i, line in enumerate(lines):
        _text_pen.penup()
        y_pos = -280 - i * 30
        _text_pen.goto(-300, y_pos)
        _text_pen.write(line, font=("字魂龙乐体.ttf", 14, "bold"))

def pic(cnt, words, total):
    """
    调用API生成图片并保存，同时更新UI进度
    """
    # 自动检查并初始化 Turtle 引擎
    _init_turtle_engine()
    
    # 初始状态提示
    _draw_progress_bar(cnt, total, f"正在请求第 {cnt+1} 张图片绘制...")
    
    access_token = _get_access_token()
    if not access_token:
        return

    # 1. 发送绘图请求
    url = f"https://aip.baidubce.com/rpc/2.0/wenxin/v1/extreme/textToImage?access_token={access_token}"
    payload = json.dumps({
        "prompt": "风格：卡通漫画" + words,
        "width": 1024,
        "height": 1024
    })
    headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
    
    try:
        response = requests.post(url, headers=headers, data=payload)
        resp_json = response.json()
        if "data" not in resp_json:
            print(f"API响应错误: {resp_json}")
            return
        task_id = resp_json["data"]["task_id"]
    except Exception as e:
        print(f"请求发起失败: {e}")
        return

    # 2. 轮询查询结果
    query_url = f"https://aip.baidubce.com/rpc/2.0/wenxin/v1/extreme/getImg?access_token={access_token}"
    query_payload = json.dumps({"task_id": task_id})
    
    while True:
        _draw_progress_bar(cnt, total, f"AI 正在绘制第 {cnt+1} 张，请耐心稍候...")
        
        try:
            response = requests.post(query_url, headers=headers, data=query_payload)
            res_data = response.json().get("data", {})
            task_status = res_data.get("task_status")
            
            if task_status == "SUCCESS":
                image_url = res_data["sub_task_result_list"][0]["final_image_list"][0]["img_url"]
                img_res = requests.get(image_url)
                
                image = Image.open(BytesIO(img_res.content))
                filename = f'{cnt}.png'
                image.save(filename)
                
                img_thumb = Image.open(filename)
                img_thumb.thumbnail((800, 800))
                img_thumb.save(filename)
                
                _draw_progress_bar(cnt + 1, total) 
                
                if cnt + 1 == total:
                    time.sleep(1)
                    _progress_pen.clear()
                break
                
            elif task_status == "FAILED":
                print(f"第 {cnt+1} 张生成失败")
                break
            else:
                time.sleep(8)
                
        except Exception as e:
            print(f"轮询查询异常: {e}")
            break
# ------------------------------------------------
