<?php

namespace App\Http\Controllers;

use App\Models\Material;
use App\Models\StockMovement;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class DamagedMaterialController extends Controller
{
    public function __construct()
    {
        $this->middleware(\App\Http\Middleware\PermissionMiddleware::class . ':manage materials,manage stock')
            ->only(['create', 'store', 'destroy']);
    }

    public function index(Request $request)
    {
        $query = StockMovement::with(['material', 'user'])
            ->damaged();

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

        if ($request->filled('date')) {
            $query->whereDate('created_at', $request->date);
        }

        $movements = $query->latest()->paginate(20);
        $materials = Material::orderBy('name')->get();

        return view('pages.stock.damaged.index', [
            'title' => 'Data Bahan Rusak',
            'movements' => $movements,
            'materials' => $materials,
        ]);
    }

    public function create()
    {
        $materials = Material::active()->orderBy('name')->get();

        return view('pages.stock.damaged.create', [
            'title' => 'Catat Bahan Rusak',
            'materials' => $materials,
        ]);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'material_id' => ['required', 'exists:materials,id'],
            'quantity' => ['required', 'numeric', 'min:0.01'],
            'notes' => ['nullable', 'string', 'max:500'],
        ]);

        $material = Material::findOrFail($validated['material_id']);
        $quantity = (float) $validated['quantity'];
        $notes = $validated['notes'] ?? null;

        if ($quantity <= 0) {
            return back()
                ->withErrors(['quantity' => 'Jumlah bahan rusak harus lebih dari 0.'])
                ->withInput();
        }

        if ((float) $material->stock < $quantity) {
            return back()
                ->withErrors(['quantity' => 'Jumlah bahan rusak melebihi stok tersedia.'])
                ->withInput();
        }

        DB::transaction(function () use ($material, $quantity, $notes, $request) {
            $material->decrement('stock', $quantity);

            $movement = new StockMovement();

            if (Schema::hasColumn('stock_movements', 'material_id')) {
                $movement->material_id = $material->id;
            }

            if (Schema::hasColumn('stock_movements', 'quantity')) {
                $movement->quantity = $quantity;
            }

            if (Schema::hasColumn('stock_movements', 'qty')) {
                $movement->qty = $quantity;
            }

            if (Schema::hasColumn('stock_movements', 'type')) {
                $movement->type = 'damaged';
            }

            if (Schema::hasColumn('stock_movements', 'movement_type')) {
                $movement->movement_type = 'damaged';
            }

            if (Schema::hasColumn('stock_movements', 'status')) {
                $movement->status = 'damaged';
            }

            if (Schema::hasColumn('stock_movements', 'direction')) {
                $movement->direction = 'out';
            }

            if (Schema::hasColumn('stock_movements', 'reference_type')) {
                $movement->reference_type = 'damaged';
            }

            if (Schema::hasColumn('stock_movements', 'reference_id')) {
                $movement->reference_id = $material->id;
            }

            if (Schema::hasColumn('stock_movements', 'notes')) {
                $movement->notes = $notes;
            }

            if (Schema::hasColumn('stock_movements', 'description')) {
                $movement->description = $notes;
            }

            if (Schema::hasColumn('stock_movements', 'user_id') && $request->user()) {
                $movement->user_id = $request->user()->id;
            }

            if (Schema::hasColumn('stock_movements', 'unit_price')) {
                $movement->unit_price = (float) ($material->base_price ?? 0);
            }

            if (Schema::hasColumn('stock_movements', 'total_price')) {
                $movement->total_price = $quantity * (float) ($material->base_price ?? 0);
            }

            $movement->save();
        });

        return redirect()->route('stock.damaged.index')
            ->with('success', 'Data bahan rusak berhasil dicatat.');
    }

    public function destroy(StockMovement $damaged)
    {
        DB::transaction(function () use ($damaged) {
            if ($damaged->material) {
                $damaged->material->increment('stock', (float) $damaged->quantity);
            }

            $damaged->delete();
        });

        return redirect()->route('stock.damaged.index')
            ->with('success', 'Data bahan rusak berhasil dihapus dan stok dikembalikan.');
    }
}