package tracker;
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 java.security.MessageDigest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.persistence.*;
import com.dampcake.bencode.Bencode;
import com.dampcake.bencode.Type;
import com.querydsl.jpa.impl.JPAUpdateClause;
import entity.*;
import entity.config;
import java.util.Scanner;
import java.io.IOException;
public class Tracker implements TrackerInterface {
    private final EntityManagerFactory emf;
    // 默认构造：产线数据库
    public Tracker() {
        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);
    }
    // 测试传入：测试库
    public Tracker(EntityManagerFactory emf) {
        this.emf = emf;
    }
    @Override
    public boolean AddUpLoad(String userid, int upload, String infoHash) {
        long newTotal = upload;  // convert to long
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            // 1) find the seedId by infoHash
            String seedId = em.createQuery(
                "SELECT s.seedId FROM SeedHash s WHERE s.infoHash = :ih", String.class)
                .setParameter("ih", infoHash)
                .getSingleResult();
            // 2) sum existing uploads for this user+seed
            Long sumSoFar = em.createQuery(
                "SELECT COALESCE(SUM(t.upload),0) FROM TransRecord t WHERE t.uploaduserid = :uid AND t.seedid = :sid",
                Long.class)
                .setParameter("uid", userid)
                .setParameter("sid", seedId)
                .getSingleResult();
            long delta = newTotal - sumSoFar;
            if (delta < 0L) {
                tx.rollback();
                return false;   // error: newTotal less than already recorded
            }
            if (delta == 0L) {
                tx.rollback();
                return false;  // nothing to do
            }
            // 3) persist a new TransRecord with only the delta
            TransRecord rd = new TransRecord();
            rd.taskid       = UUID.randomUUID().toString();
            rd.uploaduserid = userid;
            rd.seedid       = seedId;
            rd.upload       = delta;
            rd.maxupload    = newTotal;
            em.persist(rd);
            em.flush();
            // 4) 重新计算用户的总上传，确保与 TransRecord 完全一致
            Long totalUpload = em.createQuery(
                "SELECT COALESCE(SUM(t.upload),0) FROM TransRecord t WHERE t.uploaduserid = :uid",
                Long.class
            )
            .setParameter("uid", userid)
            .getSingleResult();

            Long PTuploadbefor = em.createQuery(
                "SELECT t.upload FROM UserPT t WHERE t.userid = :uid",
                Long.class
            ).setParameter("uid", userid)
            .getSingleResult();
            
        
            UserPT user = em.find(UserPT.class, userid);
            user.upload = totalUpload;
            em.merge(user);
            em.flush();
            tx.commit();

            Long PTuploadafter = em.createQuery(
                "SELECT t.upload FROM UserPT t WHERE t.userid = :uid",
                Long.class
            ).setParameter("uid", userid)
            .getSingleResult();

            System.out.println("按回车继续...");
            System.out.printf("thisadd:%d userptsofar:%d userptafter:%d totaluploadnow:%d delta:%d%n",upload, PTuploadbefor,PTuploadafter, totalUpload,delta);
            System.out.println("按回车继续...");
            return false;      // success
        } catch (RuntimeException ex) {
            if (tx.isActive()) tx.rollback();
            throw ex;
        } finally {
            em.close();
        }
    }
    
    @Override
    public boolean ReduceUpLoad(String userid, int upload){
        long uploadLong = upload;  // convert to long
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            // 1) fetch user and ensure enough upload to reduce
            UserPT user = em.find(UserPT.class, userid);
            long before = user.upload;
            if (uploadLong > before) {
                tx.rollback();
                return true;   // error: cannot reduce more than current total
            }
            // 2) subtract
            user.upload = before - uploadLong;
            em.merge(user);
            // (optional) record a negative TransRecord so sums stay in sync
            TransRecord rd = new TransRecord();
            rd.taskid       = UUID.randomUUID().toString();
            rd.uploaduserid = userid;
            rd.seedid       = null;
            rd.upload       = -uploadLong;
            rd.maxupload    = user.upload;
            em.persist(rd);
            tx.commit();
            return false;      // success
        } catch (RuntimeException ex) {
            if (tx.isActive()) tx.rollback();
            throw ex;
        } finally {
            em.close();
        }
    }
    @Override
    public boolean AddDownload(String userid, int download, String infoHash) {
        long newTotal = download;  // convert to long
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            // 1. 查 SeedHash
            TypedQuery<SeedHash> qsh = em.createQuery(
                "SELECT s FROM SeedHash s WHERE s.infoHash = :h", SeedHash.class);
            qsh.setParameter("h", infoHash);
            List<SeedHash> shl = qsh.getResultList();
            if (shl.isEmpty()) {
                System.out.println("seed没有被记录");
                return false;
            }
            String seedid = shl.get(0).seedId;

            // 2. 统计该用户在该种子上的已有 download
            TypedQuery<Long> qsum = em.createQuery(
                "SELECT COALESCE(SUM(t.download),0) FROM TransRecord t " +
                "WHERE t.seedid = :sid AND t.downloaduserid = :uid", Long.class);
            qsum.setParameter("sid", seedid);
            qsum.setParameter("uid", userid);
            long oldSeedSum = qsum.getSingleResult();

            long diff = newTotal - oldSeedSum;
            if (diff <= 0) return false;
            
            System.out.println("AddDownload: 该种子原有总量=" + oldSeedSum + ", 新总量=" + newTotal + ", 增量=" + diff);

            try {
                tx.begin();
                // 1. persist 增量记录
                TransRecord tr = new TransRecord();
                tr.taskid         = UUID.randomUUID().toString();
                tr.downloaduserid = userid;
                tr.seedid         = seedid;
                tr.download       = diff;
                tr.maxdownload    = newTotal;
                em.persist(tr);

                // 2. 全表重新累计该用户所有种子的 download，并更新 UserPT.download
                TypedQuery<Long> qTotal = em.createQuery(
                    "SELECT COALESCE(SUM(t.download),0) FROM TransRecord t WHERE t.downloaduserid = :uid",
                    Long.class
                )
                .setParameter("uid", userid);
                long userTotalDownload = qTotal.getSingleResult();
                QUserPT quser = QUserPT.userPT;
                new JPAUpdateClause(em, quser)
                    .where(quser.userid.eq(userid))
                    .set(quser.download, userTotalDownload)
                    .execute();

                tx.commit();
                return false;
            } catch (Exception e) {
                if (tx.isActive()) tx.rollback();
                return true;
            } finally {
                em.close();
            }
        } catch (Exception e) {
            return true;
        }
    }
    @Override
    public boolean ReduceDownload(String userid, int download) {
        long downloadLong = download;  // convert to long
        EntityManager em = emf.createEntityManager();
        try {
            // 1. 预检查当前值
            TypedQuery<Long> qcurr = em.createQuery(
                "SELECT u.download FROM UserPT u WHERE u.userid = :uid", Long.class);
            qcurr.setParameter("uid", userid);
            long current = qcurr.getSingleResult();
            if (downloadLong > current) {
                em.close();
                return false;
            }
            // 2. 执行减法更新
            EntityTransaction tx = em.getTransaction();
            tx.begin();
            QUserPT q = QUserPT.userPT;
            new JPAUpdateClause(em, q)
                .where(q.userid.eq(userid))
                .set(q.download, q.download.subtract(downloadLong))
                .execute();
            tx.commit();
            return false;
        } catch(Exception e) {
            return true;
        } finally {
            if (em.isOpen()) em.close();
        }
    }
    @Override
    public boolean AddMagic(String userid, int magic) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            QUserPT q = QUserPT.userPT;
            long updated = new JPAUpdateClause(em, q)
                .where(q.userid.eq(userid))
                .set(q.magic, q.magic.add(magic))
                .execute();
            tx.commit();
            return updated <= 0;
        } catch(Exception e) {
            if (tx.isActive()) tx.rollback();
            return true;
        } finally {
            em.close();
        }
    }
    @Override
    public boolean ReduceMagic(String userid, int magic) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            QUserPT q = QUserPT.userPT;
            long updated = new JPAUpdateClause(em, q)
                .where(q.userid.eq(userid))
                .set(q.magic, q.magic.subtract(magic))
                .execute();
            tx.commit();
            return updated <= 0;
        } catch(Exception e) {
            if (tx.isActive()) tx.rollback();
            return true;
        } finally {
            em.close();
        }
    }
    @Override
    public int SaveTorrent(String seedid, File TTorent){
        try {
            Path storageDir = Paths.get(config.TORRENT_STORAGE_DIR);
            if (!Files.exists(storageDir)) {
                Files.createDirectories(storageDir);
            }
            String filename = TTorent.getName();
            Path target = storageDir.resolve(seedid + "_" + filename);
            Files.copy(TTorent.toPath(), target, StandardCopyOption.REPLACE_EXISTING);

            // attempt to parse infoHash, but don't fail if parsing fails
            String infoHash = null;
            try {
                byte[] torrentData = Files.readAllBytes(target);
                Bencode bencode = new Bencode();
                @SuppressWarnings("unchecked")
                Map<String,Object> meta = bencode.decode(torrentData, Type.DICTIONARY);
                @SuppressWarnings("unchecked")
                Map<String,Object> info = (Map<String,Object>) meta.get("info");
                byte[] infoBytes = bencode.encode(info);
                MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
                byte[] digest = sha1.digest(infoBytes);
                StringBuilder sb = new StringBuilder();
                for (byte b1 : digest) {
                    sb.append(String.format("%02x", b1));
                }
                infoHash = sb.toString();
            } catch (Exception e) {
                System.err.println("Warning: could not parse torrent infoHash: " + e.getMessage());
            }

            EntityManager em = emf.createEntityManager();
            EntityTransaction tx = em.getTransaction();
            try {
                tx.begin();
                Seed seed = em.find(Seed.class, seedid);
                seed.url = target.toString();
                em.merge(seed);

                // upsert SeedHash only if we have a valid infoHash
                if (infoHash != null) {
                    SeedHash sh = new SeedHash();
                    sh.seedId = seedid;
                    sh.infoHash = infoHash;
                    em.merge(sh);
                }
                tx.commit();
                return 0;
            } catch (Exception e) {
                if (tx.isActive()) tx.rollback();
                return 1;
            } finally {
                em.close();
            }
        } catch (Exception e) {
            return 1;
        }
    }
    @Override
    public File GetTTorent(String seedid, String userid) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        File file = null;
        try {
            Seed seed = em.find(Seed.class, seedid);
            if (seed == null || seed.url == null) {
                return null;
            }
            file = new File(seed.url);
            if (!file.exists()) {
                return null;
            }
            tx.begin();
            SeedDownload sd = new SeedDownload();
            sd.seedId = seedid;
            sd.userId = userid;
            LocalDateTime now = LocalDateTime.now();
            sd.downloadStart = now;
            sd.downloadEnd = now;
            em.persist(sd);
            tx.commit();
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            // ignore persistence errors and still return the file
        } finally {
            em.close();
        }
        return file;
    }
    @Override
    public int AddRecord(TransRecord rd){
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.persist(rd);
            tx.commit();
            // 返回1表示插入成功
            return 1;
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            return -1;
        } finally {
            em.close();
        }
    }
}