<?php

namespace App\Http\Controllers;

use App\Models\Expense;
use App\Models\ExpenseCategory;
use App\Models\Purchase;
use App\Models\PurchasePayment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class PurchasePaymentController extends Controller
{
    /**
     * Store a new payment for a purchase.
     */
    public function store(Request $request, Purchase $purchase)
    {
        $request->merge([
            'amount' => str_replace('.', '', $request->amount ?? '0'),
        ]);

        $rules = [
            'amount' => ['required', 'numeric', 'min:1', 'max:' . $purchase->remaining],
            'payment_date' => ['required', 'date'],
            'payment_method' => ['required', 'in:cash,transfer'],
            'proof' => ['nullable', 'image', 'max:2048'],
            'notes' => ['nullable', 'string', 'max:500'],
        ];

        $validated = Validator::make($request->all(), $rules)->validate();

        $paymentMethod = $validated['payment_method'];
        unset($validated['payment_method']);

        $methodLabel = $paymentMethod === 'transfer' ? 'Bank Transfer' : 'Cash';

        $baseNotes = trim($validated['notes'] ?? '');
        $validated['notes'] = trim(
            ($baseNotes ? $baseNotes . ' | ' : '') . 'Metode: ' . $methodLabel
        );

        $validated['purchase_id'] = $purchase->id;
        $validated['created_by'] = Auth::id();

        if ($request->hasFile('proof')) {
            $validated['proof'] = $request->file('proof')->store('purchase-proofs', 'public');
        }

        DB::transaction(function () use ($purchase, $validated, $methodLabel) {
            $payment = PurchasePayment::create($validated);

            $this->createBahanBakuExpenseFromPurchasePayment($purchase, $payment, $methodLabel);

            $purchase->updatePaymentStatus();
        });

        return redirect()->route('purchases.show', $purchase)
            ->with('success', 'Pembayaran berhasil ditambahkan.');
    }

    /**
     * Delete a payment.
     */
    public function destroy(Purchase $purchase, PurchasePayment $payment)
    {
        if ((int) $payment->purchase_id !== (int) $purchase->id) {
            abort(404);
        }

        DB::transaction(function () use ($purchase, $payment) {
            /*
             * Hapus expense otomatis yang dibuat dari pembayaran pembelian.
             * Pakai marker purchase_payment:{id} agar tidak salah hapus expense manual.
             */
            Expense::where('description', 'like', '%purchase_payment:' . $payment->id . '%')->delete();

            if ($payment->proof) {
                Storage::disk('public')->delete($payment->proof);
            }

            $payment->delete();

            $purchase->updatePaymentStatus();
        });

        return redirect()->route('purchases.show', $purchase)
            ->with('success', 'Pembayaran berhasil dihapus.');
    }

    private function createBahanBakuExpenseFromPurchasePayment(Purchase $purchase, PurchasePayment $payment, string $methodLabel): void
    {
        $purchase->loadMissing(['material', 'supplierRelation']);

        /*
         * Jangan lagi fallback ke kategori pertama seperti Listrik.
         * Semua pembayaran dari pembelian stok wajib masuk kategori Bahan Baku.
         */
        $category = ExpenseCategory::firstOrCreate(
            ['name' => 'Bahan Baku'],
            ['is_active' => true]
        );

        $materialName = $purchase->material->name ?? 'Pembelian Bahan';
        $supplierName = $purchase->supplierRelation->name ?? ($purchase->supplier ?? '-');

        $description = "purchase_payment:{$payment->id}"
            . " | purchase_id:{$purchase->id}"
            . " | Bahan Baku"
            . " | {$materialName}"
            . " | Supplier: {$supplierName}"
            . " | {$methodLabel}";

        $alreadyExists = Expense::where('description', 'like', '%purchase_payment:' . $payment->id . '%')->exists();

        if ($alreadyExists) {
            return;
        }

        Expense::create([
            'expense_category_id' => $category->id,
            'amount' => $payment->amount,
            'expense_date' => $payment->payment_date,
            'description' => $description,
            'created_by' => $payment->created_by ?? Auth::id(),
        ]);
    }
}
