package database;

import java.util.Calendar;
import java.util.UUID;
import java.util.List;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.core.Tuple;
import object.QBegInfo;
import object.QUserVotes;
import object.QSubmitSeed;
import object.QProfile;
import object.QSeed;
import object.Seed;
import object.User;
import object.UserPT;
import object.Notice;
import object.BegInfo;
import object.Post;
import object.PostReply;
import object.Profile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// public class Database2 implements DataManagerInterface {

//     private EntityManagerFactory emf;
//     private static final Logger logger = LoggerFactory.getLogger(Database2.class);

//     // 构造函数，初始化EntityManagerFactory
//     public Database2() {
//         this.emf = Persistence.createEntityManagerFactory("myPersistenceUnit"); // 使用 persistence.xml 中定义的持久化单元名称。
//     }

//     @Override
//     public int AddBegSeed(BegInfo info) {
//         if (info == null || info.begid == null || info.begid.isEmpty()) {
//             logger.warn("Invalid parameter: info is null or begid is empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查是否重复
//             BegInfo existingBeg = em.find(BegInfo.class, info.begid);
//             if (existingBeg != null) {
//                 logger.warn("BegSeed with ID {} already exists", info.begid);
//                 return 1;
//             }

//             // 设置默认值
//             if (info.endtime == null) {
//                 // 设置默认14天截止期
//                 Calendar calendar = Calendar.getInstance();
//                 calendar.add(Calendar.DAY_OF_MONTH, 14);
//                 info.endtime = calendar.getTime();
//             }
//             info.hasseed = false;

//             // 保存新的求种信息
//             em.persist(info);
//             tx.commit();

//             logger.info("Successfully added new BegSeed with ID: {}", info.begid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error adding BegSeed: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int UpdateBegSeed(BegInfo info) {
//         if (info == null || info.begid == null || info.begid.isEmpty()) {
//             logger.warn("Invalid parameter: info is null or begid is empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查是否存在
//             BegInfo existingBeg = em.find(BegInfo.class, info.begid);
//             if (existingBeg == null) {
//                 logger.warn("BegSeed with ID {} does not exist", info.begid);
//                 return 1;
//             }

//             // 保持原有值不变的字段
//             info.hasseed = existingBeg.hasseed;
//             if (info.endtime == null) {
//                 info.endtime = existingBeg.endtime;
//             }

//             // 更新求种信息
//             em.merge(info);
//             tx.commit();

//             logger.info("Successfully updated BegSeed with ID: {}", info.begid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error updating BegSeed: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int DeleteBegSeed(String begid) {
//         if (begid == null || begid.isEmpty()) {
//             logger.warn("Invalid parameter: begid is null or empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 查找要删除的求种信息
//             BegInfo begInfo = em.find(BegInfo.class, begid);
//             if (begInfo == null) {
//                 logger.warn("BegSeed with ID {} does not exist", begid);
//                 return 1;
//             }

//             // 删除求种信息
//             em.remove(begInfo);
//             tx.commit();

//             logger.info("Successfully deleted BegSeed with ID: {}", begid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error deleting BegSeed: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int VoteSeed(String begId, String seedId, String userId) {
//         if (begId == null || seedId == null || userId == null ||
//                 begId.isEmpty() || seedId.isEmpty() || userId.isEmpty()) {
//             logger.warn("Invalid parameters: begId, seedId or userId is null or empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查求种信息是否存在
//             BegInfo begInfo = em.find(BegInfo.class, begId);
//             if (begInfo == null) {
//                 logger.warn("BegSeed with ID {} does not exist", begId);
//                 return 2;
//             }

//             // 检查用户是否已投票
//             QUserVotes uv = QUserVotes.userVotes;
//             Long voteCount = new JPAQuery<>(em)
//                     .select(uv.count())
//                     .from(uv)
//                     .where(uv.userId.eq(userId)
//                             .and(uv.begId.eq(begId))
//                             .and(uv.seedId.eq(seedId)))
//                     .fetchOne();

