package dev.service;

import dev.dao.MenuItemDao;
import dev.dao.OrderDao;
import dev.dao.OrderDetailDao;
import dev.model.MenuItem;
import dev.model.Order;
import dev.model.OrderDetail;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class OrderService {
    private final MenuItemDao menuDao;
    private final OrderDao orderDao;
    private final OrderDetailDao detailDao;
    private final Scanner scanner;

    public OrderService() {
        this.menuDao = new MenuItemDao();
        this.orderDao = new OrderDao();
        this.detailDao = new OrderDetailDao();
        this.scanner = new Scanner(System.in);
    }

    public void placeOrder(int userId) {

        System.out.println("                [Placing Order]");

        List<MenuItem> menuItems = menuDao.findAll();
        if (menuItems.isEmpty()) {
            System.out.println("No menu items available!");
            return;
        }

        MenuService menuService = new MenuService();
        menuService.showMenu();

        List<OrderDetail> orderDetails = new ArrayList<>();
        double totalPrice = 0.0;

        while (true) {
            System.out.print("\nEnter item ID (or 0 to finish): ");
            int itemId = scanner.nextInt();

            if (itemId == 0) {
                if (orderDetails.isEmpty()) {
                    System.out.println("Cannot place empty order!");
                    return;
                }
                break;
            }

            MenuItem selectedItem = null;
            for (MenuItem item : menuItems) {
                if (item.getId() == itemId) {
                    selectedItem = item;
                    break;
                }
            }

            if (selectedItem == null) {
                System.out.println("Invalid item ID! Please try again.");
                continue;
            }

            System.out.print("Enter quantity: ");
            int quantity = scanner.nextInt();

            if (quantity <= 0) {
                System.out.println("Quantity must be greater than 0!");
                continue;
            }

            OrderDetail detail = new OrderDetail();
            detail.setMenuItemId(selectedItem.getId());
            detail.setQuantity(quantity);
            detail.setPrice(selectedItem.getPrice());
            detail.setItemName(selectedItem.getName());

            orderDetails.add(detail);

            double subtotal = selectedItem.getPrice() * quantity;
            totalPrice += subtotal;

            System.out.printf("Added %dx %s ($%.2f)\n",
                    quantity, selectedItem.getName(), subtotal);
        }

        Order order = new Order();
        order.setUserId(userId);
        order.setCreatedAt(new Timestamp(System.currentTimeMillis()));
        order.setTotalPrice(totalPrice);

        int orderId = orderDao.save(order);
        if (orderId == -1) {
            System.out.println("Failed to save order!");
            return;
        }

        for (OrderDetail detail : orderDetails) {
            detail.setOrderId(orderId);
            detailDao.save(detail);
        }

        System.out.println("\nOrder placed successfully! Order #" + orderId);
        printReceipt(orderId);
    }

    public void printReceipt(int orderId) {
        List<OrderDetail> details = detailDao.findByOrderId(orderId);

        if (details.isEmpty()) {
            System.out.println("Order not found or has no items!");
            return;
        }

        Order order = orderDao.findById(orderId);
        if (order == null) {
            System.out.println("Order not found!");
            return;
        }

        System.out.println("\n========================================");
        System.out.println("           ORDER RECEIPT");
        System.out.println("========================================");
        System.out.println("Order #: " + orderId);
        System.out.println("Date:   " + order.getCreatedAt());
        System.out.println("----------------------------------------");
        System.out.printf("%-5s %-20s %-10s %-10s %-10s\n",
                "ID", "Item", "Qty", "Price", "Subtotal");
        System.out.println("----------------------------------------");

        double grandTotal = 0.0;
        for (OrderDetail detail : details) {
            double subtotal = detail.getPrice() * detail.getQuantity();
            grandTotal += subtotal;

            String itemName = detail.getItemName() != null ?
                    detail.getItemName() : "Item #" + detail.getMenuItemId();

            System.out.printf("%-5d %-20s %-10d $%-9.2f $%-9.2f\n",
                    detail.getMenuItemId(),
                    itemName,
                    detail.getQuantity(),
                    detail.getPrice(),
                    subtotal
            );
        }

        System.out.println("----------------------------------------");
        System.out.printf("%-47s $%-9.2f\n", "GRAND TOTAL:", grandTotal);
        System.out.println("========================================");
        System.out.println("   Thank you for your order!");
        System.out.println("========================================\n");
    }

    public void showOrderHistory(int userId) {
        System.out.println("\n========================================");
        System.out.println("       ORDER HISTORY");
        System.out.println("========================================\n");

        List<Order> orders = orderDao.findByUserId(userId);

        if (orders.isEmpty()) {
            System.out.println("No orders found.");
            return;
        }

        System.out.println("You have " + orders.size() + " order(s):\n");
        System.out.printf("%-10s %-25s %-10s %-10s\n",
                "Order #", "Date", "Items", "Total");
        System.out.println("------------------------------------------------------------");

        for (Order order : orders) {
            List<OrderDetail> details = detailDao.findByOrderId(order.getId());

            int itemCount = 0;
            for (OrderDetail detail : details) {
                itemCount += detail.getQuantity();
            }

            System.out.printf("%-10d %-25s %-10d $%-9.2f\n",
                    order.getId(),
                    order.getCreatedAt().toString().substring(0, 19),
                    itemCount,
                    order.getTotalPrice()
            );
        }

        System.out.println("------------------------------------------------------------\n");

        System.out.print("Enter order ID to view details (or 0 to return): ");
        int orderId = scanner.nextInt();

        if (orderId > 0) {
            printReceipt(orderId);
        }
    }
}