package dao.impl;

import common.DBTool;
import dao.CourseDB;
import pojo.CourseInfo;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class CourseDBImpl implements CourseDB {

    private CourseInfo fillCourseInfo(ResultSet rs) throws SQLException {
        CourseInfo courseInfo = new CourseInfo();
        courseInfo.setId(rs.getInt("N_COURSE_ID"));
        courseInfo.setName(rs.getString("VC_COURSE_NAME"));
        courseInfo.setType(rs.getInt("N_TYPE"));
        courseInfo.setCredit(rs.getFloat("F_CREDIT"));
        courseInfo.setGrade(rs.getInt("N_GRADE"));
        courseInfo.setMajor(rs.getInt("N_MAJOR"));
        courseInfo.setDetail(rs.getString("VC_DETAIL"));
        return courseInfo;
    }

    @Override
    public ArrayList<CourseInfo> getAllCourseInfo() {
        ArrayList<CourseInfo> courseList = new ArrayList<>();
        try {
            PreparedStatement ps = DBTool.getPreparedStatement("SELECT * FROM t_course");
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                courseList.add(fillCourseInfo(rs));
            }
            DBTool.close(ps, rs);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return courseList;
    }

    @Override
    public ArrayList<CourseInfo> getCourseInfos(int page, int pageSize, String keyword, int type) {
        ArrayList<CourseInfo> courseList = new ArrayList<>();
        String sql = "SELECT * FROM t_course WHERE UPPER(VC_COURSE_NAME) LIKE ? AND ? IN (N_TYPE, 0) ORDER BY N_COURSE_ID LIMIT ?, ?";
        try {
            PreparedStatement ps = DBTool.getPreparedStatement(sql);
            ps.setString(1, "%"+keyword.toUpperCase()+"%");
            ps.setInt(2, type);
            ps.setInt(3, (page - 1) * pageSize);
            ps.setInt(4, pageSize);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                courseList.add(fillCourseInfo(rs));
            }
            DBTool.close(ps, rs);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return courseList;
    }

    @Override
    public CourseInfo getCourseInfoByID(int id) {
        CourseInfo courseInfo = null;
        try {
            PreparedStatement ps = DBTool.getPreparedStatement("select * from t_course WHERE N_COURSE_ID = ?");
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                String name = rs.getString("VC_COURSE_NAME");
                int type = rs.getInt("N_TYPE");
                float credits = rs.getFloat("F_CREDIT");
                int grade = rs.getInt("N_GRADE");
                int major = rs.getInt("N_MAJOR");
                String detail = rs.getString("VC_DETAIL");
                courseInfo = new CourseInfo(id, name, type, credits, grade, major, detail);
            }
            DBTool.close(ps, rs);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return courseInfo;
    }

    @Override
    public int getAllCourseInfoCount() {
        int count = 0;
        String sql = "SELECT COUNT(*) FROM t_course";
        try {
            PreparedStatement ps = DBTool.getPreparedStatement(sql);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
            }
            DBTool.close(ps, rs);
        } catch (SQLException e) {
            return -1;
        }
        return count;
    }

    @Override
    public int getAllCourseInfoCount(String keyword, int type) {
        int count = 0;
        String sql = "SELECT COUNT(*) FROM t_course WHERE UPPER(VC_COURSE_NAME) LIKE ? AND ? IN (N_TYPE, 0)";
        try {
            PreparedStatement ps = DBTool.getPreparedStatement(sql);
            ps.setString(1, "%"+keyword.toUpperCase()+"%");
            ps.setInt(2, type);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
            }
            DBTool.close(ps, rs);
        } catch (SQLException e) {
            return -1;
        }
        return count;
    }

    @Override
    public int addCourseInfo(CourseInfo courseInfo) {
        int lines;
        try {
            String sql = "INSERT INTO t_course (VC_COURSE_NAME, N_TYPE, F_CREDIT, N_GRADE, N_MAJOR, VC_DETAIL) VALUES(?, ?, ?, ?, ?, ?)";
            PreparedStatement ps = DBTool.getPreparedStatement(sql);
            ps.setString(1, courseInfo.getName());
            ps.setInt(2, courseInfo.getType());
            ps.setFloat(3, courseInfo.getCredit());
            ps.setInt(4, courseInfo.getGrade());
            ps.setInt(5, courseInfo.getMajor());
            ps.setString(6, courseInfo.getDetail());
            lines = ps.executeUpdate();
            DBTool.close(ps);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return lines;
    }

    @Override
    public int updateCourseInfo(CourseInfo courseInfo) {
        int lines;
        try {
            PreparedStatement ps = DBTool.getPreparedStatement("UPDATE t_course SET VC_COURSE_NAME = ?," +
                    " N_TYPE = ?, F_CREDIT = ?, N_GRADE = ?, N_MAJOR = ?, VC_DETAIL = ? WHERE N_COURSE_ID = ?");
            ps.setString(1, courseInfo.getName());
            ps.setInt(2, courseInfo.getType());
            ps.setFloat(3, courseInfo.getCredit());
            ps.setInt(4, courseInfo.getGrade());
            ps.setInt(5, courseInfo.getMajor());
            ps.setString(6, courseInfo.getDetail());
            ps.setInt(7, courseInfo.getId());
            lines = ps.executeUpdate();
            DBTool.close(ps);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return lines;
    }

    @Override
    public int deleteCourseInfo(int id) {
        int lines;
        try {
            String sql = "DELETE FROM t_course WHERE N_COURSE_ID = ?";
            PreparedStatement ps = DBTool.getPreparedStatement(sql);
            ps.setInt(1, id);
            lines = ps.executeUpdate();
            DBTool.close(ps);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return lines;
    }
}
