package com.example.myapplication.repository;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.example.myapplication.domain.User;

public class UserRepository {
    private final Context context;
    private DatabaseHelper helper;
    private SQLiteDatabase db;

    public UserRepository(Context context) {
        this.context = context.getApplicationContext();
    }

    public void openDatabase() {
        if (helper == null) helper = new DatabaseHelper(context);
        if (db == null || !db.isOpen()) db = helper.getWritableDatabase();
    }

    public void closeDatabase() {
        if (db != null && db.isOpen()) db.close();
        db = null;
    }

    public boolean insertUser(User user) {
        openDatabase();
        ContentValues cv = new ContentValues();
        cv.put("account", user.getAccount());
        cv.put("name", user.getName());
        cv.put("password", user.getPassword());
        cv.put("type", user.getType());
        cv.put("point", user.getPoints());
        if (user.getGrade() != null) cv.put("grade", String.valueOf(user.getGrade())); else cv.putNull("grade");
        if (user.getMajorId() != null) cv.put("major_id", user.getMajorId()); else cv.putNull("major_id");
        long r = db.insertWithOnConflict("T_User", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
        closeDatabase();
        return r != -1;
    }

    public boolean insertUserWithGradeText(User user, String gradeText) {
        openDatabase();
        ContentValues cv = new ContentValues();
        cv.put("account", user.getAccount());
        cv.put("name", user.getName());
        cv.put("password", user.getPassword());
        cv.put("type", user.getType());
        cv.put("point", user.getPoints());
        if (gradeText != null && !gradeText.isEmpty()) cv.put("grade", gradeText); else cv.putNull("grade");
        if (user.getMajorId() != null) cv.put("major_id", user.getMajorId()); else cv.putNull("major_id");
        long r = db.insertWithOnConflict("T_User", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
        closeDatabase();
        return r != -1;
    }

    public boolean deleteUser(User user) {
        openDatabase();
        int rows = db.delete("T_User", "account=?", new String[]{user.getAccount()});
        closeDatabase();
        return rows > 0;
    }

    public boolean updateUser(User user) {
        openDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", user.getName());
        cv.put("password", user.getPassword());
        cv.put("type", user.getType());
        if (user.getPoints() >= 0) cv.put("point", user.getPoints());
        if (user.getGrade() != null) cv.put("grade", String.valueOf(user.getGrade()));
        if (user.getMajorId() != null) cv.put("major_id", user.getMajorId());
        int rows = db.update("T_User", cv, "account=?", new String[]{user.getAccount()});
        closeDatabase();
        return rows > 0;
    }

    public User getUserByAccount(String account) {
        openDatabase();
        User user = null;
        try (Cursor c = db.query("T_User", null, "account=?", new String[]{account}, null, null, null)) {
            if (c != null && c.moveToFirst()) {
                Integer grade = null;
                try {
                    int gi = c.getColumnIndex("grade");
                    if (gi >= 0 && !c.isNull(gi)) {
                        String gs = c.getString(gi);
                        try { grade = gs == null ? null : Integer.parseInt(gs.trim()); } catch (Exception e) { grade = null; }
                    }
                } catch (Exception ignored) {}
                Long majorId = null;
                try { int mi = c.getColumnIndex("major_id"); if (mi >= 0 && !c.isNull(mi)) majorId = c.getLong(mi); } catch (Exception ignored) {}
                user = new User(
                        c.getString(c.getColumnIndexOrThrow("account")),
                        c.getString(c.getColumnIndexOrThrow("name")),
                        c.getString(c.getColumnIndexOrThrow("password")),
                        c.getInt(c.getColumnIndexOrThrow("type")),
                        null,
                        c.getInt(c.getColumnIndexOrThrow("point")),
                        grade,
                        majorId
                );
            }
        }
        closeDatabase();
        return user;
    }

    public boolean verifyUserValidity(String account, String password) {
        openDatabase();
        boolean ok = false;
        try (Cursor c = db.query("T_User", new String[]{"account"}, "account=? AND password=?",
                new String[]{account, password}, null, null, null)) {
            ok = c != null && c.moveToFirst();
        }
        closeDatabase();
        return ok;
    }

    public int getPoints(String account) {
        openDatabase();
        int pts = 0;
        try (Cursor c = db.query("T_User", new String[]{"point"}, "account=?",
                new String[]{account}, null, null, null)) {
            if (c != null && c.moveToFirst()) pts = c.getInt(0);
        }
        closeDatabase();
        return pts;
    }

    public String getGradeText(String account) {
        openDatabase();
        String grade = null;
        try (Cursor c = db.query("T_User", new String[]{"grade"}, "account=?",
                new String[]{account}, null, null, null)) {
            if (c != null && c.moveToFirst()) {
                int idx = c.getColumnIndex("grade");
                if (idx >= 0 && !c.isNull(idx)) grade = c.getString(idx);
            }
        }
        closeDatabase();
        return grade;
    }

    public boolean addPoints(String account, int delta) {
        openDatabase();
        db.execSQL("UPDATE T_User SET point = COALESCE(point,0) + ? WHERE account=?",
                new Object[]{delta, account});
        closeDatabase();
        return true;
    }
}