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

class StudentIDGenerator:
    def __init__(self, root):
        self.root = root
        self.root.title("学生证件生成器")
        self.root.geometry("900x700")
        self.root.resizable(False, False)
        
        # 设置颜色主题
        self.bg_color = "#2c3e50"
        self.fg_color = "#ecf0f1"
        self.button_color = "#3498db"
        
        # 学生数据
        self.student_data = {}
        self.photo_image = None
        
        self.setup_ui()
        
    def setup_ui(self):
        # 设置主框架
        main_frame = tk.Frame(self.root, bg=self.bg_color)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 左侧输入区域
        left_frame = tk.Frame(main_frame, bg=self.bg_color)
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10)
        
        # 标题
        title_label = tk.Label(left_frame, text="学生信息录入", 
                               font=("Arial", 20, "bold"),
                               bg=self.bg_color, fg=self.fg_color)
        title_label.pack(pady=20)
        
        # 输入框
        fields = [
            ("姓名:", "name"),
            ("学号:", "student_id"),
            ("班级:", "class_name"),
            ("学院:", "department"),
            ("入学年份:", "enroll_year"),
            ("出生日期:", "birthday")
        ]
        
        self.entries = {}
        for label_text, field_name in fields:
            frame = tk.Frame(left_frame, bg=self.bg_color)
            frame.pack(pady=10, fill=tk.X)
            
            label = tk.Label(frame, text=label_text, width=10,
                            font=("Arial", 12), bg=self.bg_color, fg=self.fg_color)
            label.pack(side=tk.LEFT, padx=5)
            
            entry = tk.Entry(frame, font=("Arial", 12), width=25)
            entry.pack(side=tk.LEFT, padx=5)
            self.entries[field_name] = entry
        
        # 照片选择
        photo_frame = tk.Frame(left_frame, bg=self.bg_color)
        photo_frame.pack(pady=10, fill=tk.X)
        
        tk.Label(photo_frame, text="照片:", width=10,
                font=("Arial", 12), bg=self.bg_color, fg=self.fg_color).pack(side=tk.LEFT, padx=5)
        
        self.photo_label = tk.Label(photo_frame, text="未选择照片",
                                    font=("Arial", 10), bg="white", width=20, height=2,
                                    relief=tk.RAISED)
        self.photo_label.pack(side=tk.LEFT, padx=5)
        
        tk.Button(photo_frame, text="选择照片", command=self.select_photo,
                 font=("Arial", 10), bg=self.button_color, fg="white",
                 cursor="hand2").pack(side=tk.LEFT, padx=5)
        
        # 按钮区域
        button_frame = tk.Frame(left_frame, bg=self.bg_color)
        button_frame.pack(pady=30)
        
        tk.Button(button_frame, text="生成证件", command=self.generate_id_card,
                 font=("Arial", 12, "bold"), bg="#27ae60", fg="white",
                 padx=20, pady=5, cursor="hand2").pack(side=tk.LEFT, padx=10)
        
        tk.Button(button_frame, text="保存证件", command=self.save_id_card,
                 font=("Arial", 12, "bold"), bg="#3498db", fg="white",
                 padx=20, pady=5, cursor="hand2").pack(side=tk.LEFT, padx=10)
        
        tk.Button(button_frame, text="清空信息", command=self.clear_inputs,
                 font=("Arial", 12, "bold"), bg="#e74c3c", fg="white",
                 padx=20, pady=5, cursor="hand2").pack(side=tk.LEFT, padx=10)
        
        # 右侧预览区域
        right_frame = tk.Frame(main_frame, bg=self.bg_color)
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=10)
        
        preview_label = tk.Label(right_frame, text="证件预览", 
                                font=("Arial", 18, "bold"),
                                bg=self.bg_color, fg=self.fg_color)
        preview_label.pack(pady=10)
        
        self.preview_canvas = tk.Canvas(right_frame, width=400, height=600,
                                        bg="white", highlightthickness=2,
                                        highlightbackground="#bdc3c7")
        self.preview_canvas.pack(pady=10)
        
        # 初始化预览
        self.show_default_preview()
        
    def select_photo(self):
        file_path = filedialog.askopenfilename(
            title="选择学生照片",
            filetypes=[("图片文件", "*.jpg *.jpeg *.png *.bmp *.gif")]
        )
        if file_path:
            self.student_data['photo_path'] = file_path
            # 显示缩略图
            img = Image.open(file_path)
            img.thumbnail((100, 100))
            photo = ImageTk.PhotoImage(img)
            self.photo_label.config(image=photo, text="")
            self.photo_label.image = photo
            
    def show_default_preview(self):
        """显示默认预览"""
        self.preview_canvas.delete("all")
        self.preview_canvas.create_rectangle(0, 0, 400, 600, fill="#ecf0f1", outline="")
        
        # 绘制证件模板
        self.preview_canvas.create_rectangle(20, 20, 380, 580, fill="white", outline="#2c3e50", width=3)
        
        # 标题
        self.preview_canvas.create_text(200, 60, text="学生证", 
                                        font=("Arial", 24, "bold"), fill="#34495e")
        
        # 照片占位
        self.preview_canvas.create_rectangle(50, 100, 170, 220, fill="#bdc3c7", outline="#7f8c8d", width=2)
        self.preview_canvas.create_text(110, 160, text="照片", font=("Arial", 12), fill="#7f8c8d")
        
        # 信息占位
        info_y = 100
        info_items = ["姓名：", "学号：", "班级：", "学院：", "入学年份：", "有效期："]
        for i, item in enumerate(info_items):
            self.preview_canvas.create_text(200, info_y + i*45, text=item,
                                            font=("Arial", 12), fill="#2c3e50", anchor="w")
            self.preview_canvas.create_text(280, info_y + i*45, text="",
                                            font=("Arial", 12), fill="#7f8c8d", anchor="w")
        
        # 底部信息
        self.preview_canvas.create_text(200, 550, text="XX大学学生处制", 
                                        font=("Arial", 10), fill="#95a5a6")
        
    def generate_id_card(self):
        """生成学生证件"""
        # 验证输入
        name = self.entries['name'].get().strip()
        student_id = self.entries['student_id'].get().strip()
        class_name = self.entries['class_name'].get().strip()
        department = self.entries['department'].get().strip()
        enroll_year = self.entries['enroll_year'].get().strip()
        birthday = self.entries['birthday'].get().strip()
        
        if not all([name, student_id, class_name, department, enroll_year]):
            messagebox.showwarning("警告", "请填写完整的学生信息！")
            return
            
        # 保存数据
        self.student_data.update({
            'name': name,
            'student_id': student_id,
            'class_name': class_name,
            'department': department,
            'enroll_year': enroll_year,
            'birthday': birthday if birthday else "未填写"
        })
        
        # 渲染证件
        self.render_id_card()
        
    def render_id_card(self):
        """渲染证件图像"""
        # 创建证件底图
        card = Image.new('RGB', (400, 600), 'white')
        draw = ImageDraw.Draw(card)
        
        # 绘制边框
        draw.rectangle([(20, 20), (380, 580)], outline='#2c3e50', width=3)
        
        # 绘制标题
        try:
            font_title = ImageFont.truetype("simhei.ttf", 28)
            font_normal = ImageFont.truetype("simhei.ttf", 16)
            font_small = ImageFont.truetype("simhei.ttf", 12)
        except:
            font_title = ImageFont.load_default()
            font_normal = ImageFont.load_default()
            font_small = ImageFont.load_default()
        
        draw.text((160, 50), "学生证", fill='#34495e', font=font_title)
        
        # 显示照片
        if 'photo_path' in self.student_data and os.path.exists(self.student_data['photo_path']):
            try:
                photo = Image.open(self.student_data['photo_path'])
                photo = photo.resize((120, 120), Image.Resampling.LANCZOS)
                card.paste(photo, (40, 100))
            except:
                draw.rectangle([(40, 100), (160, 220)], outline='#7f8c8d', width=2)
                draw.text((70, 150), "照片加载失败", fill='red', font=font_normal)
        else:
            draw.rectangle([(40, 100), (160, 220)], outline='#7f8c8d', width=2)
            draw.text((70, 150), "无照片", fill='#7f8c8d', font=font_normal)
        
        # 填写信息
        info_y = 110
        info_items = [
            (f"姓名：{self.student_data.get('name', '')}", 180),
            (f"学号：{self.student_data.get('student_id', '')}", 225),
            (f"班级：{self.student_data.get('class_name', '')}", 270),
            (f"学院：{self.student_data.get('department', '')}", 315),
            (f"入学年份：{self.student_data.get('enroll_year', '')}", 360),
            (f"出生日期：{self.student_data.get('birthday', '')}", 405)
        ]
        
        for text, y_pos in info_items:
            draw.text((180, y_pos), text, fill='#2c3e50', font=font_normal)
        
        # 有效期
        valid_date = datetime.now().strftime("%Y年%m月")
        draw.text((180, 450), f"有效期：{valid_date} - {int(datetime.now().year)+4}年08月", 
                 fill='#2c3e50', font=font_normal)
        
        # 校徽和底部文字
        draw.ellipse([(300, 480), (360, 540)], outline='#3498db', width=2)
        draw.text((315, 500), "校徽", fill='#3498db', font=font_small)
        draw.text((150, 560), "XX大学学生处制", fill='#95a5a6', font=font_small)
        
        # 显示在canvas上
        self.card_image = ImageTk.PhotoImage(card)
        self.preview_canvas.delete("all")
        self.preview_canvas.create_image(0, 0, anchor="nw", image=self.card_image)
        
        # 保存生成的证件
        self.generated_card = card
        
    def save_id_card(self):
        """保存证件"""
        if hasattr(self, 'generated_card'):
            file_path = filedialog.asksaveasfilename(
                defaultextension=".png",
                filetypes=[("PNG图片", "*.png"), ("JPEG图片", "*.jpg"), ("所有文件", "*.*")],
                initialfile=f"学生证_{self.student_data.get('name', 'unknown')}.png"
            )
            if file_path:
                self.generated_card.save(file_path)
                messagebox.showinfo("成功", f"学生证已保存到：\n{file_path}")
        else:
            messagebox.showwarning("警告", "请先生成学生证！")
            
    def clear_inputs(self):
        """清空所有输入"""
        for entry in self.entries.values():
            entry.delete(0, tk.END)
        self.photo_label.config(image="", text="未选择照片")
        self.photo_label.image = None
        self.student_data.clear()
        self.show_default_preview()
        if hasattr(self, 'generated_card'):
            delattr(self, 'generated_card')

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

if __name__ == "__main__":
    main()