//             if (voteCount > 0) {
//                 logger.warn("User {} has already voted for seed {} in beg {}", userId, seedId, begId);
//                 return 1;
//             }

//             // 创建新的投票记录
//             em.createNativeQuery("INSERT INTO UserVotes (user_id, beg_id, seed_id, created_at) " +
//                     "VALUES (?, ?, ?, CURRENT_TIMESTAMP)")
//                     .setParameter(1, userId)
//                     .setParameter(2, begId)
//                     .setParameter(3, seedId)
//                     .executeUpdate();

//             // 更新SubmitSeed表中的投票数
//             em.createQuery("UPDATE SubmitSeed s SET s.votes = s.votes + 1 " +
//                     "WHERE s.begId = :begId AND s.seedId = :seedId")
//                     .setParameter("begId", begId)
//                     .setParameter("seedId", seedId)
//                     .executeUpdate();

//             tx.commit();
//             logger.info("Successfully added vote from user {} for seed {} in beg {}",
//                     userId, seedId, begId);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error voting for seed: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int SubmitSeed(String begid, Seed seed) {
//         if (begid == null || seed == null || begid.isEmpty() || seed.seedid == null) {
//             logger.warn("Invalid parameters: begid or seed is null or empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查求种信息是否存在
//             BegInfo begInfo = em.find(BegInfo.class, begid);
//             if (begInfo == null) {
//                 logger.warn("BegSeed with ID {} does not exist", begid);
//                 return 2;
//             }

//             // 检查种子是否已提交过
//             QSubmitSeed ss = QSubmitSeed.submitSeed;
//             Long submitCount = new JPAQuery<>(em)
//                     .select(ss.count())
//                     .from(ss)
//                     .where(ss.begId.eq(begid)
//                             .and(ss.seedId.eq(seed.seedid)))
//                     .fetchOne();

//             if (submitCount > 0) {
//                 logger.warn("Seed {} has already been submitted for beg {}", seed.seedid, begid);
//                 return 1;
//             }

//             // 保存种子信息（如果不存在）
//             if (em.find(Seed.class, seed.seedid) == null) {
//                 em.persist(seed);
//             }

//             // 创建提交记录
//             em.createNativeQuery("INSERT INTO SubmitSeed (beg_id, seed_id, votes) VALUES (?, ?, 0)")
//                     .setParameter(1, begid)
//                     .setParameter(2, seed.seedid)
//                     .executeUpdate();

//             tx.commit();
//             logger.info("Successfully submitted seed {} for beg {}", seed.seedid, begid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error submitting seed: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public void SettleBeg() {
//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 1. 获取所有已过期且未完成的求种信息
//             QBegInfo b = QBegInfo.begInfo;
//             List<BegInfo> expiredBegs = new JPAQuery<>(em)
//                     .select(b)
//                     .from(b)
//                     .where(b.endtime.loe(new Date())
//                             .and(b.hasseed.eq(false)))
//                     .fetch();

//             for (BegInfo beg : expiredBegs) {
//                 // 2. 查找投票最多的提交任务
//                 QSubmitSeed ss = QSubmitSeed.submitSeed;
//                 Tuple topSubmission = new JPAQuery<>(em)
//                         .select(ss.seedId, ss.votes)
//                         .from(ss)
//                         .where(ss.begId.eq(beg.begid))
//                         .orderBy(ss.votes.desc())
//                         .limit(1)
//                         .fetchOne();

//                 if (topSubmission != null && topSubmission.get(ss.votes) > 0) {
//                     String seedId = topSubmission.get(ss.seedId);

//                     // 3. 获取上传者ID
//                     QSeed s = QSeed.seed;
//                     String ownerId = new JPAQuery<>(em)
//                             .select(s.seeduserid)
//                             .from(s)
//                             .where(s.seedid.eq(seedId))
//                             .fetchOne();

//                     // 4. 获取上传者的PT信息并更新魔力值
//                     UserPT ownerPT = em.find(UserPT.class, ownerId);
//                     if (ownerPT != null) {
//                         // 5. 发放奖励
//                         ownerPT.magic += beg.magic;
//                         em.merge(ownerPT);

