<?php

namespace App\Http\Controllers\Warehouse;

use App\Http\Controllers\Controller;
use App\Services\Warehouse\ItemService;
use App\Services\Warehouse\InventoryService;
use App\Services\Auth\RoleBasedAccessService;
use Illuminate\Http\Request;

class DashboardController extends Controller
{
    protected $itemService;
    protected $inventoryService;
    protected $accessService;

    public function __construct(
        ItemService $itemService,
        InventoryService $inventoryService,
        RoleBasedAccessService $accessService
    ) {
        $this->itemService = $itemService;
        $this->inventoryService = $inventoryService;
        $this->accessService = $accessService;

        $this->middleware('warehouse.access');
    }

    /**
     * Display the warehouse dashboard.
     */
    public function index()
    {
        try {
            // Get basic statistics
            $stats = [
                'total_items' => $this->getTotalItemsCount(),
                'low_stock_items' => $this->getLowStockItemsCount(),
                'total_locations' => $this->getTotalLocationsCount(),
                'pending_transactions' => $this->getPendingTransactionsCount(),
            ];

            // Get recent activities
            $recentActivities = $this->getRecentActivities();

            // Get low stock items (top 5)
            $lowStockItems = $this->getLowStockItems();

            // Get inventory summary by location
            $locationSummary = $this->getLocationSummary();

            // Get recent stock movements
            $recentMovements = $this->getRecentStockMovements();

            // Get inventory chart data by category
            $categoryChartData = $this->getInventoryByCategory();

            $response = response()->view('warehouse.dashboard.index', compact(
                'stats',
                'recentActivities',
                'lowStockItems',
                'locationSummary',
                'recentMovements',
                'categoryChartData'
            ));

            $response->header('Content-Type', 'text/html; charset=utf-8');
            return $response;
        } catch (\Exception $e) {
            // Log error and show basic dashboard
            \Log::error('Warehouse dashboard error: ' . $e->getMessage());

            return view('warehouse.dashboard.index', [
                'stats' => ['total_items' => 0, 'low_stock_items' => 0, 'total_locations' => 0, 'pending_transactions' => 0],
                'recentActivities' => collect(),
                'lowStockItems' => collect(),
                'locationSummary' => collect(),
                'recentMovements' => collect(),
                'categoryChartData' => ['labels' => [], 'data' => [], 'items_count' => []],
            ]);
        }
    }

    /**
     * Get quick stats for API.
     */
    public function quickStats()
    {
        return response()->json([
            'total_items' => $this->getTotalItemsCount(),
            'low_stock_items' => $this->getLowStockItemsCount(),
            'pending_transactions' => $this->getPendingTransactionsCount(),
        ]);
    }

    /**
     * Get total items count.
     */
    protected function getTotalItemsCount()
    {
        if (!class_exists('\App\Models\Warehouse\Item')) {
            return 0;
        }
        return \App\Models\Warehouse\Item::count();
    }

    /**
     * Get total locations count.
     */
    protected function getTotalLocationsCount()
    {
        if (!class_exists('\App\Models\Warehouse\Inventory')) {
            return 0;
        }
        return \App\Models\Warehouse\Inventory::distinct('location')->count('location');
    }

    /**
     * Get low stock items count.
     */
    protected function getLowStockItemsCount()
    {
        if (!class_exists('\App\Models\Warehouse\Inventory')) {
            return 0;
        }
        return \App\Models\Warehouse\Inventory::join('items', 'inventory.item_id', '=', 'items.id')
            ->where('items.reorder_point', '>', 0)
            ->where('inventory.quantity_available', '>', 0)
            ->whereColumn('inventory.quantity_available', '<=', 'items.reorder_point')
            ->count();
    }

    /**
     * Get low stock items details.
     */
    protected function getLowStockItems()
    {
        if (!class_exists('\App\Models\Warehouse\Inventory')) {
            return collect();
        }

        return \App\Models\Warehouse\Inventory::with('item')
            ->join('items', 'inventory.item_id', '=', 'items.id')
            ->select('inventory.*', 'items.reorder_point as item_reorder_point')
            ->where('items.reorder_point', '>', 0)
            ->where('inventory.quantity_available', '>', 0)
            ->whereColumn('inventory.quantity_available', '<=', 'items.reorder_point')
            ->orderBy('inventory.quantity_available', 'asc')
            ->limit(5)
            ->get()
            ->map(function ($inventory) {
                return [
                    'item_code' => $inventory->item->item_code ?? 'N/A',
                    'item_name' => $inventory->item->item_description ?? 'Unknown Item',
                    'current_stock' => $inventory->quantity_available,
                    'reorder_point' => $inventory->item_reorder_point,
                    'location' => $inventory->location ?? 'Default',
                ];
            });
    }

