<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Product;
use App\Models\ProductSize;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class AdminProductController extends Controller
{
    private const DEFAULT_SIZES = ['S', 'M', 'L', 'XL', 'XXL'];

    public function dashboard()
    {
        $lowStockCount = Product::with('sizes')->get()->filter(fn ($p) => $p->isLowStock())->count();

        return redirect()->route('admin.products.index')->with('low_stock_count', $lowStockCount);
    }

    public function index(Request $request)
    {
        $query = Product::with('category', 'sizes');
        if ($request->filled('q')) {
            $q = $request->get('q');
            $query->where('name', 'like', "%{$q}%");
        }
        if ($request->filled('status')) {
            $products = $query->orderBy('name')->get();
            if ($request->status === 'low') {
                $products = $products->filter(fn ($p) => $p->isLowStock());
            } elseif ($request->status === 'over') {
                $products = $products->filter(fn ($p) => $p->isOverStock());
            }
            $perPage = 12;
            $page = $request->get('page', 1);
            $products = new \Illuminate\Pagination\LengthAwarePaginator(
                $products->forPage($page, $perPage)->values(),
                $products->count(),
                $perPage,
                $page,
                ['path' => $request->url(), 'query' => $request->query()]
            );
        } else {
            $products = $query->orderBy('name')->paginate(12)->withQueryString();
        }

        $lowStockProducts = Product::with('category', 'sizes')->get()->filter(fn ($p) => $p->isLowStock());

        return view('admin.products.index', compact('products', 'lowStockProducts'));
    }

    public function create()
    {
        $categories = Category::orderBy('name')->get();

        return view('admin.products.create', compact('categories'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'category_id' => 'required|exists:categories,id',
            'name' => 'required|string|max:255',
            'color' => 'nullable|string|max:255',
            'image_url' => 'nullable|string',
            'min_stock' => 'required|integer|min:0',
            'max_stock' => 'required|integer|gte:min_stock',
            'sizes' => 'array',
            'sizes.*' => 'integer|min:0',
        ]);

        $product = Product::create([
            'category_id' => $data['category_id'],
            'name' => $data['name'],
            'color' => $data['color'] ?? '',
            'image_url' => $data['image_url'] ?? '',
            'size' => '',
            'stock' => 0,
            'min_stock' => $data['min_stock'],
            'max_stock' => $data['max_stock'],
        ]);

        if ($request->hasFile('image')) {
            $file = $request->file('image');
            $ext = $file->getClientOriginalExtension();
            $filename = Str::slug($product->name) . '-' . time() . '.' . $ext;
            $file->move(public_path('images'), $filename);
            $product->image_url = '/images/' . $filename;
            $product->save();
        }

        $sizes = $data['sizes'] ?? [];
        foreach (self::DEFAULT_SIZES as $size) {
            $stock = (int) ($sizes[$size] ?? 0);
            ProductSize::on('sizes_db')->create([
                'product_id' => $product->id,
                'size' => $size,
                'stock' => $stock,
            ]);
        }

        $product->syncStock();

        if ($product->total_stock > 0) {
            $product->logStockMovement('in', $product->total_stock, 0, $product->total_stock, 'Stok awal produk baru');
        }

        return redirect()->route('admin.products.index')->with('status', 'Produk berhasil ditambahkan');
    }

    public function edit(Product $product)
    {
        $product->load('sizes');

        return view('admin.products.edit', compact('product'));
    }

    public function update(Request $request, Product $product)
    {
        $data = $request->validate([
            'name' => 'required|string',
            'color' => 'nullable|string',
            'image_url' => 'nullable|string',
            'min_stock' => 'required|integer|min:0',
            'max_stock' => 'required|integer|gte:min_stock',
            'sizes' => 'array',
            'sizes.*' => 'integer|min:0',
        ]);

        $stockBefore = $product->total_stock;

        $product->update([
            'name' => $data['name'],
            'color' => $data['color'] ?? $product->color,
            'image_url' => $data['image_url'] ?? $product->image_url,
            'min_stock' => $data['min_stock'],
            'max_stock' => $data['max_stock'],
        ]);

        if ($request->hasFile('image')) {
            $file = $request->file('image');
            $ext = $file->getClientOriginalExtension();
            $filename = Str::slug($product->name) . '-' . time() . '.' . $ext;
            $file->move(public_path('images'), $filename);
            $product->image_url = '/images/' . $filename;
            $product->save();
        }

        if (! empty($data['sizes'])) {
            foreach ($data['sizes'] as $size => $stock) {
                $ps = ProductSize::on('sizes_db')->firstOrNew(['product_id' => $product->id, 'size' => $size]);
                $ps->stock = (int) $stock;
                $ps->save();
            }
            $product->syncStock();
        }

        $stockAfter = $product->fresh()->total_stock;
        if ($stockBefore !== $stockAfter) {
            $diff = $stockAfter - $stockBefore;
            $type = $diff > 0 ? 'in' : 'out';
            $product->logStockMovement($type, abs($diff), $stockBefore, $stockAfter, 'Penyesuaian stok via edit produk');
        }

        return redirect()->route('admin.products.index')->with('status', 'Produk diperbarui');
    }

    public function destroy(Product $product)
    {
        try {
            ProductSize::on('sizes_db')->where('product_id', $product->id)->delete();
        } catch (\Exception $e) {
            // ignore
        }
        $product->delete();

        return redirect()->route('admin.products.index')->with('status', 'Produk dihapus');
    }
}
