<?php

namespace App\Modules\TakingOrder\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\VisitPlan;
use App\Models\Category;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Product;
use App\Modules\TakingOrder\Requests\StoreOrderRequest;
use App\Modules\TakingOrder\Services\OrderService;
use Inertia\Inertia;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class OrderController extends Controller
{
    protected $orderService;

    public function __construct(OrderService $orderService)
    {
        $this->orderService = $orderService;
    }

    /**
     * Dashboard - Menampilkan customer yang harus dikunjungi hari ini
     */
    public function dashboard()
    {
        $today = now()->toDateString();
        $userId = Auth::id();

        Log::info('Dashboard accessed - User ID: ' . $userId);

        $visits = VisitPlan::with('customer')
            ->where('user_id', $userId)
            ->where('visit_date', $today)
            ->where('status', 'pending')
            ->get()
            ->map(function ($visit) {
                // Cek apakah customer sudah memiliki order hari ini
                $orderCount = Order::where('user_id', Auth::id())
                    ->where('customer_id', $visit->customer->id)
                    ->whereDate('created_at', now()->toDateString())
                    ->count();

                return [
                    'id' => $visit->id,
                    'has_order' => $orderCount > 0,
                    'order_count' => $orderCount,
                    'customer' => [
                        'id' => $visit->customer->id,
                        'name' => $visit->customer->name,
                        'address' => $visit->customer->address,
                        'phone' => $visit->customer->phone,
                        'plafon' => $visit->customer->plafon,
                    ]
                ];
            });

        Log::info('Visits found: ' . $visits->count());

        return Inertia::render('Sales/Dashboard', [
            'visits' => $visits,
            'today' => $today
        ]);
    }

    /**
     * Halaman Order untuk customer tertentu
     */
    public function orderForm(Customer $customer)
    {
        $userId = Auth::id();

        // Validasi customer dijadwalkan hari ini
        $visit = VisitPlan::where('user_id', $userId)
            ->where('customer_id', $customer->id)
            ->where('visit_date', now()->toDateString())
            ->first();

        if (!$visit) {
            abort(403, 'Customer tidak dijadwalkan untuk hari ini');
        }

        // Ambil order pending hari ini untuk customer ini
        $existingOrder = Order::with(['items'])
            ->where('user_id', $userId)
            ->where('customer_id', $customer->id)
            ->where('status', 'pending')
            ->whereDate('created_at', now()->toDateString())
            ->first();

        // Buat array untuk mapping product_id => qty dari order yang sudah ada
        $existingQty = [];
        if ($existingOrder) {
            foreach ($existingOrder->items as $item) {
                $existingQty[$item->product_id] = $item->qty;
            }
        }

        // Ambil semua kategori dengan produknya (yang stock > 0)
        $categories = Category::with(['products' => function ($query) {
            $query->where('stock', '>', 0)
                ->select(
                    'id',
                    'category_id',
                    'name',
                    'sku',
                    'price',
                    'stock',
                    'image',
                    'description',
                    'bulk_unit',
                    'bulk_quantity',
                    'retail_unit'
                );
        }])
            ->orderBy('sequence')
            ->get()
            ->map(function ($category) use ($existingQty) {
                return [
                    'id' => $category->id,
                    'name' => $category->name,
                    'products' => $category->products->map(function ($product) use ($existingQty) {
                        // Hitung retail_price dari price / bulk_quantity
                        $retailPrice = $product->bulk_quantity > 0
                            ? $product->price / $product->bulk_quantity
                            : $product->price;

                        return [
                            'id' => $product->id,
                            'name' => $product->name,
                            'sku' => $product->sku,
                            'price' => $product->price, // bulk_price
                            'stock' => $product->stock,
                            'image' => $product->image,
                            'description' => $product->description,
                            'existing_qty' => $existingQty[$product->id] ?? 0,
                            'bulk_unit' => $product->bulk_unit ?? 'Karton',
                            'bulk_quantity' => $product->bulk_quantity ?? 1,
                            'retail_price' => $retailPrice, // Hasil perhitungan
                            'retail_unit' => $product->retail_unit ?? 'pcs',
                        ];
                    })
                ];
            });

        return Inertia::render('Sales/OrderForm', [
            'customer' => [
                'id' => $customer->id,
                'name' => $customer->name,
                'address' => $customer->address,
                'phone' => $customer->phone,
                'plafon' => $customer->plafon,
            ],
            'categories' => $categories,
            'existing_order_id' => $existingOrder ? $existingOrder->id : null,
        ]);
    }

    /**
     * Sync orders from offline storage
     */
    public function syncOrders(Request $request)
    {
        try {
            $orders = $request->input('orders', []);
            $synced = [];
            $failed = [];

            foreach ($orders as $orderData) {
                try {
                    // Simpan order
                    $order = $this->orderService->createOrder(
                        Auth::id(),
                        $orderData['customer_id'],
                        $orderData['items'],
                        $orderData['notes'] ?? null
                    );
                    $synced[] = $order->id;
                } catch (\Exception $e) {
                    $failed[] = $orderData;
                    Log::error('Sync order failed: ' . $e->getMessage());
                }
            }

            return response()->json([
                'success' => true,
                'synced' => $synced,
                'failed' => $failed,
                'message' => count($synced) . ' orders synced successfully'
            ]);
        } catch (\Exception $e) {
            Log::error('Sync orders failed: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Sync failed: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Menyimpan order (status pending)
     */
    public function storeOrder(StoreOrderRequest $request)
    {
        try {
            $order = $this->orderService->createOrder(
                Auth::id(),
                $request->customer_id,
                $request->items,
                $request->notes ?? null
            );

            return redirect()->route('sales.taking-order.dashboard')
                ->with('success', 'Order berhasil disimpan dengan status PENDING');
        } catch (\Exception $e) {
            Log::error('Store order failed: ' . $e->getMessage());
            return back()->with('error', 'Gagal menyimpan order: ' . $e->getMessage());
        }
    }

    /**
     * Update existing order (tambah item ke order yang sudah ada)
     */
    public function updateOrder(Order $order, StoreOrderRequest $request)
    {
        // Validasi kepemilikan order
        if ($order->user_id !== Auth::id()) {
            abort(403, 'Anda tidak memiliki akses ke order ini');
        }

        // Validasi status order harus pending
        if ($order->status !== 'pending') {
            return back()->with('error', 'Order sudah diproses, tidak bisa diupdate');
        }

        try {
            // Update order dengan items baru
            $this->orderService->updateOrder($order, $request->items);

            return redirect()->route('sales.taking-order.dashboard')
                ->with('success', 'Order berhasil diupdate!');
        } catch (\Exception $e) {
            Log::error('Update order failed: ' . $e->getMessage());
            return back()->with('error', 'Gagal mengupdate order: ' . $e->getMessage());
        }
    }

    /**
     * Memproses PO (ubah status menjadi processed)
     */
    public function processOrder(Order $order)
    {
        try {
            // Validasi kepemilikan order
            if ($order->user_id !== Auth::id()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Anda tidak memiliki akses ke order ini'
                ], 403);
            }

            // Validasi status
            if ($order->status !== 'pending') {
                return response()->json([
                    'success' => false,
                    'message' => 'Order sudah diproses sebelumnya'
                ], 400);
            }

            // Proses order
            $result = $this->orderService->processOrder($order);

            if ($result) {
                return response()->json([
                    'success' => true,
                    'message' => 'Berhasil PO! Order telah dikirim ke backoffice'
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => 'Gagal memproses PO'
            ], 500);
        } catch (\Exception $e) {
            Log::error('Process order failed: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal memproses PO: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Menampilkan daftar order pending untuk diproses (Inertia)
     */
    public function pendingOrders()
    {
        $orders = Order::with(['customer', 'items.product'])
            ->where('user_id', Auth::id())
            ->where('status', 'pending')
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(function ($order) {
                // Cek apakah semua item retail atau bulk
                $hasRetail = $order->items->contains('unit_type', 'retail');
                $hasBulk = $order->items->contains('unit_type', 'bulk');

                $orderType = 'bulk'; // default
                if ($hasRetail && !$hasBulk) {
                    $orderType = 'retail';
                } elseif ($hasRetail && $hasBulk) {
                    $orderType = 'mixed';
                }

                return [
                    'id' => $order->id,
                    'invoice_code' => $order->invoice_code,
                    'total_amount' => $order->total_amount,
                    'status' => $order->status,
                    'created_at' => $order->created_at,
                    'order_type' => $orderType, // retail, bulk, atau mixed
                    'customer' => [
                        'id' => $order->customer->id,
                        'name' => $order->customer->name,
                        'address' => $order->customer->address,
                        'phone' => $order->customer->phone,
                    ],
                    'items' => $order->items->map(function ($item) {
                        return [
                            'id' => $item->id,
                            'qty' => $item->qty,
                            'price' => $item->price,
                            'unit_type' => $item->unit_type ?? 'bulk',
                            'unit_name' => $item->unit_name ?? ($item->unit_type === 'retail' ? 'pcs' : 'Karton'),
                            'product' => [
                                'id' => $item->product->id,
                                'name' => $item->product->name,
                                'sku' => $item->product->sku,
                            ]
                        ];
                    })
                ];
            });

        return Inertia::render('Sales/OrderList', [
            'orders' => $orders
        ]);
    }

    /**
     * API endpoint untuk mengambil data pending orders (JSON)
     */
    public function getPendingOrdersData()
    {
        try {
            $userId = Auth::id();

            if (!$userId) {
                return response()->json([
                    'success' => false,
                    'message' => 'User not authenticated'
                ], 401);
            }

            $orders = Order::with(['customer', 'items.product'])
                ->where('user_id', $userId)
                ->where('status', 'pending')
                ->orderBy('created_at', 'desc')
                ->get()
                ->map(function ($order) {
                    return [
                        'id' => $order->id,
                        'invoice_code' => $order->invoice_code,
                        'total_amount' => $order->total_amount,
                        'status' => $order->status,
                        'created_at' => $order->created_at,
                        'formatted_date' => $order->created_at ? $order->created_at->format('d/m/Y H:i') : null,
                        'customer' => [
                            'id' => $order->customer->id ?? null,
                            'name' => $order->customer->name ?? 'Unknown',
                            'address' => $order->customer->address ?? '-',
                            'phone' => $order->customer->phone ?? '-',
                        ],
                        'items' => $order->items->map(function ($item) {
                            return [
                                'id' => $item->id,
                                'qty' => $item->qty,
                                'price' => $item->price,
                                'subtotal' => $item->price * $item->qty,
                                'product' => [
                                    'id' => $item->product->id ?? null,
                                    'name' => $item->product->name ?? 'Produk tidak ditemukan',
                                    'sku' => $item->product->sku ?? '-',
                                ]
                            ];
                        }),
                        'total_items' => $order->items->sum('qty')
                    ];
                });

            return response()->json([
                'success' => true,
                'orders' => $orders,
                'total' => $orders->count()
            ]);
        } catch (\Exception $e) {
            Log::error('Error fetching pending orders: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Failed to load orders',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update order item (ubah quantity)
     */
    public function updateOrderItem(Order $order, OrderItem $item, Request $request)
    {
        // Validasi kepemilikan order
        if ($order->user_id !== Auth::id()) {
            return response()->json(['success' => false, 'message' => 'Unauthorized'], 403);
        }

        // Validasi status order harus pending
        if ($order->status !== 'pending') {
            return response()->json(['success' => false, 'message' => 'Order sudah diproses'], 400);
        }

        // Validasi item milik order ini
        if ($item->order_id !== $order->id) {
            return response()->json(['success' => false, 'message' => 'Item tidak valid'], 400);
        }

        $request->validate([
            'qty' => 'required|integer|min:1|max:999'
        ]);

        try {
            $product = Product::find($item->product_id);
            $oldQty = $item->qty;
            $newQty = $request->qty;

            // Cek stok
            $stockAvailable = $product->stock + $oldQty;
            if ($newQty > $stockAvailable) {
                return response()->json([
                    'success' => false,
                    'message' => "Stok tidak mencukupi. Stok tersedia: {$stockAvailable}"
                ], 400);
            }

            // Update stock
            $stockDiff = $oldQty - $newQty;
            if ($stockDiff > 0) {
                $product->increment('stock', $stockDiff);
            } else {
                $product->decrement('stock', abs($stockDiff));
            }

            // Update item
            $item->update(['qty' => $newQty]);

            // Update total order
            $this->recalculateOrderTotal($order);

            Log::info('Order item updated', [
                'order_id' => $order->id,
                'item_id' => $item->id,
                'old_qty' => $oldQty,
                'new_qty' => $newQty
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Item berhasil diupdate',
                'order' => $this->getOrderData($order)
            ]);
        } catch (\Exception $e) {
            Log::error('Update order item failed: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengupdate item: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Delete order item
     */
    public function deleteOrderItem($orderId, $itemId)
    {
        try {
            // Cari order dengan relasi
            $order = Order::with(['customer', 'items.product'])->find($orderId);
            if (!$order) {
                return response()->json([
                    'success' => false,
                    'message' => 'Order tidak ditemukan'
                ], 404);
            }

            // Validasi kepemilikan order
            if ($order->user_id !== Auth::id()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized'
                ], 403);
            }

            // Validasi status order
            if ($order->status !== 'pending') {
                return response()->json([
                    'success' => false,
                    'message' => 'Order sudah diproses'
                ], 400);
            }

            // Cari item
            $item = OrderItem::find($itemId);
            if (!$item) {
                return response()->json([
                    'success' => false,
                    'message' => 'Item tidak ditemukan'
                ], 404);
            }

            // Validasi item milik order
            if ($item->order_id !== $order->id) {
                return response()->json([
                    'success' => false,
                    'message' => 'Item tidak valid'
                ], 400);
            }

            // Kembalikan stock
            $product = Product::find($item->product_id);
            if ($product) {
                $product->increment('stock', $item->qty);
            }

            // Hapus item
            $item->delete();

            // Recalculate total
            $this->recalculateOrderTotal($order);

            // Refresh order data
            $order->refresh();
            $order->load(['customer', 'items.product']);

            // Cek jika tidak ada item, hapus order
            if ($order->items()->count() === 0) {
                $order->delete();
                return response()->json([
                    'success' => true,
                    'message' => 'Order dihapus karena tidak ada item',
                    'order_deleted' => true
                ]);
            }

            // Ambil data order terbaru
            $orderData = $this->getOrderData($order);

            return response()->json([
                'success' => true,
                'message' => 'Item berhasil dihapus',
                'order' => $orderData
            ]);
        } catch (\Exception $e) {
            Log::error('Delete order item failed: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal menghapus item: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Delete entire order
     */
    public function deleteOrder(Order $order)
    {
        // Validasi kepemilikan order
        if ($order->user_id !== Auth::id()) {
            return response()->json(['success' => false, 'message' => 'Unauthorized'], 403);
        }

        // Validasi status order harus pending
        if ($order->status !== 'pending') {
            return response()->json(['success' => false, 'message' => 'Order sudah diproses'], 400);
        }

        try {
            // Kembalikan semua stock
            foreach ($order->items as $item) {
                $product = Product::find($item->product_id);
                if ($product) {
                    $product->increment('stock', $item->qty);
                }
            }

            // Hapus order (cascade akan menghapus items)
            $order->delete();

            Log::info('Order deleted', [
                'order_id' => $order->id,
                'user_id' => Auth::id()
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Order berhasil dihapus'
            ]);
        } catch (\Exception $e) {
            Log::error('Delete order failed: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal menghapus order: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Recalculate order total
     */
    private function recalculateOrderTotal(Order $order)
    {
        // ⚠️ PASTIKAN: total = qty × harga_satuan (bukan price)
        $total = $order->items()->sum(DB::raw('qty * harga_satuan'));
        $order->update(['total_amount' => $total]);
    }

    /**
     * Get order data with relationships
     */
    private function getOrderData(Order $order)
    {
        // Refresh order data
        $order->refresh();
        $order->load(['customer', 'items.product']);

        return [
            'id' => $order->id,
            'invoice_code' => $order->invoice_code,
            'total_amount' => $order->total_amount,
            'status' => $order->status,
            'created_at' => $order->created_at,
            'customer' => [
                'id' => $order->customer->id,
                'name' => $order->customer->name,
                'address' => $order->customer->address,
                'phone' => $order->customer->phone,
            ],
            'items' => $order->items->map(function ($item) {
                return [
                    'id' => $item->id,
                    'qty' => $item->qty,
                    'price' => $item->price,
                    'subtotal' => $item->price * $item->qty,
                    'product' => [
                        'id' => $item->product->id,
                        'name' => $item->product->name,
                        'sku' => $item->product->sku,
                        'stock' => $item->product->stock,
                    ]
                ];
            }),
            'total_items' => $order->items->sum('qty')
        ];
    }

    /**
     * API: Get pending orders untuk backoffice
     */
    public function apiGetPendingOrders()
    {
        $orders = Order::with(['customer', 'user', 'items.product'])
            ->where('status', 'pending')
            ->orderBy('created_at', 'asc')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $orders,
            'total' => $orders->count()
        ]);
    }

    /**
     * API: Sync orders dari backoffice (mark as processed)
     */
    public function apiSyncOrders(Request $request)
    {
        $request->validate([
            'order_ids' => 'required|array',
            'order_ids.*' => 'exists:orders,id'
        ]);

        DB::beginTransaction();
        try {
            $updated = Order::whereIn('id', $request->order_ids)
                ->where('status', 'pending')
                ->update(['status' => 'processed']);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => "{$updated} orders synced successfully",
                'synced_count' => $updated
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Sync orders failed: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Failed to sync orders',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get detail order by ID
     */
    public function getOrderDetail($id)
    {
        $order = Order::with(['customer', 'items.product'])
            ->where('user_id', Auth::id())
            ->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $order
        ]);
    }
}