    /**
     * Get inventory levels by category for chart.
     */
    protected function getInventoryByCategory()
    {
        if (!class_exists('\App\Models\Warehouse\Inventory') || !class_exists('\App\Models\Warehouse\Item')) {
            return ['labels' => [], 'data' => []];
        }

        $categoryData = \App\Models\Warehouse\Inventory::join('items', 'inventory.item_id', '=', 'items.id')
            ->leftJoin('item_categories', 'items.category_id', '=', 'item_categories.id')
            ->selectRaw('
                COALESCE(item_categories.category_name, "Uncategorized") as category_name,
                SUM(inventory.quantity_available) as total_quantity,
                COUNT(inventory.id) as items_count
            ')
            ->groupBy('item_categories.category_name')
            ->orderByDesc('total_quantity')
            ->get();

        return [
            'labels' => $categoryData->pluck('category_name')->toArray(),
            'data' => $categoryData->pluck('total_quantity')->toArray(),
            'items_count' => $categoryData->pluck('items_count')->toArray(),
        ];
    }

    /**
     * Get pending transactions count.
     */
    protected function getPendingTransactionsCount()
    {
        $count = 0;

        // Count pending incoming transactions
        if (class_exists('\App\Models\Warehouse\IncomingTransaction')) {
            $count += \App\Models\Warehouse\IncomingTransaction::where('status', 'pending')->count();
        }

        // Count pending outgoing transactions
        if (class_exists('\App\Models\Warehouse\OutgoingTransaction')) {
            $count += \App\Models\Warehouse\OutgoingTransaction::whereIn('status', ['pending', 'approved'])->count();
        }

        // Count pending returns
        if (class_exists('\App\Models\Warehouse\ReturnTransaction')) {
            $count += \App\Models\Warehouse\ReturnTransaction::where('status', 'pending')->count();
        }

        return $count;
    }

    /**
     * Get recent activities.
     */
    protected function getRecentActivities()
    {
        $activities = collect();

        // Get recent stock movements
        if (class_exists('\App\Models\Warehouse\StockMovement')) {
            $stockMovements = \App\Models\Warehouse\StockMovement::with(['item', 'user'])
                ->orderBy('created_at', 'desc')
                ->limit(10)
                ->get()
                ->map(function ($movement) {
                    return [
                        'type' => 'stock_movement',
                        'description' => $this->formatStockMovementActivity($movement),
                        'user' => $movement->user?->name ?? 'System',
                        'created_at' => $movement->created_at,
                        'icon' => $this->getStockMovementIcon($movement->type),
                        'color' => $this->getStockMovementColor($movement->type),
                    ];
                });

            $activities = $activities->merge($stockMovements);
        }

        return $activities->sortByDesc('created_at')->take(10)->values();
    }

    /**
     * Format stock movement activity description.
     */
    protected function formatStockMovementActivity($movement)
    {
        $itemName = $movement->item?->name ?? 'Unknown Item';
        $quantity = $movement->quantity;

        switch ($movement->type) {
            case 'increase':
                return "Added {$quantity} units of {$itemName}";
            case 'decrease':
                return "Removed {$quantity} units of {$itemName}";
            case 'adjustment':
                return "Adjusted {$itemName} by {$quantity} units";
            case 'transfer_in':
                return "Received {$quantity} units of {$itemName} (transfer)";
            case 'transfer_out':
                return "Sent {$quantity} units of {$itemName} (transfer)";
            case 'reserve':
                return "Reserved {$quantity} units of {$itemName}";
            case 'release':
                return "Released {$quantity} units of {$itemName}";
            default:
                return "Stock movement: {$quantity} units of {$itemName}";
        }
    }

    /**
     * Get stock movement icon.
     */
    protected function getStockMovementIcon($type)
    {
        switch ($type) {
            case 'increase':
            case 'transfer_in':
                return 'add_circle';
            case 'decrease':
            case 'transfer_out':
                return 'remove_circle';
            case 'adjustment':
                return 'tune';
            case 'reserve':
                return 'bookmark';
            case 'release':
                return 'bookmark_border';
            default:
                return 'swap_horiz';
        }
    }

    /**
     * Get stock movement color.
     */
    protected function getStockMovementColor($type)
    {
        switch ($type) {
            case 'increase':
            case 'transfer_in':
                return 'success';
            case 'decrease':
            case 'transfer_out':
                return 'danger';
            case 'adjustment':
                return 'warning';
            case 'reserve':
            case 'release':
                return 'info';
            default:
                return 'secondary';
        }
    }

    /**
     * Get location summary.
     */
    protected function getLocationSummary()
    {
        if (!class_exists('\App\Models\Warehouse\Inventory')) {
            return collect();
        }

        return \App\Models\Warehouse\Inventory::selectRaw('
            COALESCE(location, "Default") as location,
            COUNT(*) as total_items,
            SUM(quantity_available) as total_quantity,
            SUM(quantity_reserved) as total_reserved
        ')
        ->groupBy(\DB::raw('COALESCE(location, "Default")'))
        ->orderByDesc('total_quantity')
        ->get()
        ->map(function ($location) {
            return [
                'name' => $location->location,
                'total_items' => (int) $location->total_items,
                'total_quantity' => (float) $location->total_quantity,
                'total_reserved' => (float) $location->total_reserved,
                'available_quantity' => (float) $location->total_quantity - (float) $location->total_reserved,
            ];
        });
    }

    /**
     * Get recent stock movements.
     */
    protected function getRecentStockMovements()
    {
        if (!class_exists('\App\Models\Warehouse\StockMovement')) {
            return collect();
        }

        return \App\Models\Warehouse\StockMovement::with(['item', 'user'])
            ->orderBy('created_at', 'desc')
            ->limit(10)
            ->get()
            ->map(function ($movement) {
                return [
                    'item_name' => $movement->item->name ?? 'Unknown Item',
                    'item_code' => $movement->item->item_code ?? 'N/A',
                    'type' => $movement->type,
                    'quantity' => $movement->quantity,
                    'reason' => $movement->reason ?: 'N/A',
                    'user_name' => $movement->user->name ?? 'System',
                    'created_at' => $movement->created_at,
                    'type_badge_class' => $this->getStockMovementColor($movement->type),
                ];
            });
    }
}