<?php

namespace App\Http\Controllers\Api\V1\Order;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\V1\Order\StoreOrderRequest;
use App\Http\Requests\Api\V1\Order\UpdateOrderRequest;
use App\Http\Requests\Api\V1\Order\StorePaymentRequest;
use App\Http\Requests\Api\V1\Order\ApplyDiscountRequest;
use App\Services\OrderService;
use App\Services\ResponseService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    public function __construct(
        protected OrderService $orderService,
        protected ResponseService $responseService
    ) {}

    public function index(): JsonResponse
    {
        $orders = $this->orderService->getAll();
        return $this->responseService->success($orders, 'Orders retrieved successfully');
    }

    public function forBranch(Request $request, int $branchId): JsonResponse
    {
        $limit = $request->get('limit', 50);
        $orders = $this->orderService->getForBranch($branchId, $limit);
        return $this->responseService->success($orders, 'Orders retrieved successfully');
    }

    public function activeForBranch(int $branchId): JsonResponse
    {
        $orders = $this->orderService->getActiveForBranch($branchId);
        return $this->responseService->success($orders, 'Active orders retrieved successfully');
    }

    public function activeAll(): JsonResponse
    {
        $orders = $this->orderService->getActiveAll();
        return $this->responseService->success($orders, 'Active orders retrieved successfully');
    }

    public function byStatus(int $branchId, string $status): JsonResponse
    {
        $validStatuses = ['pending', 'preparing', 'ready', 'completed', 'cancelled'];
        if (!in_array($status, $validStatuses)) {
            return $this->responseService->error('Invalid status', 422);
        }

        $orders = $this->orderService->getByStatus($branchId, $status);
        return $this->responseService->success($orders, 'Orders retrieved successfully');
    }

    public function todayForBranch(int $branchId): JsonResponse
    {
        $orders = $this->orderService->getTodayForBranch($branchId);
        return $this->responseService->success($orders, 'Today orders retrieved successfully');
    }

    public function store(StoreOrderRequest $request): JsonResponse
    {
        $data = $request->validated();
        $data['user_id'] = auth()->id();

        $order = $this->orderService->create($data);
        return $this->responseService->success($order, 'Order created successfully', 201);
    }

    public function show(int $id): JsonResponse
    {
        $order = $this->orderService->find($id);

        if (!$order) {
            return $this->responseService->error('Order not found', 404);
        }

        return $this->responseService->success($order, 'Order retrieved successfully');
    }

    public function update(UpdateOrderRequest $request, int $id): JsonResponse
    {
        $order = $this->orderService->find($id);

        if (!$order) {
            return $this->responseService->error('Order not found', 404);
        }

        $order = $this->orderService->update($id, $request->validated());
        return $this->responseService->success($order, 'Order updated successfully');
    }

    public function destroy(int $id): JsonResponse
    {
        $order = $this->orderService->find($id);

        if (!$order) {
            return $this->responseService->error('Order not found', 404);
        }

        $this->orderService->delete($id);
        return $this->responseService->success(null, 'Order deleted successfully');
    }

    public function updateStatus(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'status' => 'required|in:pending,preparing,ready,completed,cancelled',
            'notes' => 'nullable|string|max:500',
        ]);

        $order = $this->orderService->updateStatus(
            $id,
            $request->status,
            auth()->id(),
            $request->notes
        );

        if (!$order) {
            return $this->responseService->error('Order not found', 404);
        }

        return $this->responseService->success($order, 'Order status updated successfully');
    }

    public function cancel(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'reason' => 'nullable|string|max:500',
        ]);

        $order = $this->orderService->cancel($id, auth()->id(), $request->reason);

        if (!$order) {
            return $this->responseService->error('Order not found', 404);
        }

        return $this->responseService->success($order, 'Order cancelled successfully');
    }

    // Payment Endpoints
    public function payments(int $orderId): JsonResponse
    {
        $payments = $this->orderService->getPayments($orderId);
        return $this->responseService->success($payments, 'Payments retrieved successfully');
    }

    public function addPayment(StorePaymentRequest $request, int $orderId): JsonResponse
    {
        $data = $request->validated();
        $data['user_id'] = auth()->id();

        $payment = $this->orderService->addPayment($orderId, $data);

        if (!$payment) {
            return $this->responseService->error('Order not found', 404);
        }

        return $this->responseService->success($payment, 'Payment added successfully', 201);
    }

    public function refundPayment(Request $request, int $orderId, int $paymentId): JsonResponse
    {
        $request->validate([
            'notes' => 'nullable|string|max:500',
        ]);

        $payment = $this->orderService->refundPayment($paymentId, auth()->id(), $request->notes);
        return $this->responseService->success($payment, 'Payment refunded successfully');
    }

    // Discount
    public function applyDiscount(ApplyDiscountRequest $request, int $id): JsonResponse
    {
        $order = $this->orderService->applyDiscount(
            $id,
            $request->amount,
            $request->reason
        );

        if (!$order) {
            return $this->responseService->error('Order not found', 404);
        }

        return $this->responseService->success($order, 'Discount applied successfully');
    }

    // Reporting
    public function byDateRange(Request $request, int $branchId): JsonResponse
    {
        $request->validate([
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
        ]);

        $orders = $this->orderService->getOrdersByDateRange(
            $branchId,
            $request->start_date,
            $request->end_date
        );

        return $this->responseService->success($orders, 'Orders retrieved successfully');
    }

    public function dailySummary(Request $request, int $branchId): JsonResponse
    {
        $date = $request->get('date') ? \Carbon\Carbon::parse($request->date) : null;
        $summary = $this->orderService->getDailySummary($branchId, $date);
        return $this->responseService->success($summary, 'Daily summary retrieved successfully');
    }

    // Temporary Bill Endpoints
    public function createTempBill(StoreOrderRequest $request): JsonResponse
    {
        $data = $request->validated();
        $data['user_id'] = auth()->id();

        $tempBill = $this->orderService->createTempBill($data);
        return $this->responseService->success($tempBill, 'Temporary bill created successfully', 201);
    }

    public function getTempBills(int $branchId): JsonResponse
    {
        $tempBills = $this->orderService->getTempBillsForBranch($branchId);
        return $this->responseService->success($tempBills, 'Temporary bills retrieved successfully');
    }

    public function updateTempBill(UpdateOrderRequest $request, int $id): JsonResponse
    {
        try {
            $data = $request->validated();
            $tempBill = $this->orderService->updateTempBill($id, $data, auth()->id());
            return $this->responseService->success($tempBill, 'Temporary bill updated successfully');
        } catch (\Exception $e) {
            return $this->responseService->error($e->getMessage(), 422);
        }
    }

    public function finalizeTempBill(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'method' => 'required|in:cash,card,mobile,other',
            'amount' => 'required|numeric|min:0',
            'tendered' => 'nullable|numeric|min:0',
            'reference_number' => 'nullable|string|max:100',
            'notes' => 'nullable|string|max:500',
        ]);

        try {
            $paymentData = $request->only(['method', 'amount', 'tendered', 'reference_number', 'notes']);
            $order = $this->orderService->finalizeTempBill($id, $paymentData, auth()->id());
            return $this->responseService->success($order, 'Temporary bill finalized successfully');
        } catch (\Exception $e) {
            return $this->responseService->error($e->getMessage(), 422);
        }
    }

    public function getDuplicateBill(int $id): JsonResponse
    {
        $billData = $this->orderService->getDuplicateBillData($id);

        if (!$billData) {
            return $this->responseService->error('Bill not found', 404);
        }

        return $this->responseService->success($billData, 'Duplicate bill data retrieved successfully');
    }
}
