<?php
namespace App\Http\Controllers\V1;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use App\Models\CustomerVendor;
use App\Models\Purchase;
use App\Models\PurchaseItem;
use App\Models\PurchaseFile;
use App\Models\StockItem;
use App\Models\PurchaseQuotation;
use App\Models\PurchaseOrder;
use App\Models\CreditNote;
use Str;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;


class PurchaseController extends Controller
{
    public function index(Request $request, $id = null)
    {
        $data = [];
        $filters = $request->get('filters', []);
        $page = $request->get('page', 1);
        $perPage = $request->get('per_page', 10);
        $query = Purchase::with(['items', 'files', 'vendor', 'quotation']);
        $columns = Schema::getColumnListing('purchasesv1');
        $data['columns'] = $columns;
        $data['filters'] = $filters;
    
        // Search filter
        if (isset($filters['search'])) {
            $search = $filters['search'];
            unset($filters['search']);
            $query->where(function ($q) use ($columns, $search) {
                foreach ($columns as $column) {
                    $q->orWhere($column, 'like', '%' . $search . '%');
                }
            });
        }
    
        // Custom filter: invoice_age_range
        if (isset($filters['invoice_age_range']) && $filters['invoice_age_range']) {
            $range = $filters['invoice_age_range'];
            $now = now();
    
            switch ($range) {
                case '0-15':
                    $query->whereBetween('purchase_date', [
                        $now->copy()->subDays(15)->toDateString(),
                        $now->toDateString()
                    ]);
                    break;
                case '15-30':
                    $query->whereBetween('purchase_date', [
                        $now->copy()->subDays(30)->toDateString(),
                        $now->copy()->subDays(15)->toDateString()
                    ]);
                    break;
                case '30-45':
                    $query->whereBetween('purchase_date', [
                        $now->copy()->subDays(45)->toDateString(),
                        $now->copy()->subDays(30)->toDateString()
                    ]);
                    break;
                case '45+':
                    $query->where('purchase_date', '<=', $now->copy()->subDays(45)->toDateString());
                    break;
            }
    
            unset($filters['invoice_age_range']); // Prevent further processing
        }
    
        // General column-based filters
        if (count($filters) > 0) {
            foreach ($filters as $key => $value) {
                if ($value) {
                    $filterKey = explode(":", $key)[0] ?? "";
                    if (in_array($filterKey, $columns)) {
                        if (Str::endsWith($key, ":range")) {
                            $searchValue = str_replace("><", "", $value);
                            $searchArr = explode(" - ", $searchValue);
                            $searchArr = array_map('trim', $searchArr);
                            $query->where($filterKey, '>=', $searchArr[0]);
                            $query->where($filterKey, '<=', $searchArr[1]);
                        } elseif (Str::endsWith($key, ":lte")) {
                            $query->where($filterKey, '<=', $value);
                        } elseif (Str::endsWith($key, ":gte")) {
                            $query->where($filterKey, '>=', $value);
                        } else {
                            $query->where($key, 'like', '%' . $value . '%');
                        }
                    }
                }
            }
        }
    
        // Purchase Orders
        $purchaseOrders = PurchaseOrder::where('status', 'approved')
            ->with('items', 'items.stockItem', 'vendor')
            ->whereDoesntHave('purchase')
            ->get();
        $data['purchaseOrders'] = $purchaseOrders;
    
        // Paginate
        $data['list'] = $query->paginate($perPage, $columns, null, $page)->withQueryString();
    
        // Vendors and Stock Items for filters
        $vendors = CustomerVendor::where('company_role', 'Vendor')->get();
        $data['vendors'] = $vendors;
        $stockItems = StockItem::all();
        $data['stockItems'] = $stockItems;
    
        // Individual Purchase or Form Preparation
        if ($id) {
            $purchase = Purchase::with(['items', 'files', 'vendor', 'quotation'])->find($id);
            $data['purchase'] = $purchase;
        } else {
            $nextPurchaseInvoiceNo = nextNumber('UEPL/P/INV', 'purchasesv1', 'purchase_no', 3);
            $currentDate = date('Y-m-d');
            $quotations = PurchaseQuotation::where('status', 'approved')
                ->with('items', 'items.stockItem')
                ->whereDoesntHave('purchaseOrder')
                ->get();
            $data['nextPurchaseInvoiceNo'] = $nextPurchaseInvoiceNo;
            $data['currentDate'] = $currentDate;
            $data['quotations'] = $quotations;
        }
    
        // AJAX response
        if ($request->ajax()) {
            $html = view('v1.purchase.partials.purchase-invoices-tab', $data)->render();
            return response()->json([
                'success' => true,
                'html' => $html,
                'pagination' => [
                    'total' => $data['list']->total(),
                    'per_page' => $data['list']->perPage(),
                    'current_page' => $data['list']->currentPage(),
                    'last_page' => $data['list']->lastPage(),
                    'from' => $data['list']->firstItem(),
                    'to' => $data['list']->lastItem()
                ]
            ]);
        }
    
        return view('v1.purchase.index', $data);
    }


