<?php
namespace App\Http\Controllers\Warehouse\FixedAssets;

use App\Http\Controllers\Controller;
use App\Models\Warehouse\FixedAssets\FixedAsset;
use App\Models\Warehouse\FixedAssets\FixedAssetCategory;
use App\Models\Warehouse\FixedAssets\FixedAssetMovement;
use App\Models\Warehouse\Project;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class FixedAssetInventoryController extends Controller
{
    public function __construct()
    {
        $this->middleware('warehouse.access');
        $this->middleware('warehouse.permission:warehouse.fixed-asset-inventory.view');
    }

    public function index()
    {
        $totalAssets = FixedAsset::where('status', 'active')->count();
        $inWarehouse = FixedAsset::active()->inWarehouse()->count();
        $inUse = FixedAsset::active()->inUse()->count();
        $underMaintenance = FixedAsset::active()->where('lifecycle_status', 'under_maintenance')->count();
        $disposed = FixedAsset::where('lifecycle_status', 'disposed')->count();

        $totalPurchaseValue = FixedAsset::where('status', 'active')->sum('purchase_price');
        $totalBookValue = FixedAsset::where('status', 'active')->sum('current_book_value');
        $totalDepreciation = $totalPurchaseValue - $totalBookValue;

        $byCategory = FixedAssetCategory::withCount(['assets' => fn($q) => $q->where('status', 'active')])
            ->where('status', 'active')
            ->orderBy('category_name')
            ->get();

        $byCondition = FixedAsset::where('status', 'active')
            ->selectRaw('`condition`, count(*) as count')
            ->groupBy('condition')
            ->get();

        $byLifecycle = FixedAsset::where('status', 'active')
            ->selectRaw('lifecycle_status, count(*) as count, sum(purchase_price) as total_purchase_value, sum(current_book_value) as total_book_value')
            ->groupBy('lifecycle_status')
            ->get();

        $recentMovements = FixedAssetMovement::with(['fixedAsset', 'performedBy'])
            ->latest('movement_date')
            ->take(10)
            ->get();

        return view('warehouse.fixed-assets.inventory.index', compact(
            'totalAssets', 'inWarehouse', 'inUse', 'underMaintenance', 'disposed',
            'totalPurchaseValue', 'totalBookValue', 'totalDepreciation',
            'byCategory', 'byCondition', 'byLifecycle', 'recentMovements'
        ));
    }

    public function projectAssets(Request $request)
    {
        $query = FixedAsset::where('lifecycle_status', 'in_use')
            ->whereNotNull('current_project_id')
            ->with(['category', 'currentProject', 'currentDivision']);

        if ($request->filled('project_id')) {
            $query->where('current_project_id', $request->project_id);
        }

        $assets = $query->orderBy('asset_name')->paginate(25)->withQueryString();
        $projects = Project::active()->orderBy('project_name')->get();

        return view('warehouse.fixed-assets.inventory.project-assets', compact('assets', 'projects'));
    }

    public function warehouseAssets(Request $request)
    {
        $query = FixedAsset::inWarehouse()->with(['category']);

        if ($request->filled('category_id')) {
            $query->where('category_id', $request->category_id);
        }
        if ($request->filled('condition')) {
            $query->where('condition', $request->condition);
        }

        $assets = $query->orderBy('asset_name')->paginate(25)->withQueryString();
        $categories = FixedAssetCategory::where('status', 'active')->orderBy('category_name')->get();

        return view('warehouse.fixed-assets.inventory.warehouse-assets', compact('assets', 'categories'));
    }

    public function conditionReport()
    {
        $query = FixedAsset::where('status', 'active')
            ->with(['category', 'currentProject'])
            ->orderBy('condition')
            ->orderBy('asset_name');

        $conditionSummary = (clone $query)
            ->reorder()
            ->selectRaw('`condition`, count(*) as count')
            ->groupBy('condition')
            ->get()
            ->mapWithKeys(fn ($row) => [
                $row->condition => ['count' => (int) $row->count],
            ]);

        $assets = $query->paginate(25)->withQueryString();

        return view('warehouse.fixed-assets.inventory.condition-report', compact('assets', 'conditionSummary'));
    }

    public function allAssets(Request $request)
    {
        $query = FixedAsset::where('status', 'active')
            ->with(['category', 'currentProject'])
            ->orderBy('asset_name');

        $locationType = $request->get('location_type', 'all');
        if ($locationType === 'project') {
            $query->where('lifecycle_status', 'in_use');
        } elseif ($locationType === 'warehouse') {
            $query->whereIn('lifecycle_status', ['in_warehouse', 'returned', 'acquired']);
        } elseif ($locationType === 'repair_shop') {
            $query->where('lifecycle_status', 'under_maintenance');
        }

        if ($request->filled('category_id')) {
            $query->where('category_id', $request->category_id);
        }
        if ($request->filled('condition')) {
            $query->where('condition', $request->condition);
        }
        if ($request->filled('project_id')) {
            $query->where('current_project_id', $request->project_id);
        }
        if ($request->filled('search')) {
            $s = $request->search;
            $query->where(function ($q) use ($s) {
                $q->where('asset_name', 'LIKE', "%{$s}%")
                  ->orWhere('asset_code', 'LIKE', "%{$s}%")
                  ->orWhere('serial_number', 'LIKE', "%{$s}%");
            });
        }

        $assets     = $query->paginate(25)->withQueryString();
        $categories = FixedAssetCategory::where('status', 'active')->orderBy('category_name')->get();
        $projects   = Project::active()->orderBy('project_name')->get();

        $totalCount       = FixedAsset::where('status', 'active')->count();
        $atProjectCount   = FixedAsset::where('status', 'active')->where('lifecycle_status', 'in_use')->count();
        $inWarehouseCount = FixedAsset::where('status', 'active')->whereIn('lifecycle_status', ['in_warehouse', 'returned', 'acquired'])->count();
        $repairShopCount  = FixedAsset::where('status', 'active')->where('lifecycle_status', 'under_maintenance')->count();

        return view('warehouse.fixed-assets.inventory.all-assets', compact(
            'assets', 'categories', 'projects',
            'totalCount', 'atProjectCount', 'inWarehouseCount', 'repairShopCount'
        ));
    }

    public function movementHistory(Request $request, $assetId = null)
    {
        $asset = null;
        $selectedAssetId = $assetId ?: $request->get('asset_id');

        $query = FixedAssetMovement::with(['fixedAsset', 'performedBy', 'fromProject', 'toProject'])
            ->latest('movement_date');

        if ($selectedAssetId) {
            $asset = FixedAsset::with('category')->findOrFail($selectedAssetId);
            $query->where('fixed_asset_id', $selectedAssetId);
        }

        if ($request->filled('movement_type')) {
            $query->where('movement_type', $request->movement_type);
        }

        if ($request->filled('date_from')) {
            $query->whereDate('movement_date', '>=', $request->date_from);
        }

        if ($request->filled('date_to')) {
            $query->whereDate('movement_date', '<=', $request->date_to);
        }

        $movements = $query->paginate(50)->withQueryString();
        $allAssets = FixedAsset::orderBy('asset_code')->get(['id', 'asset_code', 'asset_name']);

        return view('warehouse.fixed-assets.inventory.movement-history', compact('asset', 'movements', 'allAssets'));
    }
}
