<?php

namespace App\Http\Controllers;

use App\Models\PaymentAllocation;
use App\Models\AdvancePayment;
use App\Models\Factory;
use App\Models\OrderConfirmation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PaymentAllocationController extends Controller
{
    public function index()
    {
        $allocations = PaymentAllocation::with([
            'advancePayment.buyer', 
            'factory', 
            'orderConfirmation',
            'creator'
        ])->latest()->paginate(20);

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

    public function create()
    {
        $advancePayments = AdvancePayment::where('remaining_amount', '>', 0)
            ->where('status', 'received')
            ->with('buyer')
            ->get();
            
        $factories = Factory::all();
        $orders = OrderConfirmation::whereIn('status', ['confirmed', 'in_production'])->get();

        return view('admin.payment.allocations.create', compact('advancePayments', 'factories', 'orders'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'advance_payment_id' => 'required|exists:advance_payments,id',
            'factory_id' => 'required|exists:factories,id',
            'order_confirmation_id' => 'required|exists:order_confirmations,id',
            'amount' => 'required|numeric|min:0.01',
            'allocation_date' => 'required|date',
            'purpose' => 'required|string|max:500',
            'remarks' => 'nullable|string',
        ]);

        $advancePayment = AdvancePayment::findOrFail($validated['advance_payment_id']);

        if ($validated['amount'] > $advancePayment->remaining_amount) {
            return back()->withErrors([
                'amount' => 'Allocation amount cannot exceed remaining advance amount. Available: ₹' . number_format($advancePayment->remaining_amount, 2)
            ])->withInput();
        }

        DB::transaction(function () use ($validated) {
            $validated['created_by'] = auth()->id();
            PaymentAllocation::create($validated);
        });

        return redirect()->route('admin.payment-allocations.index')
            ->with('success', 'Payment allocated to factory successfully.');
    }

    public function show(PaymentAllocation $paymentAllocation)
    {
        $paymentAllocation->load([
            'advancePayment.buyer', 
            'factory', 
            'orderConfirmation',
            'creator'
        ]);
        
        return view('admin.payment.allocations.show', compact('paymentAllocation'));
    }

    public function edit(PaymentAllocation $paymentAllocation)
    {
        $advancePayments = AdvancePayment::where('remaining_amount', '>', 0)
            ->where('status', 'received')
            ->with('buyer')
            ->get();
            
        $factories = Factory::all();
        $orders = OrderConfirmation::whereIn('status', ['confirmed', 'in_production'])->get();

        return view('admin.payment.allocations.edit', compact(
            'paymentAllocation', 
            'advancePayments', 
            'factories', 
            'orders'
        ));
    }

    public function update(Request $request, PaymentAllocation $paymentAllocation)
    {
        $validated = $request->validate([
            'factory_id' => 'required|exists:factories,id',
            'order_confirmation_id' => 'required|exists:order_confirmations,id',
            'amount' => 'required|numeric|min:0.01',
            'allocation_date' => 'required|date',
            'purpose' => 'required|string|max:500',
            'remarks' => 'nullable|string',
        ]);

        $advancePayment = $paymentAllocation->advancePayment;
        $newAmount = $validated['amount'];
        $oldAmount = $paymentAllocation->amount;

        if (($newAmount - $oldAmount) > $advancePayment->remaining_amount) {
            return back()->withErrors([
                'amount' => 'Increased amount cannot exceed remaining advance amount. Available: ₹' . number_format($advancePayment->remaining_amount, 2)
            ])->withInput();
        }

        DB::transaction(function () use ($validated, $paymentAllocation, $oldAmount, $newAmount) {
            $paymentAllocation->update($validated);

            // Adjust allocation amounts if amount changed
            if ($newAmount != $oldAmount) {
                $difference = $newAmount - $oldAmount;
                $paymentAllocation->advancePayment->increment('allocated_amount', $difference);
                $paymentAllocation->advancePayment->decrement('remaining_amount', $difference);
            }
        });

        return redirect()->route('admin.payment-allocations.index')
            ->with('success', 'Payment allocation updated successfully.');
    }

    public function destroy(PaymentAllocation $paymentAllocation)
    {
        DB::transaction(function () use ($paymentAllocation) {
            $paymentAllocation->delete();
        });

        return redirect()->route('admin.payment-allocations.index')
            ->with('success', 'Payment allocation deleted successfully.');
    }
}