<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Purchase;
use App\Models\Supplier;
use App\Models\SupplierPayment;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;

class SupplierPaymentController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request): View
    {
        $perPage = $request->get('per_page', 10);
        $search = $request->get('search', '');

        $query = SupplierPayment::with(['purchase', 'supplier', 'creator']);

        if (! empty($search)) {
            $query->where(function ($q) use ($search) {
                $q->where('payment_number', 'like', "%{$search}%")
                    ->orWhere('reference_number', 'like', "%{$search}%")
                    ->orWhereHas('supplier', function ($sq) use ($search) {
                        $sq->where('name', 'like', "%{$search}%");
                    })
                    ->orWhereHas('purchase', function ($pq) use ($search) {
                        $pq->where('purchase_number', 'like', "%{$search}%");
                    });
            });
        }

        $payments = $query->orderBy('created_at', 'desc')->paginate($perPage);

        return view('admin.supplier-payments.index', [
            'payments' => $payments,
            'perPage' => $perPage,
            'search' => $search,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'purchase_id' => 'required|exists:purchases,id',
            'payment_date' => 'required|date',
            'reference_number' => 'nullable|string|max:255',
            'paid_amount' => 'required|numeric|min:0.01',
            'payment_source' => 'required|string|max:255',
            'notes' => 'nullable|string',
            'attachment' => 'nullable|file|mimes:pdf,doc,docx,jpg,jpeg,png|max:5120',
        ]);

        try {
            DB::beginTransaction();

            // Get the purchase to calculate amounts
            $purchase = Purchase::findOrFail($validated['purchase_id']);

            // Calculate total amount (purchase total)
            $totalAmount = $purchase->total;

            // Get existing payments for this purchase
            $existingPayments = SupplierPayment::where('purchase_id', $validated['purchase_id'])
                ->sum('paid_amount');

            // Calculate due amount
            $dueAmount = $totalAmount - ($existingPayments + $validated['paid_amount']);

            // Handle attachment upload
            $attachmentPath = null;
            if ($request->hasFile('attachment')) {
                $attachmentPath = $request->file('attachment')->store('supplier-payments', 'public');
            }

            // Generate payment number
            $paymentNumber = SupplierPayment::generatePaymentNumber();

            // Get supplier from purchase
            // Note: Purchase uses Customer model as supplier, but we have a separate Supplier model
            // Try to find matching supplier by name from purchase's supplier (customer)
            $supplierId = null;
            if ($purchase->supplier_id && $purchase->supplier) {
                // Try to find a Supplier with matching name
                $supplier = Supplier::where('name', $purchase->supplier->name)->first();
                if ($supplier) {
                    $supplierId = $supplier->id;
                }
            }

            $payment = SupplierPayment::create([
                'payment_number' => $paymentNumber,
                'purchase_id' => $validated['purchase_id'],
                'bank_account_id' => $purchase->bank_account_id,
                'supplier_id' => $supplierId,
                'payment_date' => $validated['payment_date'],
                'reference_number' => $validated['reference_number'] ?? null,
                'total_amount' => $totalAmount,
                'paid_amount' => $validated['paid_amount'],
                'due_amount' => max(0, $dueAmount), // Ensure non-negative
                'payment_source' => $validated['payment_source'],
                'notes' => $validated['notes'] ?? null,
                'attachment' => $attachmentPath,
                'created_by' => Auth::id(),
            ]);

            // Update purchase status if fully paid
            if ($dueAmount <= 0) {
                $purchase->status = 'completed';
                $purchase->save();
            } elseif ($existingPayments > 0 || $validated['paid_amount'] > 0) {
                $purchase->status = 'partially_paid';
                $purchase->save();
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Payment created successfully.',
                'payment' => $payment->load(['purchase', 'supplier']),
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'Failed to create payment: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get purchases for AJAX dropdown
     */
    public function getPurchases(Request $request): JsonResponse
    {
        try {
            $query = Purchase::with(['supplier', 'company']);

            $search = $request->get('search', '');
            if (! empty($search)) {
                $query->where(function ($q) use ($search) {
                    $q->where('purchase_number', 'like', "%{$search}%")
                        ->orWhereHas('supplier', function ($sq) use ($search) {
                            $sq->where('name', 'like', "%{$search}%");
                        });
                });
            }

            $purchases = $query->orderBy('purchase_date', 'desc')->limit(50)->get();

            return response()->json([
                'success' => true,
                'purchases' => $purchases->map(function ($purchase) {
                    // Get existing payments
                    $paidAmount = SupplierPayment::where('purchase_id', $purchase->id)->sum('paid_amount');
                    $dueAmount = $purchase->total - $paidAmount;

                    return [
                        'id' => $purchase->id,
                        'purchase_number' => $purchase->purchase_number,
                        'purchase_date' => $purchase->purchase_date->format('Y-m-d'),
                        'total' => $purchase->total,
                        'paid_amount' => $paidAmount,
                        'due_amount' => max(0, $dueAmount),
                        'supplier_name' => $purchase->supplier ? $purchase->supplier->name : 'N/A',
                    ];
                })->toArray(),
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error fetching purchases: '.$e->getMessage(),
                'purchases' => [],
            ], 500);
        }
    }

    /**
     * Get payment sources for dropdown
     */
    public function getPaymentSources(): JsonResponse
    {
        $sources = [
            'Cash',
            'Bank Transfer',
            'Credit Card',
            'Cheque',
            'Online Payment',
            'Other',
        ];

        return response()->json([
            'success' => true,
            'sources' => $sources,
        ]);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(SupplierPayment $supplierPayment): RedirectResponse
    {
        try {
            // Delete attachment if exists
            if ($supplierPayment->attachment && Storage::disk('public')->exists($supplierPayment->attachment)) {
                Storage::disk('public')->delete($supplierPayment->attachment);
            }

            $supplierPayment->delete();

            return redirect()->route('admin.supplier-payments.index')
                ->with('success', 'Payment deleted successfully.');
        } catch (\Exception $e) {
            return redirect()->route('admin.supplier-payments.index')
                ->withErrors(['error' => 'Failed to delete payment: '.$e->getMessage()]);
        }
    }
}
