package database;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Persistence;

import com.querydsl.jpa.impl.JPAQuery;

import entity.BegInfo;
import entity.Notice;
import entity.Post;
import entity.Profile;
import entity.QNotice;
import entity.QSeed;
import entity.QUser;
import entity.QUserPT;
import entity.QUserStar;
import entity.QUserInvite;
import entity.QPost;
import entity.Seed;
import entity.User;
import entity.UserPT;
import entity.UserStar;
import entity.config;
import entity.PostReply;
import entity.QPostReply;

public class Database1 implements DataManagerInterface {
    @PersistenceContext
    private final EntityManager entitymanager;

    public Database1() {
        config cfg = new config();
        Map<String,Object> props = new HashMap<>();
        props.put("javax.persistence.jdbc.url",
                  "jdbc:mysql://" + cfg.SqlURL + "/" + cfg.Database);
        props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
        props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
        this.entitymanager = Persistence.createEntityManagerFactory("myPersistenceUnit", props).createEntityManager();
    }
    @Override
    public String LoginUser(User userinfo){
        try {
            // 检查传入的参数是否合法
            if (userinfo == null || userinfo.password == null) {
                return null;
            }
            
            boolean hasEmail = userinfo.email != null && !userinfo.email.isEmpty();
            
            // 如果两个都为空或两个都不为空，返回null
            if (!hasEmail) {
                return null;
            }
            
            JPAQuery<User> query = new JPAQuery<>(entitymanager);
            QUser u = QUser.user;
            User foundUser = null;
            
            
            // 通过邮箱和密码查找
            foundUser = query.select(u)
                .from(u)
                .where(u.email.eq(userinfo.email)
                    .and(u.password.eq(userinfo.password)))
                .fetchOne();
            
            // 如果找到匹配的用户则返回用户ID，否则返回null
            return foundUser != null ? foundUser.userid : null;
            
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 返回状态：0 success，1 邮箱重复，2其他原因
    @Override
    public int RegisterUser(User userinfo){
        try{
            // 首先检查该邮箱是否在UserInvite表中被邀请过
            JPAQuery<String> inviteQuery = new JPAQuery<>(entitymanager);
            QUserInvite ui = QUserInvite.userInvite;
            List<String> invitedEmails = inviteQuery.select(ui.inviterEmail).from(ui).fetch();

            // 如果邮箱不在被邀请列表中，拒绝注册
            if(!invitedEmails.contains(userinfo.email)){
                return 2; // 未被邀请
            }

            // 检查邮箱是否已在User表中存在
            JPAQuery<String> query = new JPAQuery<>(entitymanager);
            QUser u = QUser.user;
            List<String> allEmails = query.select(u.email).from(u).fetch();

            if(allEmails.contains(userinfo.email)){
                return 1; // 邮箱重复
            }

            entitymanager.getTransaction().begin();
            entitymanager.persist(userinfo);
            entitymanager.getTransaction().commit();
            return 0; // 注册成功

        }catch(Exception e){
            e.printStackTrace();
            if (entitymanager.getTransaction().isActive()) {
                entitymanager.getTransaction().rollback();
            }   
            return 4;
        }
         
    }

    // 返回状态：0 success，1 不存在，2其他原因
    @Override
    public int UpdateInformation(User userinfo){
        try {
            if (userinfo.userid == null) {
                return 2; // userid为null直接返回错误
            }
            
            entitymanager.getTransaction().begin();
            
            JPAQuery<User> query = new JPAQuery<>(entitymanager);
            QUser u = QUser.user;
            User updateUser = query.select(u).from(u).where(u.userid.eq(userinfo.userid)).fetchOne();

            if(updateUser == null){
                entitymanager.getTransaction().rollback();
                return 1;
            }
            // 只更新需要的字段，避免破坏持久化状态和关联关系
            if (userinfo.email != null) updateUser.email = userinfo.email;
            if (userinfo.username != null) updateUser.username = userinfo.username;
            if (userinfo.password != null) updateUser.password = userinfo.password;
            if (userinfo.sex != null) updateUser.sex = userinfo.sex;
            if (userinfo.school != null) updateUser.school = userinfo.school;
            if (userinfo.pictureurl != null) updateUser.pictureurl = userinfo.pictureurl;
            if (userinfo.profile != null) updateUser.profile = userinfo.profile;
            updateUser.accountstate = userinfo.accountstate;
            updateUser.invitetimes = userinfo.invitetimes;
            // 如有其他字段也一并赋值
            entitymanager.merge(updateUser);
            entitymanager.getTransaction().commit();
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            if (entitymanager.getTransaction().isActive()) {
                entitymanager.getTransaction().rollback();
            }
            return 2;
        }
        
    }

    // 返回用户的全部基本信息
    @Override
    public User GetInformation(String userid){
        User user = entitymanager.find(User.class, userid);
        return user;
    }

    //返回用户的全部pt站信息
    @Override
    public UserPT GetInformationPT(String userid){
        UserPT userPT = entitymanager.find(UserPT.class, userid);
        return userPT;
    }

    //返回状态：0 success，1 邮箱重复，2其他原因
    @Override
    public int UpdateInformationPT(UserPT userinfo){
        try{
            JPAQuery<UserPT> query = new JPAQuery<>(entitymanager);
            QUserPT u = QUserPT.userPT;
            UserPT userPT = query.select(u).from(u).where(u.userid.eq(userinfo.userid)).fetchOne();
        
            if(userPT == null){
                return 1;
            }
            userPT = userinfo;
            entitymanager.merge(userPT);
            return 0;

        }catch(Exception e){
            e.printStackTrace();
            return 2;
        }
    }

    //返回状态：0 success，1 id重复，2其他原因
    @Override
    public int RegisterUserPT(UserPT userinfo){
        try {
            entitymanager.getTransaction().begin();
            
            JPAQuery<UserPT> query = new JPAQuery<>(entitymanager);
            QUserPT u = QUserPT.userPT;
            UserPT checkUserPT = query.select(u).from(u).where(u.userid.eq(userinfo.userid)).fetchOne();
            if (checkUserPT != null) {
                entitymanager.getTransaction().rollback();
                return 1;
            }
            
            entitymanager.persist(userinfo);
            entitymanager.getTransaction().commit();
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            if (entitymanager.getTransaction().isActive()) {
                entitymanager.getTransaction().rollback();
            }
            return 2;
        }
    }

    //返回种子的全部信息
    @Override
    public Seed GetSeedInformation(String seedid){
        JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
        QSeed s = QSeed.seed;
        Seed seed = query.select(s).from(s).where(s.seedid.eq(seedid)).fetchOne();
        return seed;
    }

    @Override
    public Seed[] GetSeedListByTag(String tag){
        JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
        QSeed s = QSeed.seed;
        List<Seed> seeds = query.select(s).from(s).where(s.seedtag.eq(tag)).fetch();
        return seeds.toArray(new Seed[0]);
    }

    @Override
    public Seed[] GetSeedListByUser(String userid){
        JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
        QSeed s = QSeed.seed;
        List<Seed> seeds = query.select(s).from(s).where(s.seeduserid.eq(userid)).fetch();
        return seeds.toArray(new Seed[0]);
    }

    @Override
    public int DeleteSeed(String seedid){
        try {
            entitymanager.getTransaction().begin();
            Seed seed = entitymanager.find(Seed.class, seedid);
            if (seed == null) {
                entitymanager.getTransaction().rollback();
                return 1; // 种子不存在
            }
            entitymanager.remove(seed);
            entitymanager.getTransaction().commit();
            return 0; // 成功删除
        } catch (Exception e) {
            e.printStackTrace();
            if (entitymanager.getTransaction().isActive()) {
                entitymanager.getTransaction().rollback();
            }
            return 2; // 其他错误
        }
    }

    //添加一个新的种子，0成功，其他失败信息待定;
    @Override
    public int RegisterSeed(Seed seedinfo){
        try {
            entitymanager.getTransaction().begin();
            JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
            QSeed s = QSeed.seed;
            Seed seed = query.select(s).from(s).where(s.seedid.eq(seedinfo.seedid)).fetchOne();
            User user = entitymanager.find(User.class, seedinfo.seeduserid);
            if (user == null) {
                entitymanager.getTransaction().rollback();
                return 2; // 用户不存在
            }
            seedinfo.user = user; // 设置种子的用户关联
            if (seed != null) {
                entitymanager.getTransaction().rollback();
                return 1;
            }
            entitymanager.persist(seedinfo);
            entitymanager.getTransaction().commit();
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            if (entitymanager.getTransaction().isActive()) {
                entitymanager.getTransaction().rollback();
            }
            return 2;
        }
    }

    //接收新的种子然后更新其全部属性
    @Override
    public int UpdateSeed(Seed seedinfo){
        try {
            JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
            QSeed s = QSeed.seed;
            Seed seed = query.select(s).from(s).where(s.seedid.eq(seedinfo.seedid)).fetchOne();
            if (seed == null) {
                return 1;
            }
            seed = seedinfo;
            entitymanager.merge(seed);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return 2;
        }
    }

    //传入搜索的关键词或句子，返回搜索到的种子信息（按照公共字符数量排序）
    @Override
    public Seed[] SearchSeed(String userQ){
        JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
        QSeed s = QSeed.seed;
        List<Seed> seeds = query.select(s).from(s).fetch();

        if (seeds == null || userQ == null || userQ.trim().isEmpty()) {
            return seeds.toArray(new Seed[0]);
        }

        String processedQuery = userQ.toLowerCase().trim();
        Map<Seed, Integer> seedCountMap = new HashMap<>();
        for(Seed seed : seeds){
            String title = seed.title.toLowerCase().trim();
            int count = countCommonCharacter(processedQuery, title);
            seedCountMap.put(seed, count);
        }
        seeds.sort((s1, s2) -> {
            int count1 = seedCountMap.getOrDefault(s1, 0);
            int count2 = seedCountMap.getOrDefault(s2, 0);
            return Integer.compare(count2, count1);
        });

        return seeds.toArray(new Seed[0]);
    }

    //计算字符串公共字符数量
    private int countCommonCharacter(String str1, String str2){
        Map<Character, Integer> map1 = new HashMap<>();
        Map<Character, Integer> map2 = new HashMap<>();

        for(char c : str1.toCharArray()){
            if (!Character.isWhitespace(c)) {
                map1.put(c, map1.getOrDefault(c, 0) + 1);
            }
        }

        for(char c : str2.toCharArray()){
            if (!Character.isWhitespace(c)) {
                map2.put(c, map2.getOrDefault(c, 0) + 1);
            }
        }

        int res = 0;
        for(char c : map1.keySet()){
            if (map2.containsKey(c)) {
                res += Math.min(map1.get(c), map2.get(c));
            }
            
        }
        return res;
    }

    //返回状态：0 success，1 重复，2其他原因
    @Override
    public int AddNotice(Notice notice){
        try {
            JPAQuery<Notice> query = new JPAQuery<>(entitymanager);
            QNotice n = QNotice.notice;
            Notice checkNotice = query.select(n).from(n).where(n.noticeid.eq(notice.noticeid)).fetchOne();
            if (checkNotice != null) {
                return 1;
            }
            
            entitymanager.persist(notice);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return 2;
        }
        
    }

    //返回状态：0 success，1 不存在，2其他原因
    @Override
    public boolean UpdateNotice(Notice notice){
        try {
            Notice oldNotice = entitymanager.find(Notice.class, notice.noticeid);
            if (oldNotice == null) {
                return false;
            }
            oldNotice = notice;
            entitymanager.merge(oldNotice);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //删除公告，返回状态：0 success，1 不存在，2其他原因
    @Override
    public boolean DeleteNotice(String noticeid){
        try {
            Notice notice = entitymanager.find(Notice.class, noticeid);
            if (notice == null) {
                return false;
            }
            entitymanager.remove(notice);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        
    }

    //获取用户的剩余邀请次数
    public int GetUserAvailableInviteTimes(String userid){
        try {
            JPAQuery<Integer> query = new JPAQuery<>(entitymanager);
            QUser u = QUser.user;
            int invite_left = query.select(u.invitetimes).from(u).where(u.userid.eq(userid)).fetchOne();
            
            return invite_left;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
        
    }

    //邀请用户，返回状态：0 success，1 剩余次数不足，2,3其他原因
    @Override
    public int InviteUser(String inviterid,String inviteemail){
        try {
            User user = entitymanager.find(User.class, inviterid);
            if (user == null || !user.email.equals(inviteemail)) {
                return 3;
            }
            if (user.invitetimes <= 0) {
                return 1;
            }
            user.invitetimes -= 1;
            entitymanager.merge(user);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return 2;
        }
        
    }

    //添加一个收藏，返回状态：0 success，1 不存在,2其他原因
    @Override
    public boolean AddCollect(String userid,String seedid){
        JPAQuery<User> query2 = new JPAQuery<>(entitymanager);
        QUser u2 = QUser.user;
        User user = query2.select(u2).from(u2).where(u2.userid.eq(userid)).fetchOne();
        if (user == null) {
            return false;
        }
        JPAQuery<Seed> query3 = new JPAQuery<>(entitymanager);
        QSeed p = QSeed.seed;
        Seed seed = query3.select(p).from(p).where(p.seedid.eq(seedid)).fetchOne();
        if (seed == null) {
            return false;
        }
        JPAQuery<String> query = new JPAQuery<>(entitymanager);
        QUserStar u = QUserStar.userStar;
        List<String> allSeedId = query.select(u.seedid).from(u).where(u.userid.eq(userid)).fetch();

        if (allSeedId.contains(seedid)) {
            return false;
        }
        UserStar userStar = new UserStar();
        userStar.userid = userid;
        userStar.seedid = seedid;
        entitymanager.persist(userStar);
        return true;
    }

    //删除一个收藏，返回状态：0 success，1 不存在,2其他原因
    @Override
    public boolean DeleteCollect(String userid,String seedid){
        try {
            JPAQuery<UserStar> query = new JPAQuery<>(entitymanager);
            QUserStar u = QUserStar.userStar;
            UserStar userStar = query.select(u).from(u).where(u.userid.eq(userid).and(u.seedid.eq(seedid))).fetchOne();
            if (userStar == null) {
                return true; // 收藏不存在
            }
            entitymanager.remove(userStar);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        
    }

    @Override
    public int AddBegSeed(BegInfo info){
        return 0;
    }

    @Override
    public int UpdateBegSeed(BegInfo info){
        return 0;
    }

    @Override
    public int DeleteBegSeed(String begid){
        return 0;
    }

    @Override
    public int VoteSeed(String begId, String seedId, String userId){
        return 0;
    }

    @Override
    public int SubmitSeed(String begid,Seed seed){
        return 0;
    }

    @Override
    public void SettleBeg(){
        
    }

    @Override
    public int AddPost(Post post){
        return 0;
    }

    @Override
    public int UpdatePost(Post post){
        return 0;
    }

    @Override
    public int DeletePost(String postid){
        return 0;
    }

    @Override
    public int AddComment(String postid, String userid, String comment){
        return 0;
    }

    @Override
    public int DeleteComment(String postid,String commentid){
        return 0;
    }

    @Override
    public boolean ExchangeMagicToUpload(String userid,int magic)//将魔力值兑换为上传量，返回状态：0 success，1 不存在,2其他原因
    {
        return true;
    }
    
    @Override
    public boolean ExchangeMagicToDownload(String userid,int magic)
    {
        return true;
    }//将魔力值兑换为下载量，返回状态：0 success，1 不存在,2其他原因

    @Override
    public boolean ExchangeMagicToVip(String userid,int magic){
        return true;
    }
    //将魔力值兑换为VIP次数，返回状态：0 success，1 不存在,2其他原因

    @Override
    public boolean UploadTransmitProfile(Profile profile){
        return true;
    }

    @Override
    public Profile GetTransmitProfile(String profileid){
        Profile profile = new Profile();
        return profile;
    }
    //获取迁移信息
    
    @Override
    public boolean ExamTransmitProfile(String profileid,boolean result){
        return true;
    }
    //审核迁移信息,0成功，1失败
    @Override
    public Profile[] GetTransmitProfileList(){
        return new Profile[0];
    }
    //获取所有迁移信息

    @Override
    public Post[] GetPostList() {
        JPAQuery<Post> query = new JPAQuery<>(entitymanager);
        QPost p = QPost.post;
        List<Post> posts = query.select(p).from(p).fetch();
        return posts.toArray(new Post[0]);
    }

    @Override
    public Post GetPost(String postid) {
        JPAQuery<Post> query = new JPAQuery<>(entitymanager);
        QPost p = QPost.post;
        Post post = query.select(p).from(p).where(p.postid.eq(postid)).fetchOne();
        return post;
    }

    @Override
    public PostReply[] GetPostReplyList(String postid) {
        JPAQuery<PostReply> query = new JPAQuery<>(entitymanager);
        QPostReply p = QPostReply.postReply;
        List<PostReply> replies = query.select(p).from(p).where(p.postid.eq(postid)).fetch();
        return replies.toArray(new PostReply[0]);
    }
}