    public function store(Request $request)
    {
        $data = $request->validate([
            'purchase_no' => 'required|unique:purchasesv1,purchase_no',
            'purchase_date' => 'required|date',
            'purchase_order_no' => 'nullable|exists:purchase_orders,purchase_order_no',
            'purchase_order_date' => 'nullable|date',
            'vendor_id' => 'nullable|exists:customer_vendors,id',
            'vendor_ref_no' => 'nullable|string',
            'vendor_invoice_no' => 'nullable|string',
            'quotation_no' => 'nullable|exists:purchase_quotations,quotation_no',
            'quotation_date' => 'nullable|date',
            'company_name' => 'nullable|string',
            'company_phone' => 'nullable|string',
            'company_email' => 'nullable|string',
            'company_gstn' => 'nullable|string',
            'company_address' => 'nullable|string',
            'payment_terms' => 'nullable|string',
            'bill_address' => 'nullable|string',
            'ship_address' => 'nullable|string',
            'subtotal' => 'nullable|numeric',
            'sgst_amount' => 'nullable|numeric',
            'cgst_amount' => 'nullable|numeric',
            'igst_amount' => 'nullable|numeric',
            'additional_charges' => 'nullable|numeric',
            'tds_amount' => 'nullable|numeric',
            'net_payable_amount' => 'nullable|numeric',
            'grand_total' => 'nullable|numeric',
            'paid_amount' => 'nullable|numeric',
            'balance_amount' => 'nullable|numeric',
            'payment_status' => 'nullable|string',
            'inr_in_words' => 'nullable|string',
            'payment_method' => 'nullable|string',
            'payment_reference_no' => 'nullable|string',
            'payment_delay_reason' => 'nullable|string',
            'description' => 'nullable|string',
            'delivery_terms' => 'nullable|string',
            'note' => 'nullable|string',

            'items' => 'required|array|min:1',
            'items.*.stock_item_id' => 'required|exists:stock_items,id',
            'items.*.stock_item_name' => 'nullable|string',
            'items.*.description' => 'nullable|string',
            'items.*.quantity' => 'required|numeric',
            'items.*.uom' => 'nullable|string',
            'items.*.unit_rate' => 'required|numeric',
            'items.*.tds' => 'nullable|numeric',
            'items.*.discount' => 'nullable|numeric',
            'items.*.value' => 'nullable|numeric',
            'items.*.sgst' => 'nullable|numeric',
            'items.*.cgst' => 'nullable|numeric',
            'items.*.igst' => 'nullable|numeric',
            'items.*.amount' => 'nullable|numeric',

            'purchaseFiles' => 'nullable|array',
            'purchaseFiles.*' => 'file|mimes:pdf,jpg,jpeg,png|max:2048',
        ]);

        DB::transaction(function () use ($data, $request) {
            // Prepare purchase order data (exclude items and files)
            $poData = $data;
            unset($poData['items'], $poData['purchaseFiles']);

            $purchase = Purchase::create($poData);

            foreach ($data['items'] as $item) {
                $itemData = $item;
                $itemData['purchase_id'] = $purchase->id;
                PurchaseItem::create($itemData);
            }

            if ($request->hasFile('purchaseFiles')) {
                foreach ($request->file('purchaseFiles') as $file) {
                    $path = $file->store('purchase_files', 'public');
                    PurchaseFile::create([
                        'purchase_id' => $purchase->id,
                        'file_path' => $path,
                        'file_name' => $file->getClientOriginalName(),
                        'file_size' => $file->getSize(),
                    ]);
                }
            }
        });

        return redirect()->route('superadmin.purchase.v1.index')
            ->with('success', 'Purchase Invoice created successfully!');
    }

