<?php

namespace App\Http\Controllers\Warehouse\IndirectGoods;

use App\Http\Controllers\Controller;
use App\Models\Warehouse\IndirectGoods\IndirectGoodsConsumption;
use App\Models\Warehouse\IndirectGoods\IndirectGoodsProjectInventory;
use App\Models\Warehouse\IndirectGoods\IndirectGood;
use App\Models\Warehouse\Project;
use Illuminate\Http\Request;

class IndirectGoodsConsumptionController extends Controller
{
    public function __construct()
    {
        $this->middleware('warehouse.access');
        $this->middleware('warehouse.permission:warehouse.indirect-consumption.view')->only(['index', 'show']);
        $this->middleware('warehouse.permission:warehouse.indirect-consumption.create')->only(['create', 'store']);
    }

    public function index(Request $request)
    {
        if ($request->ajax() || $request->expectsJson()) {
            $query = IndirectGoodsConsumption::with(['project', 'indirectGood', 'recorder']);

            // Filters
            if ($request->filled('project_id')) {
                $query->where('project_id', $request->project_id);
            }
            if ($request->filled('consumption_type')) {
                $query->where('consumption_type', $request->consumption_type);
            }
            if ($request->filled('date_from')) {
                $query->whereDate('consumption_date', '>=', $request->date_from);
            }
            if ($request->filled('date_to')) {
                $query->whereDate('consumption_date', '<=', $request->date_to);
            }
            if ($request->filled('search.value') && $request->input('search.value') !== '') {
                $search = $request->input('search.value');
                $query->where(function ($q) use ($search) {
                    $q->where('consumption_number', 'LIKE', "%{$search}%")
                      ->orWhere('invoice_number', 'LIKE', "%{$search}%")
                      ->orWhere('reason', 'LIKE', "%{$search}%")
                      ->orWhereHas('indirectGood', function ($q2) use ($search) {
                          $q2->where('ig_code', 'LIKE', "%{$search}%")
                             ->orWhere('ig_description', 'LIKE', "%{$search}%");
                      });
                });
            }

            $totalRecords = IndirectGoodsConsumption::count();
            $filteredRecords = $query->count();

            // Sorting
            $orderColumn = $request->input('order.0.column', 0);
            $orderDir = $request->input('order.0.dir', 'desc');
            $columns = ['id', 'consumption_number', 'consumption_date', 'project_id', 'indirect_good_id', 'invoice_number', 'quantity_consumed', 'consumption_type', 'created_at'];
            $orderBy = $columns[$orderColumn] ?? 'created_at';
            $query->orderBy($orderBy, $orderDir);

            $start = $request->input('start', 0);
            $length = $request->input('length', 10);
            $records = $query->skip($start)->take($length)->get();

            return response()->json([
                'draw' => intval($request->input('draw')),
                'recordsTotal' => $totalRecords,
                'recordsFiltered' => $filteredRecords,
                'data' => $records->map(function ($record, $index) use ($start) {
                    return [
                        'DT_RowIndex' => $start + $index + 1,
                        'id' => $record->id,
                        'consumption_number' => $record->consumption_number,
                        'consumption_date' => $record->consumption_date ? $record->consumption_date->format('Y-m-d') : '-',
                        'project' => $record->project ? $record->project->project_name : '-',
                        'indirect_good' => $record->indirectGood ? $record->indirectGood->ig_code . ' - ' . $record->indirectGood->ig_description : '-',
                        'invoice_number' => $record->invoice_number ?: '-',
                        'quantity_consumed' => number_format($record->quantity_consumed, 2),
                        'consumption_type' => $record->consumption_type,
                        'reason' => $record->reason ?: '-',
                        'recorded_by' => $record->recorder ? $record->recorder->name : '-',
                        'created_at' => $record->created_at->format('Y-m-d H:i'),
                    ];
                }),
            ]);
        }

        $projects = Project::orderBy('project_name')->get();
        return view('warehouse.indirect-goods.consumption.index', compact('projects'));
    }

    public function create()
    {
        $projects = Project::orderBy('project_name')->get();
        return view('warehouse.indirect-goods.consumption.create', compact('projects'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'consumption_date' => 'required|date',
            'project_id' => 'required|exists:projects,id',
            'indirect_good_id' => 'required|exists:indirect_goods,id',
            'invoice_number' => 'required|string',
            'quantity_consumed' => 'required|numeric|min:0.01',
            'consumption_type' => 'required|in:consumed,written_off,damaged,expired',
            'reason' => 'nullable|string|max:1000',
        ]);

        // Check availability
        $projectInv = IndirectGoodsProjectInventory::where('project_id', $validated['project_id'])
            ->where('indirect_good_id', $validated['indirect_good_id'])
            ->where('invoice_number', $validated['invoice_number'])
            ->where('quantity_available', '>', 0)
            ->first();

        if (!$projectInv || $projectInv->quantity_available < $validated['quantity_consumed']) {
            return back()->withInput()->with('error', 'Insufficient quantity available in project inventory. Available: ' . ($projectInv ? $projectInv->quantity_available : 0));
        }

        $validated['recorded_by'] = auth()->id();

        $consumption = IndirectGoodsConsumption::create($validated);
        $consumption->processConsumption();

        return redirect()->route('warehouse.indirect-goods.consumption.show', $consumption->id)
            ->with('success', 'Consumption record created successfully.');
    }

    public function show($id)
    {
        $consumption = IndirectGoodsConsumption::with(['project', 'indirectGood', 'recorder', 'approver'])->findOrFail($id);
        return view('warehouse.indirect-goods.consumption.show', compact('consumption'));
    }

    /**
     * AJAX: Get indirect goods available in a project's inventory.
     */
    public function getProjectItems($projectId)
    {
        $items = IndirectGoodsProjectInventory::where('project_id', $projectId)
            ->where('quantity_available', '>', 0)
            ->whereHas('indirectGood')
            ->with('indirectGood')
            ->get()
            ->groupBy('indirect_good_id')
            ->map(function ($group) {
                $first = $group->first();
                return [
                    'id' => $first->indirect_good_id,
                    'text' => $first->indirectGood->ig_code . ' - ' . $first->indirectGood->ig_description,
                    'total_available' => $group->sum('quantity_available'),
                ];
            })
            ->values();

        return response()->json($items);
    }

    /**
     * AJAX: Get invoice numbers for a specific item in a project.
     */
    public function getItemInvoices($projectId, $indirectGoodId)
    {
        $invoices = IndirectGoodsProjectInventory::where('project_id', $projectId)
            ->where('indirect_good_id', $indirectGoodId)
            ->where('quantity_available', '>', 0)
            ->get()
            ->map(function ($inv) {
                return [
                    'invoice_number' => $inv->invoice_number,
                    'quantity_available' => $inv->quantity_available,
                    'unit_price' => $inv->unit_price,
                    'batch_number' => $inv->batch_number,
                ];
            });

        return response()->json($invoices);
    }
}
