package f1.db;

import f1.entity.CommentItem;
import f1.entity.User;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDao extends BaseDao {

    public UserDao(Database db) {
        super(db);
    }

    public boolean createUser(User user) {
        String sql = "INSERT INTO user (username, password, email, country, avatar) VALUES (?, ?, ?, ?, ?)";
        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setString(1, user.getUsername());
            stmt.setString(2, user.getPassword());
            stmt.setString(3, user.getEmail());
            stmt.setString(4, user.getCountry());
            stmt.setString(5, user.getAvatar());
            int affectedRows = stmt.executeUpdate();
            return affectedRows > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    public User getUserByUsername(String username) {
        String sql = "SELECT * FROM user WHERE username = ?";
        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setString(1, username);
            var rs = stmt.executeQuery();
            if (rs.next()) {
                return new User(
                        rs.getInt("id"),
                        rs.getString("username"),
                        rs.getString("password"),
                        rs.getString("email"),
                        rs.getString("country"),
                        rs.getString("avatar"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public User getUserById(int id) {
        String sql = "SELECT username, email, country, avatar FROM user WHERE id = ?";
        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setInt(1, id);
            var rs = stmt.executeQuery();
            if (rs.next()) {
                // Password is not selected, so we pass null
                return new User(
                        id,
                        rs.getString("username"),
                        null, // password
                        rs.getString("email"),
                        rs.getString("country"),
                        rs.getString("avatar"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean addComment(int userId, Integer responseId, Integer rootId, String content) {
        String sql = "INSERT INTO comment (user_id, response_id, root_id, content) VALUES (?, ?, ?, ?)";
        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setInt(1, userId);

            if (responseId == null) {
                stmt.setNull(2, java.sql.Types.INTEGER);
            } else {
                stmt.setInt(2, responseId);
            }

            if (rootId == null) {
                stmt.setNull(3, java.sql.Types.INTEGER);
            } else {
                stmt.setInt(3, rootId);
            }

            stmt.setString(4, content);
            int affectedRows = stmt.executeUpdate();
            return affectedRows > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean deleteComment(int commentId) {
        String sql = "DELETE FROM comment WHERE id = ?";
        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setInt(1, commentId);
            int affectedRows = stmt.executeUpdate();
            return affectedRows > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    public List<CommentItem> getRootComments(int limit, int offset) {
        List<CommentItem> comments = new ArrayList<>();
        String sql = "SELECT c.id, c.user_id, u.username, c.content, COUNT(replies.id) AS reply_count " +
                "FROM comment c " +
                "JOIN user u ON c.user_id = u.id " +
                "LEFT JOIN comment replies ON replies.root_id = c.id " +
                "WHERE c.root_id IS NULL " +
                "GROUP BY c.id " +
                "ORDER BY c.id DESC " +
                "LIMIT ? OFFSET ?";

        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setInt(1, limit);
            stmt.setInt(2, offset);
            var rs = stmt.executeQuery();
            while (rs.next()) {
                comments.add(new CommentItem(
                        rs.getInt("id"),
                        rs.getInt("user_id"),
                        rs.getString("username"),
                        null, // response_id is null for root
                        null, // root_id is null for root
                        rs.getString("content"),
                        rs.getInt("reply_count")));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return comments;
    }

    public List<CommentItem> getChildComments(int rootId) {
        List<CommentItem> comments = new ArrayList<>();
        String sql = "SELECT c.id, c.user_id, u.username, c.response_id, c.content, " +
                "parent_c.user_id AS reply_to_user_id, parent_u.username AS reply_to_username " +
                "FROM comment c " +
                "JOIN user u ON c.user_id = u.id " +
                "LEFT JOIN comment parent_c ON c.response_id = parent_c.id " +
                "LEFT JOIN user parent_u ON parent_c.user_id = parent_u.id " +
                "WHERE c.root_id = ? " +
                "ORDER BY c.id ASC";

        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setInt(1, rootId);
            var rs = stmt.executeQuery();
            while (rs.next()) {
                comments.add(new CommentItem(
                        rs.getInt("id"),
                        rs.getInt("user_id"),
                        rs.getString("username"),
                        (Integer) rs.getObject("response_id"),
                        null, // root_id is known and not needed in response
                        rs.getString("content"),
                        (Integer) rs.getObject("reply_to_user_id"),
                        rs.getString("reply_to_username")));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return comments;
    }

    public CommentItem getCommentById(int id) {
        String sql = "SELECT c.id, c.user_id, u.username, c.content, COUNT(replies.id) AS reply_count " +
                     "FROM comment c " +
                     "JOIN user u ON c.user_id = u.id " +
                     "LEFT JOIN comment replies ON replies.root_id = c.id " +
                     "WHERE c.id = ? " +
                     "GROUP BY c.id";
        
        try (var con = getConnection(); var stmt = con.prepareStatement(sql)) {
            stmt.setInt(1, id);
            var rs = stmt.executeQuery();
            if (rs.next()) {
                return new CommentItem(
                    rs.getInt("id"),
                    rs.getInt("user_id"),
                    rs.getString("username"),
                    null, 
                    null, 
                    rs.getString("content"),
                    rs.getInt("reply_count")
                );
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}