    public function update(Request $request, $id)
    {
        $purchase = Purchase::findOrFail($id);

        $data = $request->validate([
            'purchase_no' => 'required|exists:purchasesv1,purchase_no',
            'purchase_date' => 'required|date',
            'purchase_order_no' => 'nullable|exists:purchase_orders,purchase_order_no',
            'purchase_order_date' => 'nullable|date',
            'vendor_id' => 'nullable|exists:customer_vendors,id',
            'vendor_ref_no' => 'nullable|string',
            'vendor_invoice_no' => 'nullable|string',
            'quotation_no' => 'nullable|exists:purchase_quotations,quotation_no',
            'quotation_date' => 'nullable|date',
            'company_name' => 'nullable|string',
            'company_phone' => 'nullable|string',
            'company_email' => 'nullable|string',
            'company_gstn' => 'nullable|string',
            'company_address' => 'nullable|string',
            'payment_terms' => 'nullable|string',
            'bill_address' => 'nullable|string',
            'ship_address' => 'nullable|string',
            'subtotal' => 'nullable|numeric',
            'sgst_amount' => 'nullable|numeric',
            'cgst_amount' => 'nullable|numeric',
            'igst_amount' => 'nullable|numeric',
            'additional_charges' => 'nullable|numeric',
            'tds_amount' => 'nullable|numeric',
            'net_payable_amount' => 'nullable|numeric',
            'grand_total' => 'nullable|numeric',
            'paid_amount' => 'nullable|numeric',
            'balance_amount' => 'nullable|numeric',
            'payment_status' => 'nullable|string',
            'inr_in_words' => 'nullable|string',
            'payment_method' => 'nullable|string',
            'payment_reference_no' => 'nullable|string',
            'payment_delay_reason' => 'nullable|string',
            'description' => 'nullable|string',
            'delivery_terms' => 'nullable|string',
            'note' => 'nullable|string',

            'items' => 'required|array|min:1',
            'items.*.stock_item_id' => 'required|exists:stock_items,id',
            'items.*.stock_item_name' => 'nullable|string',
            'items.*.description' => 'nullable|string',
            'items.*.quantity' => 'required|numeric',
            'items.*.uom' => 'nullable|string',
            'items.*.unit_rate' => 'required|numeric',
            'items.*.tds' => 'nullable|numeric',
            'items.*.discount' => 'nullable|numeric',
            'items.*.value' => 'nullable|numeric',
            'items.*.sgst' => 'nullable|numeric',
            'items.*.cgst' => 'nullable|numeric',
            'items.*.igst' => 'nullable|numeric',
            'items.*.amount' => 'nullable|numeric',

            'purchaseFiles' => 'nullable|array',
            'purchaseFiles.*' => 'file|mimes:pdf,jpg,jpeg,png|max:2048',
        ]);

        DB::transaction(function () use ($data, $request, $purchase) {
            // Update purchase order data (exclude items and files)
            $poData = $data;
            unset($poData['items'], $poData['purchaseFiles']);

            $purchase->update($poData);
            $existingItemIds = $purchase->items()->pluck('stock_item_id')->toArray();
            $incomingItemIds = array_column($data['items'], 'stock_item_id');

            // Delete items that are no longer in the incoming data
            $itemsToDelete = array_diff($existingItemIds, $incomingItemIds);
            if (!empty($itemsToDelete)) {
                $purchase->items()->whereIn('stock_item_id', $itemsToDelete)->delete();
            }

            // Update existing items or create new ones
            foreach ($data['items'] as $item) {
                $itemData = $item;
                $itemData['purchase_id'] = $purchase->id;

                PurchaseItem::updateOrCreate(
                    [
                        'purchase_id' => $purchase->id,
                        'stock_item_id' => $item['stock_item_id']
                    ],
                    $itemData
                );
            }

            // Handle new file uploads
            if ($request->hasFile('purchaseFiles')) {
                foreach ($request->file('purchaseFiles') as $file) {
                    $path = $file->store('purchase_files', 'public');
                    PurchaseFile::create([
                        'purchase_id' => $purchase->id,
                        'file_path' => $path,
                        'file_name' => $file->getClientOriginalName(),
                        'file_size' => $file->getSize(),
                    ]);
                }
            }
        });

        return redirect()->route('superadmin.purchase.v1.index')
            ->with('success', 'Purchase Invoice updated successfully!');
    }

