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

class StudentIDGenerator:
    def __init__(self, root):
        self.root = root
        self.root.title("学生证件生成系统")
        self.root.geometry("900x700")
        self.root.configure(bg='#f0f8ff')
        
        # 设置字体
        self.title_font = ("微软雅黑", 20, "bold")
        self.label_font = ("微软雅黑", 12)
        self.button_font = ("微软雅黑", 11)
        
        # 初始化变量
        self.photo_path = None
        self.student_photo = None
        
        # 创建界面
        self.create_widgets()
        
    def create_widgets(self):
        # 标题
        title_label = tk.Label(
            self.root, 
            text="学生证件生成系统", 
            font=self.title_font, 
            bg='#4682b4', 
            fg='white',
            pady=10
        )
        title_label.pack(fill=tk.X)
        
        # 主框架
        main_frame = tk.Frame(self.root, bg='#f0f8ff')
        main_frame.pack(pady=20, padx=20, fill=tk.BOTH, expand=True)
        
        # 左侧信息输入区域
        input_frame = tk.LabelFrame(
            main_frame, 
            text="学生信息录入", 
            font=self.label_font,
            bg='#f0f8ff',
            relief=tk.GROOVE
        )
        input_frame.pack(side=tk.LEFT, fill=tk.BOTH, padx=(0, 10), expand=True)
        
        # 学生信息输入字段
        fields = [
            ("学号:", "entry_stu_id"),
            ("姓名:", "entry_name"),
            ("性别:", "entry_gender"),
            ("学院:", "entry_college"),
            ("专业:", "entry_major"),
            ("班级:", "entry_class"),
            ("入学时间:", "entry_enroll_date")
        ]
        
        self.entries = {}
        
        for i, (label_text, key) in enumerate(fields):
            # 标签
            tk.Label(
                input_frame, 
                text=label_text, 
                font=self.label_font,
                bg='#f0f8ff',
                width=10,
                anchor='e'
            ).grid(row=i, column=0, padx=10, pady=10, sticky='e')
            
            # 输入框
            if label_text == "性别:":
                # 性别使用下拉框
                entry = ttk.Combobox(
                    input_frame, 
                    font=self.label_font,
                    width=25,
                    state='readonly',
                    values=["男", "女"]
                )
                entry.current(0)
            elif label_text == "入学时间:":
                # 入学时间默认为当前年份
                current_year = datetime.datetime.now().year
                entry = tk.Entry(
                    input_frame, 
                    font=self.label_font,
                    width=27
                )
                entry.insert(0, f"{current_year}年9月")
            else:
                entry = tk.Entry(
                    input_frame, 
                    font=self.label_font,
                    width=27
                )
            
            entry.grid(row=i, column=1, padx=10, pady=10, sticky='w')
            self.entries[key] = entry
        
        # 照片上传区域
        photo_frame = tk.Frame(input_frame, bg='#f0f8ff')
        photo_frame.grid(row=len(fields), column=0, columnspan=2, pady=20)
        
        # 照片预览标签
        self.photo_label = tk.Label(
            photo_frame,
            text="暂无照片",
            bg='white',
            width=20,
            height=8,
            relief=tk.SUNKEN,
            font=("微软雅黑", 10)
        )
        self.photo_label.pack(pady=(0, 10))
        
        # 上传照片按钮
        upload_btn = tk.Button(
            photo_frame,
            text="上传照片",
            command=self.upload_photo,
            font=self.button_font,
            bg='#4CAF50',
            fg='white',
            padx=20,
            pady=5
        )
        upload_btn.pack()
        
        # 右侧预览区域
        preview_frame = tk.LabelFrame(
            main_frame, 
            text="证件预览", 
            font=self.label_font,
            bg='#f0f8ff',
            relief=tk.GROOVE
        )
        preview_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 证件预览画布
        self.preview_canvas = tk.Canvas(
            preview_frame,
            bg='white',
            width=350,
            height=500,
            relief=tk.SUNKEN
        )
        self.preview_canvas.pack(pady=20)
        
        # 按钮区域
        button_frame = tk.Frame(self.root, bg='#f0f8ff')
        button_frame.pack(pady=20)
        
        # 生成预览按钮
        preview_btn = tk.Button(
            button_frame,
            text="预览证件",
            command=self.preview_id,
            font=self.button_font,
            bg='#2196F3',
            fg='white',
            padx=30,
            pady=10
        )
        preview_btn.pack(side=tk.LEFT, padx=10)
        
        # 保存证件按钮
        save_btn = tk.Button(
            button_frame,
            text="保存证件",
            command=self.save_id,
            font=self.button_font,
            bg='#FF9800',
            fg='white',
            padx=30,
            pady=10
        )
        save_btn.pack(side=tk.LEFT, padx=10)
        
        # 清空信息按钮
        clear_btn = tk.Button(
            button_frame,
            text="清空信息",
            command=self.clear_info,
            font=self.button_font,
            bg='#f44336',
            fg='white',
            padx=30,
            pady=10
        )
        clear_btn.pack(side=tk.LEFT, padx=10)
        
        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set("就绪 - 请输入学生信息")
        status_bar = tk.Label(
            self.root,
            textvariable=self.status_var,
            font=("微软雅黑", 10),
            bg='#4682b4',
            fg='white',
            anchor='w',
            relief=tk.SUNKEN
        )
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
        # 初始化默认预览
        self.draw_default_preview()
    
    def upload_photo(self):
        """上传学生照片"""
        file_path = filedialog.askopenfilename(
            title="选择照片",
            filetypes=[
                ("图片文件", "*.jpg *.jpeg *.png *.bmp *.gif"),
                ("所有文件", "*.*")
            ]
        )
        
        if file_path:
            try:
                # 打开并调整照片大小
                self.photo_path = file_path
                image = Image.open(file_path)
                image.thumbnail((150, 200), Image.Resampling.LANCZOS)
                
                # 转换为Tkinter可用的格式
                self.student_photo = ImageTk.PhotoImage(image)
                
                # 更新预览
                self.photo_label.configure(
                    image=self.student_photo,
                    text=""
                )
                
                self.status_var.set(f"照片已上传: {os.path.basename(file_path)}")
                
            except Exception as e:
                messagebox.showerror("错误", f"无法加载照片: {str(e)}")
    
    def draw_default_preview(self):
        """绘制默认预览"""
        canvas = self.preview_canvas
        canvas.delete("all")
        
        # 绘制证件背景
        canvas.create_rectangle(10, 10, 340, 490, fill='#f5f5f5', outline='#ccc')
        canvas.create_rectangle(20, 20, 330, 480, fill='white', outline='#4682b4', width=2)
        
        # 标题
        canvas.create_text(175, 50, text="学生证", font=("楷体", 24, "bold"), fill='#4682b4')
        
        # 照片占位框
        canvas.create_rectangle(100, 100, 250, 250, outline='#ccc', width=2)
        canvas.create_text(175, 175, text="照片区域", font=("宋体", 12), fill='#999')
        
        # 提示文字
        canvas.create_text(175, 300, text="请填写信息并点击预览", font=("宋体", 14), fill='#666')
        canvas.create_text(175, 330, text="生成学生证件", font=("宋体", 14), fill='#666')
    
    def preview_id(self):
        """预览学生证件"""
        # 验证必填字段
        if not all([
            self.entries['entry_stu_id'].get(),
            self.entries['entry_name'].get(),
            self.entries['entry_college'].get(),
            self.entries['entry_major'].get()
        ]):
            messagebox.showwarning("警告", "请填写完整的必填信息！")
            return
        
        canvas = self.preview_canvas
        canvas.delete("all")
        
        # 绘制证件背景
        canvas.create_rectangle(10, 10, 340, 490, fill='#f5f5f5', outline='#ccc')
        canvas.create_rectangle(20, 20, 330, 480, fill='white', outline='#4682b4', width=3)
        
        # 标题
        canvas.create_text(175, 50, text="学 生 证", font=("楷体", 28, "bold"), fill='#4682b4')
        
        # 学校名称
        canvas.create_text(175, 85, text="XX大学", font=("黑体", 16), fill='#333')
        
        # 照片区域
        photo_x1, photo_y1 = 100, 120
        photo_x2, photo_y2 = 250, 270
        
        if self.student_photo:
            # 显示上传的照片
            canvas.create_image(175, 195, image=self.student_photo)
        else:
            # 显示占位符
            canvas.create_rectangle(photo_x1, photo_y1, photo_x2, photo_y2, outline='#ccc', width=2, fill='#f0f0f0')
            canvas.create_text(175, 195, text="照片", font=("宋体", 12), fill='#999')
        
        canvas.create_text(175, 285, text="照片", font=("宋体", 10), fill='#666')
        
        # 学生信息
        y_start = 320
        line_height = 30
        
        info_items = [
            ("学号:", self.entries['entry_stu_id'].get()),
            ("姓名:", self.entries['entry_name'].get()),
            ("性别:", self.entries['entry_gender'].get()),
            ("学院:", self.entries['entry_college'].get()),
            ("专业:", self.entries['entry_major'].get()),
            ("班级:", self.entries['entry_class'].get()),
            ("入学时间:", self.entries['entry_enroll_date'].get())
        ]
        
        for label, value in info_items:
            canvas.create_text(100, y_start, text=label, font=("黑体", 12), fill='#333', anchor='e')
            canvas.create_text(120, y_start, text=value, font=("宋体", 12), fill='#000', anchor='w')
            y_start += line_height
        
        # 证件有效期
        canvas.create_text(175, y_start + 20, text="有效期: 2026年9月 - 2030年6月", 
                          font=("宋体", 10), fill='#666')
        
        # 证件编号
        import random
        cert_id = f"ID{random.randint(100000, 999999)}"
        canvas.create_text(175, 460, text=f"证件号: {cert_id}", 
                          font=("宋体", 9), fill='#999')
        
        self.status_var.set("证件预览已生成")
    
    def save_id(self):
        """保存学生证件为图片"""
        # 检查是否有预览
        if not self.entries['entry_stu_id'].get():
            messagebox.showwarning("警告", "请先生成预览！")
            return
        
        # 选择保存路径
        file_path = filedialog.asksaveasfilename(
            title="保存证件",
            defaultextension=".png",
            filetypes=[
                ("PNG图片", "*.png"),
                ("JPEG图片", "*.jpg"),
                ("所有文件", "*.*")
            ],
            initialfile=f"学生证_{self.entries['entry_name'].get()}.png"
        )
        
        if file_path:
            try:
                # 创建新图片
                img_width, img_height = 800, 600
                img = Image.new('RGB', (img_width, img_height), color='white')
                draw = ImageDraw.Draw(img)
                
                # 加载字体
                try:
                    title_font = ImageFont.truetype("simhei.ttf", 40)
                    normal_font = ImageFont.truetype("simhei.ttf", 24)
                    small_font = ImageFont.truetype("simhei.ttf", 18)
                except:
                    title_font = ImageFont.load_default()
                    normal_font = ImageFont.load_default()
                    small_font = ImageFont.load_default()
                
                # 绘制背景框
                draw.rectangle([20, 20, img_width-20, img_height-20], outline='#4682b4', width=3)
                
                # 标题
                draw.text((img_width//2, 60), "学 生 证", font=title_font, fill='#4682b4', anchor='mm')
                draw.text((img_width//2, 110), "XX大学", font=normal_font, fill='#333', anchor='mm')
                
                # 照片区域
                photo_x, photo_y = 150, 180
                photo_size = 150
                
                if self.photo_path:
                    try:
                        # 加载并调整照片大小
                        photo_img = Image.open(self.photo_path)
                        photo_img.thumbnail((photo_size, photo_size), Image.Resampling.LANCZOS)
                        img.paste(photo_img, (photo_x, photo_y))
                    except:
                        # 如果无法加载照片，绘制占位符
                        draw.rectangle([photo_x, photo_y, photo_x+photo_size, photo_y+photo_size], 
                                     outline='#ccc', width=2)
                        draw.text((photo_x+photo_size//2, photo_y+photo_size//2), "照片", 
                                font=small_font, fill='#999', anchor='mm')
                else:
                    draw.rectangle([photo_x, photo_y, photo_x+photo_size, photo_y+photo_size], 
                                 outline='#ccc', width=2, fill='#f0f0f0')
                    draw.text((photo_x+photo_size//2, photo_y+photo_size//2), "照片", 
                            font=small_font, fill='#999', anchor='mm')
                
                # 学生信息
                info_x = 400
                info_y = 180
                line_height = 40
                
                info_items = [
                    ("学号:", self.entries['entry_stu_id'].get()),
                    ("姓名:", self.entries['entry_name'].get()),
                    ("性别:", self.entries['entry_gender'].get()),
                    ("学院:", self.entries['entry_college'].get()),
                    ("专业:", self.entries['entry_major'].get()),
                    ("班级:", self.entries['entry_class'].get()),
                    ("入学时间:", self.entries['entry_enroll_date'].get())
                ]
                
                for label, value in info_items:
                    draw.text((info_x, info_y), f"{label} {value}", font=normal_font, fill='#000')
                    info_y += line_height
                
                # 有效期和编号
                draw.text((img_width//2, 500), "有效期: 2026年9月 - 2030年6月", 
                         font=small_font, fill='#666', anchor='mm')
                
                import random
                cert_id = f"ID{random.randint(100000, 999999)}"
                draw.text((img_width//2, 530), f"证件编号: {cert_id}", 
                         font=small_font, fill='#999', anchor='mm')
                
                # 保存图片
                img.save(file_path)
                
                self.status_var.set(f"证件已保存: {os.path.basename(file_path)}")
                messagebox.showinfo("成功", f"学生证件已保存到:\n{file_path}")
                
            except Exception as e:
                messagebox.showerror("错误", f"保存失败: {str(e)}")
    
    def clear_info(self):
        """清空所有信息"""
        if messagebox.askyesno("确认", "确定要清空所有信息吗？"):
            for entry in self.entries.values():
                if isinstance(entry, ttk.Combobox):
                    entry.set("")
                    entry.current(0)
                else:
                    entry.delete(0, tk.END)
            
            # 清空照片
            self.photo_path = None
            self.student_photo = None
            self.photo_label.configure(image="", text="暂无照片")
            
            # 重置预览
            self.draw_default_preview()
            
            self.status_var.set("信息已清空")
            messagebox.showinfo("提示", "所有信息已清空！")

def main():
    root = tk.Tk()
    app = StudentIDGenerator(root)
    root.mainloop()

if __name__ == "__main__":
    main()