import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from PIL import Image, ImageDraw, ImageFont
import os

class StudentIDApp:
    def __init__(self, root):
        self.root = root
        self.root.title("009. 学生证件生成器")
        self.root.geometry("420x550")
        self.root.resizable(False, False)

        self.photo_path = None
        self.preview_window = None

        self.setup_ui()

    def setup_ui(self):
        title = tk.Label(
            self.root,
            text="🪪 学生证件生成器",
            font=("微软雅黑", 18, "bold"),
            pady=10
        )
        title.pack()

        frame = tk.Frame(self.root)
        frame.pack(pady=10, padx=30, fill=tk.X)

        # ===== 表单 =====
        fields = [
            ("姓名：", "entry_name"),
            ("学号：", "entry_id"),
        ]

        self.entry_name = self.make_entry(frame, "姓名：", 0)
        self.entry_id = self.make_entry(frame, "学号：", 1)

        # 性别
        tk.Label(frame, text="性别：").grid(row=2, column=0, sticky="e", pady=6)
        self.gender = ttk.Combobox(frame, width=17, state="readonly")
        self.gender['values'] = ("男", "女")
        self.gender.current(0)
        self.gender.grid(row=2, column=1, pady=6)

        # 院系
        tk.Label(frame, text="院系：").grid(row=3, column=0, sticky="e", pady=6)
        self.dept = ttk.Combobox(frame, width=17, state="readonly")
        self.dept['values'] = (
            "计算机科学与技术",
            "软件工程",
            "电子信息工程",
            "通信工程",
            "数学与应用数学"
        )
        self.dept.current(0)
        self.dept.grid(row=3, column=1, pady=6)

        # ===== 照片选择 =====
        photo_frame = tk.Frame(self.root)
        photo_frame.pack(pady=10)

        self.photo_label = tk.Label(
            photo_frame,
            text="未选择照片",
            width=30,
            relief=tk.SUNKEN,
            padx=5,
            pady=5
        )
        self.photo_label.pack(side=tk.LEFT, padx=5)

        tk.Button(
            photo_frame,
            text="选择照片",
            command=self.choose_photo
        ).pack(side=tk.LEFT, padx=5)

        # ===== 按钮 =====
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=20)

        tk.Button(
            btn_frame, text="生成证件",
            bg="#4CAF50", fg="white",
            font=("微软雅黑", 12),
            width=14, height=2,
            command=self.generate_id
        ).pack(side=tk.LEFT, padx=10)

        tk.Button(
            btn_frame, text="退出",
            bg="#f44336", fg="white",
            font=("微软雅黑", 12),
            width=14, height=2,
            command=self.root.quit
        ).pack(side=tk.LEFT, padx=10)

    def make_entry(self, parent, label, row):
        tk.Label(parent, text=label).grid(row=row, column=0, sticky="e", pady=6)
        entry = tk.Entry(parent, width=20)
        entry.grid(row=row, column=1, pady=6)
        return entry

    def choose_photo(self):
        path = filedialog.askopenfilename(
            title="选择学生照片",
            filetypes=[
                ("图片文件", "*.jpg *.jpeg *.png *.bmp"),
                ("所有文件", "*.*")
            ]
        )
        if path:
            self.photo_path = path
            self.photo_label.config(text=os.path.basename(path))

    def generate_id(self):
        name = self.entry_name.get().strip()
        sid = self.entry_id.get().strip()

        if not name or not sid:
            messagebox.showwarning("提示", "请填写姓名和学号！")
            return

        # ===== 创建证件图片 =====
        img_w, img_h = 320, 210
        img = Image.new("RGB", (img_w, img_h), "#1a237e")
        draw = ImageDraw.Draw(img)

        # 顶部标题
        try:
            title_font = ImageFont.truetype("msyh.ttc", 22)
            info_font = ImageFont.truetype("msyh.ttc", 14)
        except:
            title_font = ImageFont.load_default()
            info_font = ImageFont.load_default()

        # 蓝色背景上的白色文字
        draw.text((img_w // 2, 15), "学 生 证", fill="white", font=title_font, anchor="mt")
        draw.line([(20, 50), (img_w - 20, 50)], fill="white", width=2)

        # 照片区域
        photo_x = 210
        photo_y = 65
        photo_w, photo_h = 90, 110

        if self.photo_path:
            try:
                photo = Image.open(self.photo_path).resize((photo_w, photo_h))
                img.paste(photo, (photo_x, photo_y))
            except:
                draw.rectangle(
                    [photo_x, photo_y, photo_x + photo_w, photo_y + photo_h],
                    outline="white", width=2
                )
                draw.text((photo_x + 20, photo_y + 40), "照片", fill="white", font=info_font)
        else:
            draw.rectangle(
                [photo_x, photo_y, photo_x + photo_w, photo_y + photo_h],
                outline="white", width=2
            )
            draw.text((photo_x + 20, photo_y + 40), "照片", fill="white", font=info_font)

        # 信息文字
        info_x = 25
        info_start_y = 65
        line_h = 28

        draw.text((info_x, info_start_y), f"姓  名：{name}", fill="white", font=info_font)
        draw.text((info_x, info_start_y + line_h), f"学  号：{sid}", fill="white", font=info_font)
        draw.text((info_x, info_start_y + line_h * 2), f"性  别：{self.gender.get()}", fill="white", font=info_font)
        draw.text((info_x, info_start_y + line_h * 3), f"院  系：{self.dept.get()}", fill="white", font=info_font)

        # 底部
        draw.line([(20, 185), (img_w - 20, 185)], fill="white", width=1)
        draw.text((img_w // 2, 192), "— 请妥善保管 —", fill="#bbbbbb", font=info_font, anchor="mt")

        # ===== 保存 =====
        save_path = f"学生证件_{sid}.png"
        img.save(save_path)

        # ===== 弹出预览窗口 =====
        if self.preview_window:
            self.preview_window.destroy()

        self.preview_window = tk.Toplevel(self.root)
        self.preview_window.title(f"证件预览 - {name}")
        self.preview_window.resizable(False, False)

        # 显示预览
        display_img = img.resize((480, 315), Image.LANCZOS)
        photo_tk = ImageTk.PhotoImage(display_img)

        label = tk.Label(self.preview_window, image=photo_tk)
        label.image = photo_tk
        label.pack(padx=10, pady=10)

        tk.Label(
            self.preview_window,
            text=f"已保存到：{save_path}",
            font=("微软雅黑", 10),
            fg="green"
        ).pack(pady=5)

        tk.Button(
            self.preview_window,
            text="关闭预览",
            command=self.preview_window.destroy
        ).pack(pady=5)

        messagebox.showinfo("成功", f"学生证件已生成并保存为：\n{save_path}")


if __name__ == "__main__":
    root = tk.Tk()
    app = StudentIDApp(root)
    root.mainloop()