    public function destroy(Request $request, $id)
    {
        try {
            $purchase = Purchase::findOrFail($id);
            $purchase->items()->delete();
            $purchase->files()->delete();
            $purchase->delete();

            return response()->json(['success' => true, 'message' => 'Purchase deleted successfully.']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Failed to delete purchase.', 'error' => $e->getMessage()], 500);
        }
    }

    // Show a single purchase order
    public function show($id)
    {
        $purchase = Purchase::with(['files', 'vendor', 'items', 'creditNotes'])->findOrFail($id);
        return view('v1.purchase.show', compact('purchase'));
    }

    // Print a purchase order
    public function print($id)
    {
        $purchaseOrder = Purchase::with(['items.stockItem'])->findOrFail($id);
        return view('v1.purchase.print', compact('purchaseOrder'));
    }

    // Approve a purchase order
    public function approve($id)
    {
        $purchaseOrder = Purchase::findOrFail($id);
        $purchaseOrder->status = 'approved';
        $purchaseOrder->save();
        return redirect()->route('superadmin.purchase.v1.index')->with('success', 'Purchase Order approved successfully!');
    }

    // Reject a purchase order
    public function reject($id)
    {
        $purchaseOrder = Purchase::findOrFail($id);
        $purchaseOrder->status = 'rejected';
        $purchaseOrder->save();
        return redirect()->route('superadmin.purchase.v1.index')->with('success', 'Purchase Order rejected successfully!');
    }

    // Delete file
    public function deleteFile($id)
    {
        $file = PurchaseFile::findOrFail($id);

        if (Storage::disk('public')->exists($file->file_path)) {
            Storage::disk('public')->delete($file->file_path);
        }

        $file->delete();

        return redirect()->back()->with('success', 'File deleted successfully.');
    }

    // Get vendor payments data
    public function vendorPayments(Request $request)
    {
        // Debug: Log that this method is being called
        Log::info('VendorPayments method called', ['request' => $request->all()]);
        
        try {
            $filters = $request->all();
            $query = Purchase::with(['vendor', 'items'])
                ->whereIn('payment_status', ['paid', 'partial'])
                ->where('paid_amount', '>', 0);

            // Apply filters
            if (!empty($filters['vendor_id'])) {
                $query->where('vendor_id', $filters['vendor_id']);
            }

            if (!empty($filters['date_range'])) {
                $dates = explode(' - ', $filters['date_range']);
                if (count($dates) == 2) {
                    $query->whereBetween('purchase_date', [$dates[0], $dates[1]]);
                }
            }

            if (!empty($filters['min_amount'])) {
                $query->where('paid_amount', '>=', $filters['min_amount']);
            }

            if (!empty($filters['max_amount'])) {
                $query->where('paid_amount', '<=', $filters['max_amount']);
            }

            $payments = $query->orderBy('purchase_date', 'desc')->get();

            // Transform data for DataTable
            $data = $payments->map(function ($purchase) {
                return [
                    'payment_id' => 'PAY-' . str_pad($purchase->id, 6, '0', STR_PAD_LEFT),
                    'invoice_date' => $purchase->purchase_date,
                    'purchase_date' => $purchase->purchase_order_date ?? $purchase->purchase_date,
                    'party' => $purchase->vendor->company ?? $purchase->company_name,
                    'invoice_id' => $purchase->vendor_invoice_no,
                    'purchase_id' => $purchase->purchase_no,
                    'amount' => $purchase->paid_amount,
                    'payment_mode' => $purchase->payment_method ?? 'N/A',
                    'reference' => $purchase->payment_reference_no ?? 'N/A',
                    'id' => $purchase->id,
                    'balance_amount' => $purchase->balance_amount,
                    'grand_total' => $purchase->grand_total,
                    'payment_status' => $purchase->payment_status
                ];
            });

            // Always return JSON for vendor payments
            return response()->json([
                'success' => true,
                'data' => $data
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error fetching vendor payments: ' . $e->getMessage(),
                'data' => []
            ], 500);
        }
    }

    // Get credit notes data for DataTable
    public function creditNotes(Request $request)
    {
        
        $filters = $request->all();
        $query = CreditNote::with(['party']);

        // Apply filters
        if (!empty($filters['party_id'])) {
            $query->where('party_id', $filters['party_id']);
        }

        if (!empty($filters['date_range'])) {
            $dates = explode(' - ', $filters['date_range']);
            if (count($dates) == 2) {
                $query->whereBetween('date', [$dates[0], $dates[1]]);
            }
        }

        if (!empty($filters['credit_note_no'])) {
            $query->where('credit_note_no', 'like', '%' . $filters['credit_note_no'] . '%');
        }

        $creditNotes = $query->orderBy('date', 'desc')->get();

        

        // Transform data for DataTable
        $data = $creditNotes->map(function ($creditNote) {
            return [
                'id' => $creditNote->id,
                'credit_note_no' => $creditNote->credit_note_no,
                'date' => $creditNote->date,
                'party' => $creditNote->party->company ?? 'N/A',
                'invoice_no' => $creditNote->invoice_no,
                'amount' => $creditNote->amount,
                'reason' => $creditNote->reason,
                'description' => $creditNote->description,
            ];
        });

        if ($request->ajax()) {
            return response()->json([
                'data' => $data
            ]);
        }

        return $data;
    }

    // Store new credit note
    public function storeCreditNote(Request $request)
    {
        $data = $request->validate([
            'credit_note_no' => 'required|unique:credit_notes,credit_note_no',
            'date' => 'required|date',
            'invoice_no' => 'required|string',
            'party_id' => 'required|exists:customer_vendors,id',
            'amount' => 'required|numeric|min:0',
            'reason' => 'required|string|max:255',
            'description' => 'nullable|string',
        ]);

        try {
            CreditNote::create($data);

            if ($request->ajax()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Credit note created successfully!'
                ]);
            }

            return redirect()->route('superadmin.purchase.v1.index')
                ->with('success', 'Credit note created successfully!');
        } catch (\Exception $e) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Error creating credit note: ' . $e->getMessage()
                ], 500);
            }

            return redirect()->back()
                ->with('error', 'Error creating credit note: ' . $e->getMessage())
                ->withInput();
        }
    }

    // Update credit note
    public function updateCreditNote(Request $request, $id)
    {
        $creditNote = CreditNote::findOrFail($id);

        $data = $request->validate([
            'credit_note_no' => 'required|unique:credit_notes,credit_note_no,' . $id,
            'date' => 'required|date',
            'invoice_no' => 'required|string',
            'party_id' => 'required|exists:customer_vendors,id',
            'amount' => 'required|numeric|min:0',
            'reason' => 'required|string|max:255',
            'description' => 'nullable|string',
        ]);

        try {
            $creditNote->update($data);

            if ($request->ajax()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Credit note updated successfully!'
                ]);
            }

            return redirect()->route('superadmin.purchase.v1.index')
                ->with('success', 'Credit note updated successfully!');
        } catch (\Exception $e) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Error updating credit note: ' . $e->getMessage()
                ], 500);
            }

            return redirect()->back()
                ->with('error', 'Error updating credit note: ' . $e->getMessage())
                ->withInput();
        }
    }

    // Delete credit note
    public function destroyCreditNote($id)
    {
        try {
            $creditNote = CreditNote::findOrFail($id);
            $creditNote->delete();

            return response()->json([
                'success' => true,
                'message' => 'Credit note deleted successfully!'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error deleting credit note: ' . $e->getMessage()
            ], 500);
        }
    }

    // Get credit note details for editing
    public function getCreditNote($id)
    {
        try {
            $creditNote = CreditNote::with('party')->findOrFail($id);
            
            return response()->json([
                'success' => true,
                'data' => $creditNote
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Credit note not found'
            ], 404);
        }
    }

    // Generate next credit note number
    public function getNextCreditNoteNumber()
    {
        $nextNumber = nextNumber('UEPL/CN', 'credit_notes', 'credit_note_no');
        
        return response()->json([
            'success' => true,
            'credit_note_no' => $nextNumber
        ]);
    }

    // Get aging report data
    public function agingReport(Request $request)
    {
        $asOfDate = $request->input('as_of_date', now()->format('Y-m-d'));
        $partyId = $request->input('party_id');
        $reportType = $request->input('report_type', 'summary'); // summary or detailed

        $query = Purchase::with(['vendor'])
            ->where('payment_status', '!=', 'paid')
            ->where('balance_amount', '>', 0);

        // Filter by party if specified
        if ($partyId) {
            $query->where('vendor_id', $partyId);
        }

        // Filter by date (only include invoices up to the as-of date)
        $query->where('purchase_date', '<=', $asOfDate);

        $purchases = $query->get();

        $agingData = [];

        foreach ($purchases as $purchase) {
            $vendorName = $purchase->vendor ? $purchase->vendor->company : $purchase->company_name;
            $vendorId = $purchase->vendor_id;
            
            // Calculate days overdue from purchase date to as-of date
            $purchaseDate = \Carbon\Carbon::parse($purchase->purchase_date);
            $asOfDateCarbon = \Carbon\Carbon::parse($asOfDate);
            $daysOverdue = $purchaseDate->diffInDays($asOfDateCarbon);

            $balanceAmount = (float) $purchase->balance_amount;

            // Initialize vendor entry if not exists
            if (!isset($agingData[$vendorId])) {
                $agingData[$vendorId] = [
                    'vendor_id' => $vendorId,
                    'vendor_name' => $vendorName,
                    'current' => 0,
                    '1_30' => 0,
                    '31_60' => 0,
                    '61_90' => 0,
                    'over_90' => 0,
                    'total_due' => 0,
                    'invoices' => []
                ];
            }

            // Categorize by aging buckets
            if ($daysOverdue <= 0) {
                $agingData[$vendorId]['current'] += $balanceAmount;
                $bucket = 'current';
            } elseif ($daysOverdue <= 30) {
                $agingData[$vendorId]['1_30'] += $balanceAmount;
                $bucket = '1_30';
            } elseif ($daysOverdue <= 60) {
                $agingData[$vendorId]['31_60'] += $balanceAmount;
                $bucket = '31_60';
            } elseif ($daysOverdue <= 90) {
                $agingData[$vendorId]['61_90'] += $balanceAmount;
                $bucket = '61_90';
            } else {
                $agingData[$vendorId]['over_90'] += $balanceAmount;
                $bucket = 'over_90';
            }

            $agingData[$vendorId]['total_due'] += $balanceAmount;

            // Add invoice details for detailed report
            if ($reportType === 'detailed') {
                $agingData[$vendorId]['invoices'][] = [
                    'id' => $purchase->id,
                    'purchase_no' => $purchase->purchase_no,
                    'vendor_invoice_no' => $purchase->vendor_invoice_no,
                    'purchase_date' => $purchase->purchase_date,
                    'due_date' => $purchase->due_date ?? $purchase->purchase_date,
                    'days_overdue' => $daysOverdue,
                    'balance_amount' => $balanceAmount,
                    'bucket' => $bucket,
                    'grand_total' => $purchase->grand_total,
                    'paid_amount' => $purchase->paid_amount
                ];
            }
        }

        // Convert to array and sort by total due descending
        $agingData = array_values($agingData);
        usort($agingData, function($a, $b) {
            return $b['total_due'] <=> $a['total_due'];
        });

        // Calculate totals
        $totals = [
            'current' => array_sum(array_column($agingData, 'current')),
            '1_30' => array_sum(array_column($agingData, '1_30')),
            '31_60' => array_sum(array_column($agingData, '31_60')),
            '61_90' => array_sum(array_column($agingData, '61_90')),
            'over_90' => array_sum(array_column($agingData, 'over_90')),
            'total_due' => array_sum(array_column($agingData, 'total_due'))
        ];

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'data' => $agingData,
                'totals' => $totals,
                'as_of_date' => $asOfDate,
                'report_type' => $reportType
            ]);
        }

        return [
            'data' => $agingData,
            'totals' => $totals,
            'as_of_date' => $asOfDate
        ];
    }

    // Export aging report
    public function exportAgingReport(Request $request)
    {
        $format = $request->input('format', 'excel'); // excel, pdf, csv
        $asOfDate = $request->input('as_of_date', now()->format('Y-m-d'));
        $partyId = $request->input('party_id');
        $reportType = $request->input('report_type', 'summary');

        // Get aging data
        $request->merge(['report_type' => $reportType]);
        $agingData = $this->agingReport($request);

        $filename = 'aging_report_' . $asOfDate . '_' . now()->format('Y-m-d_H-i-s');

        if ($format === 'csv') {
            $csvData = "Vendor,Current,1-30 Days,31-60 Days,61-90 Days,>90 Days,Total Due\n";
            
            foreach ($agingData['data'] as $row) {
                $csvData .= sprintf(
                    '"%s",%.2f,%.2f,%.2f,%.2f,%.2f,%.2f' . "\n",
                    $row['vendor_name'],
                    $row['current'],
                    $row['1_30'],
                    $row['31_60'],
                    $row['61_90'],
                    $row['over_90'],
                    $row['total_due']
                );
            }

            // Add totals row
            $csvData .= sprintf(
                '"TOTAL",%.2f,%.2f,%.2f,%.2f,%.2f,%.2f',
                $agingData['totals']['current'],
                $agingData['totals']['1_30'],
                $agingData['totals']['31_60'],
                $agingData['totals']['61_90'],
                $agingData['totals']['over_90'],
                $agingData['totals']['total_due']
            );

            return response($csvData)
                ->header('Content-Type', 'text/csv')
                ->header('Content-Disposition', 'attachment; filename="' . $filename . '.csv"');
        }

        // For now, return JSON for Excel/PDF (can be enhanced with actual Excel/PDF generation)
        return response()->json([
            'success' => true,
            'message' => 'Export functionality can be enhanced with Excel/PDF libraries',
            'data' => $agingData
        ]);
    }

    // Get aging summary for dashboard
    public function agingSummary(Request $request)
    {
        $asOfDate = $request->input('as_of_date', now()->format('Y-m-d'));
        
        $agingData = $this->agingReport($request);
        
        return response()->json([
            'success' => true,
            'summary' => [
                'total_outstanding' => $agingData['totals']['total_due'],
                'current_due' => $agingData['totals']['current'],
                'overdue_amount' => $agingData['totals']['1_30'] + $agingData['totals']['31_60'] + $agingData['totals']['61_90'] + $agingData['totals']['over_90'],
                'critical_overdue' => $agingData['totals']['over_90'], // >90 days
                'vendor_count' => count($agingData['data']),
                'as_of_date' => $asOfDate
            ]
        ]);
    }
}
