<?php

namespace App\Http\Controllers\Modules\Accounts;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use App\Models\PurchaseOrder;
use App\Models\CustomerVendor;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

/**
 * Unified Accounts Payable Controller
 *
 * Handles vendor payables (purchase orders) for all roles.
 * Uses HasRoleViews trait to automatically resolve role-specific views.
 */
class AccountsPayableController extends Controller
{
    use HasRoleViews;

    /**
     * Display list of all payables (purchase orders)
     */
    public function index(Request $request)
    {
        $query = PurchaseOrder::with('vendor')
            ->orderBy('purchase_order_date', 'desc');

        // Filter by vendor
        if ($request->filled('vendor_id')) {
            $query->where('vendor_id', $request->vendor_id);
        }

        // Filter by date range
        if ($request->filled('from_date')) {
            $query->whereDate('purchase_order_date', '>=', $request->from_date);
        }
        if ($request->filled('to_date')) {
            $query->whereDate('purchase_order_date', '<=', $request->to_date);
        }

        $payables = $query->paginate(20);

        // Get summary statistics
        $stats = $this->getPayableStats();

        // Get vendors for filter dropdown
        $vendors = CustomerVendor::where('company_role', 'vendor')
            ->orWhere('company_role', 'both')
            ->orderBy('company')
            ->get();

        return $this->roleView('accounts.payable.index', compact('payables', 'stats', 'vendors'));
    }

    /**
     * Show single payable details
     */
    public function show($id)
    {
        $payable = PurchaseOrder::with(['vendor', 'items'])->findOrFail($id);

        return $this->roleView('accounts.payable.show', compact('payable'));
    }

    /**
     * Record payment against a payable
     */
    public function recordPayment(Request $request, $id)
    {
        // PurchaseOrder doesn't have payment fields - placeholder for future
        return back()->with('info', 'Payment recording requires additional setup. Purchase Orders don\'t track payments directly.');
    }

    /**
     * Generate aging report (30/60/90 days)
     */
    public function agingReport(Request $request)
    {
        $today = Carbon::today();

        // Get all purchase orders
        $payables = PurchaseOrder::with('vendor')
            ->orderBy('purchase_order_date', 'asc')
            ->get();

        // Categorize by aging buckets
        $aging = [
            'current' => ['items' => collect(), 'total' => 0],      // 0-30 days
            'days_30' => ['items' => collect(), 'total' => 0],      // 31-60 days
            'days_60' => ['items' => collect(), 'total' => 0],      // 61-90 days
            'days_90_plus' => ['items' => collect(), 'total' => 0], // 90+ days
        ];

        foreach ($payables as $payable) {
            $orderDate = Carbon::parse($payable->purchase_order_date);
            $daysOld = $orderDate->diffInDays($today);
            $total = $payable->grand_total ?? 0;

            // Add balance field for view compatibility
            $payable->balance_amount = $total;
            $payable->paid_amount = 0;

            if ($daysOld <= 30) {
                $aging['current']['items']->push($payable);
                $aging['current']['total'] += $total;
            } elseif ($daysOld <= 60) {
                $aging['days_30']['items']->push($payable);
                $aging['days_30']['total'] += $total;
            } elseif ($daysOld <= 90) {
                $aging['days_60']['items']->push($payable);
                $aging['days_60']['total'] += $total;
            } else {
                $aging['days_90_plus']['items']->push($payable);
                $aging['days_90_plus']['total'] += $total;
            }
        }

        $grandTotal = array_sum(array_column($aging, 'total'));

        return $this->roleView('accounts.payable.aging', compact('aging', 'grandTotal'));
    }

    /**
     * Get payable summary statistics
     */
    protected function getPayableStats(): array
    {
        $totalPayables = PurchaseOrder::sum('grand_total') ?? 0;
        $totalPaid = 0;
        $totalOutstanding = $totalPayables;

        $pendingCount = PurchaseOrder::count();
        $overdueCount = PurchaseOrder::whereDate('purchase_order_date', '<', Carbon::today()->subDays(30))->count();

        return [
            'total_payables' => $totalPayables,
            'total_paid' => $totalPaid,
            'total_outstanding' => $totalOutstanding,
            'pending_count' => $pendingCount,
            'overdue_count' => $overdueCount,
        ];
    }

    /**
     * Export payables to PDF
     */
    public function exportPdf(Request $request)
    {
        $payables = PurchaseOrder::with('vendor')
            ->orderBy('purchase_order_date', 'desc')
            ->get();

        return $this->roleView('accounts.payable.print', compact('payables'));
    }
}
