<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Voucher;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class VoucherController extends Controller
{
    public function index(Request $request)
    {
        $query = Voucher::with('creator')->latest();

        if ($request->filled('search')) {
            $query->where('code', 'like', '%' . $request->search . '%')
                  ->orWhere('name', 'like', '%' . $request->search . '%');
        }

        if ($request->filled('status')) {
            $query->where('is_active', $request->status === 'active');
        }

        $vouchers = $query->paginate(15)->withQueryString();

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

    public function create()
    {
        return view('admin.vouchers.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name'          => 'required|string|max:255',
            'description'   => 'nullable|string',
            'type'          => 'required|in:percentage,fixed',
            'discount_value' => 'required|numeric|min:0.01',
            'min_purchase'  => 'nullable|numeric|min:0',
            'max_discount'  => 'nullable|numeric|min:0',
            'max_uses'      => 'nullable|integer|min:1',
            'valid_from'    => 'nullable|date',
            'valid_until'   => 'nullable|date|after_or_equal:valid_from',
            'is_active'     => 'boolean',
            'auto_generate' => 'boolean',
            'code'          => 'nullable|string|max:50|unique:vouchers,code',
            'bulk_count'    => 'nullable|integer|min:1|max:100',
        ]);

        if ($request->boolean('auto_generate') && $request->filled('bulk_count')) {
            $count = (int) $request->bulk_count;
            $created = 0;

            for ($i = 0; $i < $count; $i++) {
                $data = $this->buildVoucherData($validated, session('admin_id'));
                $data['code'] = $this->generateUniqueCode();
                Voucher::create($data);
                $created++;
            }

            return redirect()->route('admin.vouchers.index')
                ->with('success', "$created voucher berhasil dibuat secara massal.");
        }

        $data = $this->buildVoucherData($validated, session('admin_id'));
        $data['code'] = $request->boolean('auto_generate')
            ? $this->generateUniqueCode()
            : strtoupper($validated['code'] ?? $this->generateUniqueCode());

        Voucher::create($data);

        return redirect()->route('admin.vouchers.index')
            ->with('success', 'Voucher berhasil dibuat.');
    }

    public function edit(Voucher $voucher)
    {
        return view('admin.vouchers.edit', compact('voucher'));
    }

    public function update(Request $request, Voucher $voucher)
    {
        $validated = $request->validate([
            'name'           => 'required|string|max:255',
            'description'    => 'nullable|string',
            'type'           => 'required|in:percentage,fixed',
            'discount_value' => 'required|numeric|min:0.01',
            'min_purchase'   => 'nullable|numeric|min:0',
            'max_discount'   => 'nullable|numeric|min:0',
            'max_uses'       => 'nullable|integer|min:1',
            'valid_from'     => 'nullable|date',
            'valid_until'    => 'nullable|date|after_or_equal:valid_from',
            'is_active'      => 'boolean',
            'code'           => 'required|string|max:50|unique:vouchers,code,' . $voucher->id,
        ]);

        $voucher->update([
            'name'           => $validated['name'],
            'description'    => $validated['description'] ?? null,
            'type'           => $validated['type'],
            'discount_value' => $validated['discount_value'],
            'min_purchase'   => $validated['min_purchase'] ?? 0,
            'max_discount'   => $validated['max_discount'] ?? null,
            'max_uses'       => $validated['max_uses'] ?? null,
            'valid_from'     => $validated['valid_from'] ?? null,
            'valid_until'    => $validated['valid_until'] ?? null,
            'is_active'      => $request->boolean('is_active'),
            'code'           => strtoupper($validated['code']),
        ]);

        return redirect()->route('admin.vouchers.index')
            ->with('success', 'Voucher berhasil diperbarui.');
    }

    public function destroy(Voucher $voucher)
    {
        $voucher->delete();

        return redirect()->route('admin.vouchers.index')
            ->with('success', 'Voucher berhasil dihapus.');
    }

    public function show(Voucher $voucher)
    {
        $usages = $voucher->usages()->latest()->paginate(20);

        return view('admin.vouchers.show', compact('voucher', 'usages'));
    }

    private function buildVoucherData(array $validated, ?int $adminId): array
    {
        return [
            'name'           => $validated['name'],
            'description'    => $validated['description'] ?? null,
            'type'           => $validated['type'],
            'discount_value' => $validated['discount_value'],
            'min_purchase'   => $validated['min_purchase'] ?? 0,
            'max_discount'   => $validated['max_discount'] ?? null,
            'max_uses'       => $validated['max_uses'] ?? null,
            'valid_from'     => $validated['valid_from'] ?? null,
            'valid_until'    => $validated['valid_until'] ?? null,
            'is_active'      => $validated['is_active'] ?? true,
            'created_by'     => $adminId,
        ];
    }

    private function generateUniqueCode(): string
    {
        do {
            $code = strtoupper(Str::random(4) . '-' . Str::random(4));
        } while (Voucher::where('code', $code)->exists());

        return $code;
    }
}