//                         // 6. 更新求种状态
//                         beg.hasseed = true;
//                         em.merge(beg);

//                         logger.info("Reward {} magic points awarded to user {} for beg {}",
//                                 beg.magic, ownerId, beg.begid);
//                     }
//                 }
//             }

//             tx.commit();
//             logger.info("Successfully settled {} expired beg requests", expiredBegs.size());

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error settling beg requests: {}", e.getMessage(), e);
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int AddPost(Post post) {
//         if (post == null || post.postid == null || post.postid.isEmpty()) {
//             logger.warn("Invalid parameter: post is null or postid is empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查是否重复
//             Post existingPost = em.find(Post.class, post.postid);
//             if (existingPost != null) {
//                 logger.warn("Post with ID {} already exists", post.postid);
//                 return 1;
//             }

//             // 检查用户是否存在
//             User user = em.find(User.class, post.postuserid);
//             if (user == null) {
//                 logger.warn("User with ID {} does not exist", post.postuserid);
//                 return 2;
//             }

//             // 设置初始值
//             if (post.posttime == null) {
//                 post.posttime = new Date();
//             }
//             post.replytime = 0;
//             post.readtime = 0;

//             // 保存帖子
//             em.persist(post);
//             tx.commit();

//             logger.info("Successfully added new post with ID: {}", post.postid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error adding post: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int UpdatePost(Post post) {
//         if (post == null || post.postid == null || post.postid.isEmpty()) {
//             logger.warn("Invalid parameter: post is null or postid is empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查帖子是否存在
//             Post existingPost = em.find(Post.class, post.postid);
//             if (existingPost == null) {
//                 logger.warn("Post with ID {} does not exist", post.postid);
//                 return 1;
//             }

//             // 保持原有不可修改的字段
//             post.postuserid = existingPost.postuserid;
//             post.posttime = existingPost.posttime;
//             post.replytime = existingPost.replytime;
//             post.readtime = existingPost.readtime;

//             // 更新帖子
//             em.merge(post);
//             tx.commit();

//             logger.info("Successfully updated post with ID: {}", post.postid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error updating post: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int DeletePost(String postid) {
//         if (postid == null || postid.isEmpty()) {
//             logger.warn("Invalid parameter: postid is null or empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 查找要删除的帖子
//             Post post = em.find(Post.class, postid);
//             if (post == null) {
//                 logger.warn("Post with ID {} does not exist", postid);
//                 return 1;
//             }

//             // 删除帖子(由于设置了级联删除，相关的回复会自动删除)
//             em.remove(post);
//             tx.commit();

//             logger.info("Successfully deleted post with ID: {}", postid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error deleting post: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int AddComment(String postid, String userid, String comment) {
//         if (postid == null || postid.isEmpty() ||
//                 userid == null || userid.isEmpty() ||
//                 comment == null || comment.isEmpty()) {
//             logger.warn("Invalid parameters: postid, userid or comment is null or empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查帖子是否存在
//             Post post = em.find(Post.class, postid);
//             if (post == null) {
//                 logger.warn("Post with ID {} does not exist", postid);
//                 return 1;
//             }

//             // 检查评论用户是否存在
//             User user = em.find(User.class, userid);
//             if (user == null) {
//                 logger.warn("User with ID {} does not exist", userid);
//                 return 1;
//             }

//             // 创建新的回复
//             PostReply reply = new PostReply();
//             reply.replyid = UUID.randomUUID().toString();
//             reply.postid = postid;
//             reply.content = comment;
//             reply.authorid = userid;
//             reply.createdAt = new Date();

//             // 保存回复
//             em.persist(reply);

//             // 更新帖子的回复数
//             post.replytime += 1;
//             em.merge(post);

//             tx.commit();

//             logger.info("Successfully added comment by user {} to post {}, reply ID: {}",
//                     userid, postid, reply.replyid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error adding comment: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public int DeleteComment(String postid, String commentid) {
//         if (postid == null || postid.isEmpty() || commentid == null || commentid.isEmpty()) {
//             logger.warn("Invalid parameters: postid or commentid is null or empty");
//             return 2;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查帖子是否存在
//             Post post = em.find(Post.class, postid);
//             if (post == null) {
//                 logger.warn("Post with ID {} does not exist", postid);
//                 return 1;
//             }

//             // 检查评论是否存在且属于该帖子
//             PostReply reply = em.find(PostReply.class, commentid);
//             if (reply == null || !reply.postid.equals(postid)) {
//                 logger.warn("Comment {} does not exist or does not belong to post {}", commentid, postid);
//                 return 1;
//             }

//             // 删除评论
//             em.remove(reply);

//             // 更新帖子的回复数
//             post.replytime = Math.max(0, post.replytime - 1);
//             em.merge(post);

//             tx.commit();

//             logger.info("Successfully deleted comment {} from post {}", commentid, postid);
//             return 0;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("Error deleting comment: {}", e.getMessage());
//             return 2;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public boolean ExchangeMagicToUpload(String userid, int magic) {
//         if (userid == null || userid.isEmpty() || magic <= 0) {
//             logger.warn("参数无效: userid为空或magic <= 0");
//             return false;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             UserPT userPT = em.find(UserPT.class, userid);
//             if (userPT == null) {
//                 logger.warn("未找到用户 {} 的PT信息", userid);
//                 return false;
//             }

//             if (userPT.magic < magic) {
//                 logger.warn("用户 {} 的魔力值不足", userid);
//                 return false;
//             }

//             // 1:1兑换，直接加上魔力值（假设单位是MB）
//             userPT.magic -= magic;
//             userPT.upload += magic;

//             // 更新分享率
//             if (userPT.download > 0) {
//                 userPT.share = (double) userPT.upload / userPT.download;
//             }

//             em.merge(userPT);
//             tx.commit();

//             logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 上传量", userid, magic, magic);
//             return true;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("魔力值兑换上传量时发生错误: {}", e.getMessage());
//             return false;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public boolean ExchangeMagicToDownload(String userid, int magic) {
//         if (userid == null || userid.isEmpty() || magic <= 0) {
//             logger.warn("参数无效: userid为空或magic <= 0");
//             return false;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             UserPT userPT = em.find(UserPT.class, userid);
//             if (userPT == null) {
//                 logger.warn("未找到用户 {} 的PT信息", userid);
//                 return false;
//             }

//             if (userPT.magic < magic) {
//                 logger.warn("用户 {} 的魔力值不足", userid);
//                 return false;
//             }

//             // 1:1兑换，直接减去魔力值对应的下载量（假设单位是MB）
//             userPT.magic -= magic;
//             userPT.download = Math.max(0, userPT.download - magic);

//             // 更新分享率
//             if (userPT.download > 0) {
//                 userPT.share = (double) userPT.upload / userPT.download;
//             }

//             em.merge(userPT);
//             tx.commit();

//             logger.info("用户 {} 成功将 {} 点魔力值兑换为 {}MB 下载量减免", userid, magic, magic);
//             return true;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("魔力值兑换下载量时发生错误: {}", e.getMessage());
//             return false;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public boolean ExchangeMagicToVip(String userid, int magic) {
//         if (userid == null || userid.isEmpty() || magic <= 0) {
//             logger.warn("参数无效: userid为空或magic <= 0");
//             return false;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             UserPT userPT = em.find(UserPT.class, userid);
//             if (userPT == null) {
//                 logger.warn("未找到用户 {} 的PT信息", userid);
//                 return false;
//             }

//             if (userPT.magic < magic) {
//                 logger.warn("用户 {} 的魔力值不足", userid);
//                 return false;
//             }

//             // 1:1兑换VIP下载次数
//             userPT.magic -= magic;
//             userPT.viptime += magic;

//             em.merge(userPT);
//             tx.commit();

//             logger.info("用户 {} 成功将 {} 点魔力值兑换为 {} 次VIP下载次数", userid, magic, magic);
//             return true;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("魔力值兑换VIP下载次数时发生错误: {}", e.getMessage());
//             return false;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public boolean UploadTransmitProfile(Profile profile) {
//         if (profile == null || profile.profileurl == null || profile.profileurl.isEmpty() ||
//                 profile.userid == null || profile.userid.isEmpty()) {
//             logger.warn("参数无效: profile为空或必要字段为空");
//             return false;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             // 检查用户是否存在
//             User user = em.find(User.class, profile.userid);
//             if (user == null) {
//                 logger.warn("用户 {} 不存在", profile.userid);
//                 return false;
//             }

//             // 检查是否已存在相同的迁移申请
//             Profile existingProfile = em.find(Profile.class, profile.profileurl);
//             if (existingProfile != null) {
//                 logger.warn("迁移申请 {} 已存在", profile.profileurl);
//                 return false;
//             }

//             // 设置初始值
//             profile.exampass = false;
//             profile.magicgived = "0";
//             profile.uploadgived = "0";

//             // 保存迁移申请
//             em.persist(profile);
//             tx.commit();

//             logger.info("成功上传迁移申请 {}", profile.profileurl);
//             return true;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("上传迁移申请时发生错误: {}", e.getMessage());
//             return false;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public Profile GetTransmitProfile(String profileid) {
//         if (profileid == null || profileid.isEmpty()) {
//             logger.warn("参数无效: profileid为空");
//             return null;
//         }

//         EntityManager em = null;

//         try {
//             em = emf.createEntityManager();
//             Profile profile = em.find(Profile.class, profileid);
//             if (profile == null) {
//                 logger.warn("未找到迁移申请 {}", profileid);
//                 return null;
//             }

//             logger.info("成功获取迁移申请 {}", profileid);
//             return profile;

//         } catch (Exception e) {
//             logger.error("获取迁移申请时发生错误: {}", e.getMessage());
//             return null;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public boolean ExamTransmitProfile(String profileid, boolean result) {
//         if (profileid == null || profileid.isEmpty()) {
//             logger.warn("参数无效: profileid为空");
//             return false;
//         }

//         EntityManager em = null;
//         EntityTransaction tx = null;

//         try {
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();

//             Profile profile = em.find(Profile.class, profileid);
//             if (profile == null) {
//                 logger.warn("未找到迁移申请 {}", profileid);
//                 return false;
//             }

//             if (profile.exampass != result) {
//                 profile.exampass = result;

//                 if (result) {
//                     // 如果审核通过，更新用户的PT信息
//                     UserPT userPT = em.find(UserPT.class, profile.userid);
//                     if (userPT != null) {
//                         // 发放魔力值
//                         int magicToGive = Integer.parseInt(profile.magictogive);
//                         userPT.magic += magicToGive;
//                         profile.magicgived = String.valueOf(magicToGive);

//                         // 发放上传量
//                         long uploadToGive = Long.parseLong(profile.uploadtogive);
//                         userPT.upload += uploadToGive;
//                         profile.uploadgived = String.valueOf(uploadToGive);

//                         em.merge(userPT);
//                     }
//                 }

//                 em.merge(profile);
//             }

//             tx.commit();

//             logger.info("成功审核迁移申请 {}, 结果: {}", profileid, result);
//             return true;

//         } catch (Exception e) {
//             if (tx != null && tx.isActive()) {
//                 tx.rollback();
//             }
//             logger.error("审核迁移申请时发生错误: {}", e.getMessage());
//             return false;
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }

//     @Override
//     public Profile[] GetTransmitProfileList() {
//         EntityManager em = null;

//         try {
//             em = emf.createEntityManager();

//             // 获取所有迁移申请
//             QProfile p = QProfile.profile;
//             List<Profile> profiles = new JPAQuery<>(em)
//                     .select(p)
//                     .from(p)
//                     .fetch();

//             logger.info("成功获取所有迁移申请，共 {} 条", profiles.size());
//             return profiles.toArray(new Profile[0]);

//         } catch (Exception e) {
//             logger.error("获取迁移申请列表时发生错误: {}", e.getMessage());
//             return new Profile[0];
//         } finally {
//             if (em != null) {
//                 em.close();
//             }
//         }
//     }
// }