package com.nisum.dao;

import com.nisum.model.UserAddress;
import com.nisum.util.DBConnection;

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

public class AddressDAO {

    public List<UserAddress> getUserAddresses(int userId) throws SQLException {
        List<UserAddress> list = new ArrayList<>();
        String sql = "SELECT * FROM UserAddresses WHERE UserID = ?";
        try (Connection conn = DBConnection.get();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, userId);
            try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                    list.add(mapAddress(rs));
                }
            }
        }
        return list;
    }

    public UserAddress getById(int addressId) throws SQLException {
        String sql = "SELECT * FROM UserAddresses WHERE AddressID = ?";
        try (Connection conn = DBConnection.get();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, addressId);
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    return mapAddress(rs);
                }
            }
        }
        return null;
    }

    public UserAddress getByUserId(int userId) throws SQLException {
        String sql = "SELECT * FROM UserAddresses WHERE UserID = ?";
        try (Connection conn = DBConnection.get();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, userId);
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    return mapAddress(rs);
                }
            }
        }
        return null;
    }

    public int addAddress(UserAddress addr) throws SQLException {
        String sql = "INSERT INTO UserAddresses (UserID, AddressLine1, AddressLine2, ZipCode, State, Country) "
                + "VALUES (?, ?, ?, ?, ?, ?)";
        try (Connection conn = DBConnection.get();
             PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            ps.setInt(1, addr.getUserId());
            ps.setString(2, addr.getAddressLine1());
            ps.setString(3, addr.getAddressLine2());
            ps.setString(4, addr.getZipCode());
            ps.setString(5, addr.getState());
            ps.setString(6, addr.getCountry());
            ps.executeUpdate();

            try (ResultSet keys = ps.getGeneratedKeys()) {
                if (keys.next()) {
                    return keys.getInt(1);
                }
            }
        }
        throw new SQLException("Creating address failed, no ID obtained.");
    }

    public void updateAddress(UserAddress addr) throws SQLException {
        String sql = "UPDATE UserAddresses SET "
                + "AddressLine1 = ?, AddressLine2 = ?, ZipCode = ?, State = ?, Country = ? "
                + "WHERE AddressID = ?";
        try (Connection conn = DBConnection.get();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setString(1, addr.getAddressLine1());
            ps.setString(2, addr.getAddressLine2());
            ps.setString(3, addr.getZipCode());
            ps.setString(4, addr.getState());
            ps.setString(5, addr.getCountry());
            ps.setInt(6, addr.getAddressId());
            ps.executeUpdate();
        }
    }

    public void deleteAddress(int addressId) throws SQLException {
        String sql = "DELETE FROM UserAddresses WHERE AddressID = ?";
        try (Connection conn = DBConnection.get();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, addressId);
            ps.executeUpdate();
        }
    }

    private UserAddress mapAddress(ResultSet rs) throws SQLException {
        return new UserAddress(
                rs.getInt("AddressID"),
                rs.getInt("UserID"),
                rs.getString("AddressLine1"),
                rs.getString("AddressLine2"),
                rs.getString("ZipCode"),
                rs.getString("State"),
                rs.getString("Country")
        );
    }
}
