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

use App\Http\Controllers\Controller;
use App\Models\Warehouse\FixedAssets\FixedAssetMaintenance;
use App\Models\Warehouse\FixedAssets\FixedAsset;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class FixedAssetMaintenanceController extends Controller
{
    public function __construct()
    {
        $this->middleware('warehouse.access');
        $this->middleware('warehouse.permission:warehouse.fixed-asset-maintenance.view')->only(['index', 'show', 'upcoming', 'overdue']);
        $this->middleware('warehouse.permission:warehouse.fixed-asset-maintenance.create')->only(['create', 'store']);
        $this->middleware('warehouse.permission:warehouse.fixed-asset-maintenance.edit')->only(['edit', 'update']);
        $this->middleware('warehouse.permission:warehouse.fixed-asset-maintenance.process')->only(['start', 'complete']);
    }

    public function index(Request $request)
    {
        $query = FixedAssetMaintenance::with(['fixedAsset.category', 'createdBy'])
            ->latest('created_at');

        if ($request->filled('status')) $query->where('status', $request->status);
        if ($request->filled('maintenance_type')) $query->where('maintenance_type', $request->maintenance_type);
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('maintenance_number', 'LIKE', "%{$search}%")
                  ->orWhereHas('fixedAsset', fn($aq) => $aq->where('asset_name', 'LIKE', "%{$search}%")->orWhere('asset_code', 'LIKE', "%{$search}%"));
            });
        }

        $records = $query->paginate(25)->withQueryString();
        return view('warehouse.fixed-assets.maintenance.index', compact('records'));
    }

    public function create()
    {
        $assets = FixedAsset::where('status', 'active')->orderBy('asset_name')->get();
        return view('warehouse.fixed-assets.maintenance.create', compact('assets'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'fixed_asset_id' => 'required|exists:fixed_assets,id',
            'maintenance_type' => 'required|in:scheduled,unscheduled,inspection,calibration',
            'priority' => 'nullable|in:low,medium,high,critical',
            'scheduled_date' => 'nullable|date',
            'description' => 'required|string|max:2000',
            'vendor' => 'nullable|string|max:255',
            'labor_cost' => 'nullable|numeric|min:0',
            'parts_cost' => 'nullable|numeric|min:0',
            'condition_before' => 'nullable|in:new,good,fair,poor,damaged',
            'notes' => 'nullable|string|max:2000',
        ]);

        try {
            $record = FixedAssetMaintenance::create([
                'fixed_asset_id' => $request->fixed_asset_id,
                'maintenance_type' => $request->maintenance_type,
                'priority' => $request->priority ?? 'medium',
                'scheduled_date' => $request->scheduled_date,
                'description' => $request->description,
                'vendor' => $request->vendor,
                'labor_cost' => $request->labor_cost,
                'parts_cost' => $request->parts_cost,
                'condition_before' => $request->condition_before,
                'notes' => $request->notes,
                'status' => 'scheduled',
                'created_by' => Auth::id(),
            ]);

            if ($request->expectsJson()) {
                return response()->json(['success' => true, 'data' => $record, 'message' => 'Maintenance record created.'], 201);
            }
            return redirect()->route('warehouse.fixed-assets.maintenance.show', $record->id)
                ->with('success', 'Maintenance record ' . $record->maintenance_number . ' created.');
        } catch (\Exception $e) {
            \Log::error('FixedAssetMaintenanceController@store error: ' . $e->getMessage());
            if ($request->expectsJson()) {
                return response()->json(['success' => false, 'message' => $e->getMessage()], 400);
            }
            return back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function show($id)
    {
        $record = FixedAssetMaintenance::with(['fixedAsset.category', 'createdBy', 'completedBy'])->findOrFail($id);
        return view('warehouse.fixed-assets.maintenance.show', compact('record'));
    }

    public function edit($id)
    {
        $record = FixedAssetMaintenance::findOrFail($id);
        if (!in_array($record->status, ['scheduled'])) {
            return redirect()->route('warehouse.fixed-assets.maintenance.show', $record->id)
                ->with('error', 'Only scheduled records can be edited.');
        }
        $assets = FixedAsset::where('status', 'active')->orderBy('asset_name')->get();
        return view('warehouse.fixed-assets.maintenance.edit', compact('record', 'assets'));
    }

    public function update(Request $request, $id)
    {
        $record = FixedAssetMaintenance::findOrFail($id);
        if ($record->status !== 'scheduled') {
            if ($request->expectsJson()) {
                return response()->json(['success' => false, 'message' => 'Only scheduled records can be updated.'], 422);
            }
            return back()->with('error', 'Only scheduled records can be updated.');
        }

        $request->validate([
            'maintenance_type' => 'required|in:scheduled,unscheduled,inspection,calibration',
            'priority' => 'nullable|in:low,medium,high,critical',
            'scheduled_date' => 'nullable|date',
            'description' => 'required|string|max:2000',
            'vendor' => 'nullable|string|max:255',
            'labor_cost' => 'nullable|numeric|min:0',
            'parts_cost' => 'nullable|numeric|min:0',
            'condition_before' => 'nullable|in:new,good,fair,poor,damaged',
            'notes' => 'nullable|string|max:2000',
        ]);

        try {
            $record->update($request->only([
                'maintenance_type', 'priority', 'scheduled_date', 'description',
                'vendor', 'labor_cost', 'parts_cost', 'condition_before', 'notes',
            ]));

            if ($request->expectsJson()) {
                return response()->json(['success' => true, 'message' => 'Maintenance record updated.']);
            }
            return redirect()->route('warehouse.fixed-assets.maintenance.show', $record->id)
                ->with('success', 'Maintenance record updated.');
        } catch (\Exception $e) {
            \Log::error('FixedAssetMaintenanceController@update error: ' . $e->getMessage());
            if ($request->expectsJson()) {
                return response()->json(['success' => false, 'message' => $e->getMessage()], 400);
            }
            return back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function start($id)
    {
        $record = FixedAssetMaintenance::findOrFail($id);
        if ($record->status !== 'scheduled') {
            if (request()->expectsJson()) {
                return response()->json(['success' => false, 'message' => 'Only scheduled records can be started.'], 422);
            }
            return back()->with('error', 'Only scheduled records can be started.');
        }

        try {
            $record->start();
            if (request()->expectsJson()) {
                return response()->json(['success' => true, 'message' => 'Maintenance started.']);
            }
            return redirect()->route('warehouse.fixed-assets.maintenance.show', $record->id)
                ->with('success', 'Maintenance started. Asset is now under maintenance.');
        } catch (\Exception $e) {
            \Log::error('FixedAssetMaintenanceController@start error: ' . $e->getMessage());
            if (request()->expectsJson()) {
                return response()->json(['success' => false, 'message' => $e->getMessage()], 400);
            }
            return back()->with('error', $e->getMessage());
        }
    }

    public function complete(Request $request, $id)
    {
        $record = FixedAssetMaintenance::findOrFail($id);
        if ($record->status !== 'in_progress') {
            if ($request->expectsJson()) {
                return response()->json(['success' => false, 'message' => 'Only in-progress records can be completed.'], 422);
            }
            return back()->with('error', 'Only in-progress records can be completed.');
        }

        $request->validate([
            'condition_after' => 'nullable|in:new,good,fair,poor,damaged',
            'findings' => 'nullable|string|max:2000',
            'actions_taken' => 'nullable|string|max:2000',
            'labor_cost' => 'nullable|numeric|min:0',
            'parts_cost' => 'nullable|numeric|min:0',
        ]);

        try {
            $record->update([
                'condition_after' => $request->condition_after,
                'findings' => $request->findings,
                'actions_taken' => $request->actions_taken,
                'labor_cost' => $request->labor_cost ?? $record->labor_cost,
                'parts_cost' => $request->parts_cost ?? $record->parts_cost,
            ]);

            $record->complete(Auth::id());

            if ($request->expectsJson()) {
                return response()->json(['success' => true, 'message' => 'Maintenance completed.']);
            }
            return redirect()->route('warehouse.fixed-assets.maintenance.show', $record->id)
                ->with('success', 'Maintenance completed successfully.');
        } catch (\Exception $e) {
            \Log::error('FixedAssetMaintenanceController@complete error: ' . $e->getMessage());
            if ($request->expectsJson()) {
                return response()->json(['success' => false, 'message' => $e->getMessage()], 400);
            }
            return back()->with('error', $e->getMessage());
        }
    }

    public function upcoming()
    {
        $records = FixedAssetMaintenance::with(['fixedAsset.category'])
            ->upcoming(30)
            ->orderBy('scheduled_date')
            ->paginate(25);

        return view('warehouse.fixed-assets.maintenance.upcoming', compact('records'));
    }

    public function overdue()
    {
        $records = FixedAssetMaintenance::with(['fixedAsset.category'])
            ->overdue()
            ->orderBy('scheduled_date')
            ->paginate(25);

        return view('warehouse.fixed-assets.maintenance.overdue', compact('records'));
    }
}
