package cheat;

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

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.apache.commons.lang3.tuple.Pair;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

import com.querydsl.jpa.impl.JPAQueryFactory;

import entity.Appeal;
import entity.QAppeal;
import entity.QSeed;
import entity.User;
import entity.config;
import entity.QUser;
import entity.TTorent;

public class Cheat implements CheatInterfnterface {

    @PersistenceContext
    private EntityManagerFactory emf;

    public Cheat() {
        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.emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
    }

    @Override
    @Transactional
    public boolean AddAppeal(Appeal appeal) {
        EntityManager entityManager = emf.createEntityManager();
        try {
            entityManager.getTransaction().begin();
            entityManager.persist(appeal);
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (entityManager.getTransaction().isActive()) {
                entityManager.getTransaction().rollback();
            }
            return false;
        }
        return true;
    }

    @Override
    public Appeal GetAppeal(String appealid) {
        try {
            EntityManager entityManager = emf.createEntityManager();
            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
            QAppeal qAppeal = QAppeal.appeal;
            Appeal appeal = queryFactory
                .selectFrom(qAppeal)
                .where(qAppeal.appealid.eq(appealid))
                .fetchOne();
            return appeal;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public Appeal[] GetAppealList() {
        EntityManager entityManager = emf.createEntityManager();
        try {
            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
            QAppeal qAppeal = QAppeal.appeal;
            List<Appeal> appeals = queryFactory
                .selectFrom(qAppeal)
                .fetch();
            return appeals.toArray(new Appeal[0]);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (entityManager != null) {
                entityManager.close();
            }
        }
    }

    @Override
    public boolean HandleAppeal(String appealid, Integer status) {
        EntityManager entityManager = emf.createEntityManager();
        try {
            Appeal appeal = GetAppeal(appealid);
            if (appeal != null) {
                appeal.status = status;
                entityManager.getTransaction().begin();
                entityManager.merge(appeal);
                User user = entityManager.find(User.class, appeal.appealuserid);
                // if (user != null && user.accountstate != false) {
                if (user != null) {
                    if (status == 1) {
                        user.accountstate = false;
                    }
                    entityManager.merge(user);
                }
                entityManager.getTransaction().commit();
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            if (emf.createEntityManager().getTransaction().isActive()) {
                emf.createEntityManager().getTransaction().rollback();
            }
            return false;
        } finally {
            if (entityManager != null) {
                entityManager.close();
            }
        }
    }

    @Override
    public Pair<String, String>[] GetFakeSeed() {
        List<Pair<String, String>> fakeSeeds = new ArrayList<>();
        try {
            EntityManager entityManager = emf.createEntityManager();
            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
            QSeed qSeed = QSeed.seed;
            List<com.querydsl.core.Tuple> results = queryFactory
                .select(qSeed.seedid, qSeed.seeduserid)
                .from(qSeed)
                .where(qSeed.faketime.gt(config.getFakeTime()))
                .fetch();
            for (com.querydsl.core.Tuple result : results) {
                String seedid = result.get(qSeed.seedid);
                String userid = result.get(qSeed.seeduserid);
                fakeSeeds.add(Pair.of(seedid, userid));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return fakeSeeds.toArray(new Pair[0]);
    }

    @Override
    public String[] GetPunishedUserList() {
        List<String> punishedUsers = new ArrayList<>();
        try {
            EntityManager entityManager = emf.createEntityManager();
            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
            entity.QUser qUser = entity.QUser.user;
            List<String> results = queryFactory
                .select(qUser.userid)
                .from(qUser)
                .where(qUser.accountstate.isTrue())
                .fetch();
            for (String userid : results) {
                punishedUsers.add(userid);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return punishedUsers.toArray(new String[0]);
    }

    @Override
    public void DetectTrans() {
        // JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
        // QSeed qSeed = QSeed.seed;
        // List<Seed> seeds = queryFactory
        //     .selectFrom(qSeed)
        //     .fetch();
        // for (Seed seed : seeds) {
        //     QTransRecord qTransRecord = QTransRecord.transRecord;
        //     List<TransRecord> tasks = queryFactory
        //         .selectFrom(qTransRecord)
        //         .where(qTransRecord.seedid.eq(seed.seedid))
        //         .fetch();

        //     int n = tasks.size();
        //     if (n == 0) continue;

        //     double[] xArr = new double[n];
        //     for (int i = 0; i < n; i++) {
        //         TransRecord t = tasks.get(i);
        //         xArr[i] = Math.max(0, t.upload - t.download);
        //     }

        //     double sum = 0;
        //     for (double x : xArr) sum += x;
        //     double mu = sum / n;

        //     double sqSum = 0;
        //     for (double x : xArr) sqSum += (x - mu) * (x - mu);
        //     double sigma = Math.sqrt(sqSum / n);

        //     for (int i = 0; i < n; i++) {
        //         if (Math.abs(xArr[i] - mu) > 3 * sigma) {
        //             User user = entityManager.find(User.class, tasks.get(i).downloaduserid);
        //             if (user != null) {
        //                 user.detectedCount++;
        //                 user.lastDetectedTime = new java.util.Date();
        //                 entityManager.merge(user);
        //             }
        //         }
        //     }
        // }
    }

    @Override
    public void DetectFakeSeed(){
    }

    @Override
    public boolean DetectFakeSeed(String seedid){
        return false;
    }

    @Override
    public void PunishUser(){
        EntityManager entityManager = emf.createEntityManager();
        JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
        entity.QUser qUser = entity.QUser.user;
        List<User> users = queryFactory
            .selectFrom(qUser)
            .where(qUser.detectedCount.gt(config.getCheatTime()) 
                .or(qUser.fakeDetectedCount.gt(config.getFakeTime())))
            .fetch();

        for (User user : users) {
            user.accountstate = true;
            entityManager.merge(user);
        }
    }

    @Override
    public User[] GetCheatUsers() {
        EntityManager entityManager = emf.createEntityManager();
        List<User> cheatUsers = new ArrayList<>();
        try {
            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
            QUser qUser = QUser.user;
            cheatUsers = queryFactory
                .selectFrom(qUser)
                .where(qUser.accountstate.eq(true))
                .fetch();
            return cheatUsers.toArray(new User[0]);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (entityManager != null){
                entityManager.close();
            }
        }
    }

    @Override
    public User[] GetSuspiciousUsers() {
        EntityManager entityManager = emf.createEntityManager();
        List<User> suspiciousUsers = new ArrayList<>();
        try {
            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
            QUser qUser = QUser.user;
            suspiciousUsers = queryFactory
                .selectFrom(qUser)
                .where((qUser.detectedCount.gt(0)
                    .or(qUser.fakeDetectedCount.gt(0)))
                    .and(qUser.accountstate.eq(false)))
                .fetch();
            return suspiciousUsers.toArray(new User[0]);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (entityManager != null){
                entityManager.close();
            }
        }
    }
    
    @Override
    public int UnbanUser(String userid) {
        EntityManager entityManager = emf.createEntityManager();
        try {
            User user = entityManager.find(User.class, userid);
            if (user == null) {
                return 1; // 用户不存在
            }
            if (user.accountstate) {
                user.accountstate = false; // 解封用户
                entityManager.getTransaction().begin();
                entityManager.merge(user);
                entityManager.getTransaction().commit();
                return 0; // 成功解封
            }
            return 2; // 用户未被封禁
        } catch (Exception e) {
            e.printStackTrace();
            if (entityManager.getTransaction().isActive()) {
                entityManager.getTransaction().rollback();
            }
            return -1; // 出现异常
        } finally {
            if (entityManager != null){
                entityManager.close();
            }
        }
    }

    @Override
    public int BanUser(String userid) {
        EntityManager entityManager = emf.createEntityManager();
        try {
            User user = entityManager.find(User.class, userid);
            if (user == null) {
                return 1; // 用户不存在
            }
            if (!user.accountstate) {
                user.accountstate = true; // 封禁用户
                entityManager.getTransaction().begin();
                entityManager.merge(user);
                entityManager.getTransaction().commit();
                return 0; // 成功封禁
            }
            return 2; // 用户已被封禁
        } catch (Exception e) {
            e.printStackTrace();
            if (entityManager.getTransaction().isActive()) {
                entityManager.getTransaction().rollback();
            }
            return -1; // 出现异常
        } finally {
            if (entityManager != null){
                entityManager.close();
            }
        }
    }

    @Override
    public int SubmitAppeal(String userid, String content, File file) {
        EntityManager entityManager = emf.createEntityManager();
        try {
            User user = entityManager.find(User.class, userid);
            if (user == null) {
                return 1; // 用户不存在
            }
            Appeal appeal = new Appeal();
            appeal.appealid = java.util.UUID.randomUUID().toString();
            appeal.appealuserid = userid;
            appeal.content = content;
            appeal.user = user; // 设置关联的用户
            Path storageDir = Paths.get(config.APPEAL_STORAGE_DIR);
            if (!Files.exists(storageDir)) {
                Files.createDirectories(storageDir);
            }
            String filename = file.getName();
            Path target = storageDir.resolve(appeal.appealid + "_" + filename);
            Files.copy(file.toPath(), target, StandardCopyOption.REPLACE_EXISTING);
            appeal.status = 0; // 初始状态为未处理
            appeal.fileURL = target.toString(); // 设置文件存储路径
            entityManager.getTransaction().begin();
            entityManager.persist(appeal);
            entityManager.getTransaction().commit();
            return 0; // 成功提交申诉
        } catch (Exception e) {
            e.printStackTrace();
            if (entityManager.getTransaction().isActive()) {
                entityManager.getTransaction().rollback();
            }
            return -1; // 出现异常
        } finally {
            if (entityManager != null){
                entityManager.close();
            }
        }
    }
}