<?php

namespace App\Services;

use App\Models\Order;
use App\Models\OrderItem;
use App\Models\BillModification;
use Illuminate\Support\Facades\DB;

class TempBillService
{
    /**
     * Create a new temporary bill
     */
    public function createTempBill(array $data): Order
    {
        return DB::transaction(function () use ($data) {
            // Create order as temp bill
            $order = Order::create([
                'branch_id' => $data['branch_id'],
                'user_id' => auth()->id(),
                'order_number' => Order::generateTempOrderNumber($data['branch_id']),
                'status' => Order::STATUS_TEMP_BILL,
                'bill_type' => Order::BILL_TYPE_TEMP,
                'is_temp_bill' => true,
                'order_type' => $data['order_type'] ?? Order::TYPE_DINE_IN,
                'table_number' => $data['table_number'] ?? null,
                'customer_name' => $data['customer_name'] ?? null,
                'customer_phone' => $data['customer_phone'] ?? null,
                'tax_amount' => $data['tax_amount'] ?? 0,
                'tax_rate' => $data['tax_rate'] ?? 0,
                'notes' => 'TEMP BILL - NOT PAID',
            ]);

            // Add items
            foreach ($data['items'] as $itemData) {
                $this->addItemToTempBill($order, $itemData, false);
            }

            // Calculate totals
            $order->calculateTotals();
            $order->save();

            return $order->fresh(['items.product', 'payments']);
        });
    }

    /**
     * Add item to temp bill
     */
    public function addItemToTempBill(Order $order, array $itemData, bool $recalculate = true): OrderItem
    {
        if (!$order->canBeEdited()) {
            throw new \Exception('This bill is locked and cannot be edited');
        }

        $item = $order->items()->create([
            'product_id' => $itemData['product_id'],
            'product_name' => $itemData['product_name'],
            'quantity' => $itemData['quantity'],
            'unit_price' => $itemData['unit_price'],
            'total_price' => $itemData['unit_price'] * $itemData['quantity'],
            'selected_options' => $itemData['selected_options'] ?? [],
            'selected_inner_options' => $itemData['selected_inner_options'] ?? [],
            'notes' => $itemData['notes'] ?? null,
        ]);

        // Log modification
        $this->logModification($order, 'item_added', null, [
            'item_id' => $item->id,
            'product_id' => $item->product_id,
            'quantity' => $item->quantity,
        ]);

        // Recalculate order totals
        if ($recalculate) {
            $order->calculateTotals();
            $order->save();
        }

        return $item;
    }

    /**
     * Remove item from temp bill
     */
    public function removeItemFromTempBill(Order $order, int $itemId): void
    {
        if (!$order->canBeEdited()) {
            throw new \Exception('This bill is locked and cannot be edited');
        }

        $item = $order->items()->findOrFail($itemId);

        // Log modification
        $this->logModification($order, 'item_removed', [
            'item_id' => $item->id,
            'product_id' => $item->product_id,
            'quantity' => $item->quantity,
        ], null);

        $item->delete();

        // Recalculate order totals
        $order->calculateTotals();
        $order->save();
    }

    /**
     * Update item quantity in temp bill
     */
    public function updateItemQuantity(Order $order, int $itemId, int $newQuantity): OrderItem
    {
        if (!$order->canBeEdited()) {
            throw new \Exception('This bill is locked and cannot be edited');
        }

        $item = $order->items()->findOrFail($itemId);
        $oldQuantity = $item->quantity;

        $item->quantity = $newQuantity;
        $item->total_price = $item->unit_price * $item->quantity;
        $item->save();

        // Log modification
        $this->logModification($order, 'quantity_changed', [
            'item_id' => $item->id,
            'old_quantity' => $oldQuantity,
        ], [
            'item_id' => $item->id,
            'new_quantity' => $newQuantity,
        ]);

        // Recalculate order totals
        $order->calculateTotals();
        $order->save();

        return $item;
    }

    /**
     * Lock temp bill for payment (prevent further edits)
     */
    public function lockForPayment(Order $order): Order
    {
        if (!$order->isTempBill()) {
            throw new \Exception('Only temp bills can be locked');
        }

        if ($order->items->isEmpty()) {
            throw new \Exception('Cannot lock an empty bill');
        }

        $order->locked_at = now();
        $order->status = Order::STATUS_AWAITING_PAYMENT;
        $order->save();

        return $order;
    }

    /**
     * Cancel temp bill
     */
    public function cancelTempBill(Order $order, string $reason = null): Order
    {
        if (!$order->isTempBill() && $order->status !== Order::STATUS_AWAITING_PAYMENT) {
            throw new \Exception('Only temp bills can be cancelled');
        }

        return DB::transaction(function () use ($order, $reason) {
            // If any payment was received, handle refund
            if ($order->payment_received > 0) {
                // This would integrate with your CashRegisterService
                // For now, we'll just log it
                $this->logModification($order, 'cancelled_with_refund', [
                    'refund_amount' => $order->payment_received,
                ], null);
            }

            $order->status = Order::STATUS_CANCELLED;
            $order->cancelled_at = now();
            $order->cancellation_reason = $reason ?? 'No reason provided';
            $order->notes = ($order->notes ?? '') . "\nCANCELLED: " . ($reason ?? 'No reason provided');
            $order->save();

            return $order;
        });
    }

    /**
     * Log bill modification
     */
    private function logModification(Order $order, string $type, $oldValue, $newValue): void
    {
        BillModification::create([
            'order_id' => $order->id,
            'user_id' => auth()->id(),
            'modification_type' => $type,
            'old_value' => $oldValue,
            'new_value' => $newValue,
        ]);
    }
}
