package dev.service;

import dev.dao.MenuItemDao;
import dev.database.DatabaseConnection;
import dev.model.MenuItem;

import java.sql.*;
import java.util.Scanner;

public class OrderService {
    private final MenuItemDao menuItemDao = new MenuItemDao();
    private final Scanner scanner = new Scanner(System.in);

    public void placeOrder(int userId) {
        Connection conn = null;
        try {
            conn = DatabaseConnection.getConnection();
            conn.setAutoCommit(false);

            String insertOrderSql = "INSERT INTO orders (user_id, total_price) VALUES (?, 0.00)";
            PreparedStatement orderStmt = conn.prepareStatement(insertOrderSql, Statement.RETURN_GENERATED_KEYS);
            orderStmt.setInt(1, userId);
            orderStmt.executeUpdate();

            ResultSet generatedKeys = orderStmt.getGeneratedKeys();
            int orderId = 0;
            if (generatedKeys.next()) {
                orderId = generatedKeys.getInt(1);
            }

            double grandTotal = 0.0;
            boolean addingItems = true;
            String insertDetailSql = "INSERT INTO order_details (order_id, menu_item_id, quantity, price_at_purchase) VALUES (?, ?, ?, ?)";
            PreparedStatement detailStmt = conn.prepareStatement(insertDetailSql);

            while (addingItems) {
                System.out.print("Enter Menu Item ID to add (or 0 to finish): ");
                int itemId = scanner.nextInt();
                if (itemId == 0) {
                    addingItems = false;
                    continue;
                }

                MenuItem item = menuItemDao.findById(itemId);
                if (item == null) {
                    System.out.println("Invalid Item ID. Try again.");
                    continue;
                }

                System.out.print("Enter quantity: ");
                int quantity = scanner.nextInt();
                if (quantity <= 0) {
                    System.out.println("Quantity must be greater than zero.");
                    continue;
                }

                double subtotal = (item.getPrice()) * quantity;
                grandTotal += subtotal;

                detailStmt.setInt(1, orderId);
                detailStmt.setInt(2, item.getId());
                detailStmt.setInt(3, quantity);
                detailStmt.setDouble(4, item.getPrice());
                detailStmt.executeUpdate();
            }

            if (grandTotal == 0.0) {
                System.out.println("No items selected. Canceling order.");
                conn.rollback();
                return;
            }

            String updateOrderSql = "UPDATE orders SET total_price = ? WHERE id = ?";
            PreparedStatement updateStmt = conn.prepareStatement(updateOrderSql);
            updateStmt.setDouble(1, grandTotal);
            updateStmt.setInt(2, orderId);
            updateStmt.executeUpdate();

            conn.commit();
            System.out.println("Order successfully saved!");
            printReceipt(orderId);

        } catch (SQLException e) {
            System.out.println("Order failed: " + e.getMessage());
            if (conn != null) {
                try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); }
            }
        }
    }

    public void printReceipt(int orderId) {

        String sql = "SELECT od.quantity, od.price_at_purchase, m.name, o.total_price " +
                "FROM order_details od " +
                "JOIN menu_items m ON od.menu_item_id = m.id " +
                "JOIN orders o ON od.order_id = o.id " +
                "WHERE od.order_id = ?";

        try (Connection conn = DatabaseConnection.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, orderId);
            try (ResultSet rs = pstmt.executeQuery()) {
                System.out.println("\n========= RECEIPT (Order #" + orderId + ") =========");
                double grandTotal = 0.0;
                boolean hasRows = false;

                while (rs.next()) {
                    hasRows = true;
                    String name = rs.getString("name");
                    int qty = rs.getInt("quantity");
                    double price = rs.getDouble("price_at_purchase");
                    double subtotal = qty * price;
                    grandTotal = rs.getDouble("total_price");

                    System.out.printf("- %s x%d @ $%.2f = $%.2f\n", name, qty, price, subtotal);
                }
                if (!hasRows) {
                    System.out.println("Order not found.");
                    return;
                }
                System.out.println("----------------------------------------");
                System.out.printf("GRAND TOTAL: $%.2f\n", grandTotal);
                System.out.println("========================================");
            }
        } catch (SQLException e) {
            System.out.println("Error generating receipt: " + e.getMessage());
        }
    }

    public void showOrderHistory(int userId) {
        String sql = "SELECT id, created_at, total_price FROM orders WHERE user_id = ? ORDER BY created_at DESC";

        try (Connection conn = DatabaseConnection.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, userId);
            try (ResultSet rs = pstmt.executeQuery()) {
                System.out.println("\n===== YOUR ORDER HISTORY =====");
                boolean hasHistory = false;
                while (rs.next()) {
                    hasHistory = true;
                    System.out.printf("Order #%d | Date: %s | Total Spent: $%.2f\n",
                            rs.getInt("id"),
                            rs.getTimestamp("created_at").toString(),
                            rs.getDouble("total_price")
                    );
                }
                if (!hasHistory) {
                    System.out.println("You haven't placed any orders yet.");
                }
            }
        } catch (SQLException e) {
            System.out.println("Error fetching history: " + e.getMessage());
        }
    }

}