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.Seed;
import entity.User;
import entity.UserPT;
import entity.UserStar;
import entity.config;

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();
    }

    // 返回状态：0 success，1 邮箱重复，2其他原因
    @Override
    public int RegisterUser(User userinfo){
        try{
            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.persist(userinfo);
            return 0;

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

    // 返回状态：0 success，1 不存在，2其他原因
    @Override
    public int UpdateInformation(User userinfo){
        try {
            if (userinfo.userid == null) {
                return 2; // userid为null直接返回错误
            }
            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){
                return 1;
            }
            // 只更新需要的字段，避免破坏持久化状态和关联关系
            updateUser.email = userinfo.email;
            updateUser.username = userinfo.username;
            updateUser.password = userinfo.password;
            updateUser.sex = userinfo.sex;
            updateUser.school = userinfo.school;
            updateUser.pictureurl = userinfo.pictureurl;
            updateUser.profile = userinfo.profile;
            updateUser.accountstate = userinfo.accountstate;
            updateUser.invitetimes = userinfo.invitetimes;
            // 如有其他字段也一并赋值
            entitymanager.merge(updateUser);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            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 {
            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) {
                return 1;
            }
            entitymanager.persist(userinfo);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            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]);
    }

    //添加一个新的种子，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; // 用户不存在
            }
            seed.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];
    }
    //获取所有迁移信息

}

