package com.nisum.dao;

import com.nisum.model.CartItem;

import com.nisum.model.Order;

import com.nisum.util.DBConnection;

import java.math.BigDecimal;

import java.sql.*;

import java.util.ArrayList;

import java.util.List;

public class OrderDAO {

    /**

     * Places an order: writes to Orders and OrderItems, returns new OrderID.

     */

    public static int placeOrder(int userId, int shippingAddrId, int billingAddrId,

                          String paymentMethod, List<CartItem> items, BigDecimal total)

            throws SQLException {

        String insertOrder = "INSERT INTO Orders "

                + "(UserID, ShippingAddressID, BillingAddressID, PaymentMethod, TotalAmount, OrderDate) "

                + "VALUES (?, ?, ?, ?, ?, NOW())";

        try (Connection conn = DBConnection.get()) {

            conn.setAutoCommit(false);

            int orderId;

            try (PreparedStatement ps = conn.prepareStatement(insertOrder, Statement.RETURN_GENERATED_KEYS)) {

                ps.setInt(1, userId);

                ps.setInt(2, shippingAddrId);

                ps.setInt(3, billingAddrId);

                ps.setString(4, paymentMethod);

                ps.setBigDecimal(5, total);

                ps.executeUpdate();

                try (ResultSet keys = ps.getGeneratedKeys()) {

                    if (!keys.next()) throw new SQLException("Order creation failed, no ID.");

                    orderId = keys.getInt(1);

                }

            }

            String insertItem = "INSERT INTO OrderItems (OrderID, ProductID, Quantity, Price) "

                    + "VALUES (?, ?, ?, ?)";

            try (PreparedStatement psItem = conn.prepareStatement(insertItem)) {

                for (CartItem ci : items) {

                    psItem.setInt(1, orderId);

                    psItem.setInt(2, ci.getCartItemId());

                    psItem.setInt(3, ci.getQuantity());

                    psItem.setDouble(4, ci.getFinalPrice());

                    psItem.addBatch();

                }

                psItem.executeBatch();

            }

            conn.commit();

            return orderId;

        }

    }

    /** Fetch a single order (basic info only). */

    public Order getById(int orderId) throws SQLException {

        String sql = "SELECT * FROM Orders WHERE OrderID = ?";

        try (Connection conn = DBConnection.get();

             PreparedStatement ps = conn.prepareStatement(sql)) {

            ps.setInt(1, orderId);

            try (ResultSet rs = ps.executeQuery()) {

                if (rs.next()) {

                    return mapOrder(rs);

                }

            }

        }

        return null;

    }

    /** List all orders for a user. */

    public List<Order> listByUser(int userId) throws SQLException {

        List<Order> list = new ArrayList<>();

        String sql = "SELECT * FROM Orders WHERE UserID = ? ORDER BY OrderDate DESC";

        try (Connection conn = DBConnection.get();

             PreparedStatement ps = conn.prepareStatement(sql)) {

            ps.setInt(1, userId);

            try (ResultSet rs = ps.executeQuery()) {

                while (rs.next()) {

                    list.add(mapOrder(rs));

                }

            }

        }

        return list;

    }

    private Order mapOrder(ResultSet rs) throws SQLException {

        return new Order(

                rs.getInt("OrderID"),

                rs.getInt("UserID"),

                rs.getInt("ShippingAddressID"),

                rs.getInt("BillingAddressID"),

                rs.getString("PaymentMethod"),

                rs.getBigDecimal("TotalAmount"),

                rs.getTimestamp("OrderDate")

        );

    }

}


