<?php

namespace App\Http\Controllers;

use App\Models\Payment;
use App\Models\Customer;
use App\Models\RentServiceBill;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Carbon\Carbon;
use Barryvdh\DomPDF\Facade\Pdf;

class PaymentController extends Controller
{
    public function index(Request $request)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        $search = $request->input('search');

        $payments = Payment::with(['customer.unit.property', 'receivedBy'])
            ->whereHas('customer.unit.property', function($q) use ($companyId) {
                $q->where('CompanyID', $companyId);
            })
            ->when($search, function($query) use ($search) {
                $query->where(function($q) use ($search) {
                    $q->where('ReceiptNo', 'like', "%{$search}%")
                      ->orWhere('PaymentMode', 'like', "%{$search}%")
                      ->orWhere('TotalPayment', 'like', "%{$search}%")
                      ->orWhereHas('customer', function($q) use ($search) {
                          $q->where('CustomerName', 'like', "%{$search}%")
                            ->orWhere('TelNo', 'like', "%{$search}%")
                            ->orWhere('Email', 'like', "%{$search}%");
                      });
                });
            })
            ->orderBy('PaymentDate', 'desc')
            ->paginate(20)
            ->withQueryString();

        if ($request->ajax()) {
            return response()->json([
                'table' => view('payments.partials.payments_table', compact('payments'))->render(),
                'pagination' => (string) $payments->links()
            ]);
        }

        return view('payments.index', compact('payments', 'search'));
    }

    public function create(Request $request)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        // Get all active properties for the user's company
        $properties = \App\Models\Property::where('CompanyID', $companyId)
            ->orderBy('PropName')
            ->get();
        
        // Get customers based on property filter
        $customers = Customer::with('unit')
            ->whereHas('unit.property', function($q) use ($companyId) {
                $q->where('CompanyID', $companyId);
            })
            ->active()
            ->when($request->has('property_id'), function($query) use ($request) {
                $query->whereHas('unit', function($q) use ($request) {
                    $q->where('PropID', $request->property_id);
                });
            })
            ->orderBy('CustomerName')
            ->get();
            
        $invoices = [];
        
        // Check if customer has any outstanding rent payments
        if ($request->has('customer_id')) {
            $customer = Customer::with('unit.property')
                ->where('CustomerID', $request->customer_id)
                ->whereHas('unit.property', function($q) use ($companyId) {
                    $q->where('CompanyID', $companyId);
                })
                ->first();
                
            if ($customer) {
                $invoices = RentServiceBill::where('CustomerID', $customer->CustomerID)
                    ->where('BillStatus', '!=', 'paid')
                    ->get()
                    ->map(function($invoice) {
                        return [
                            'id' => 'rent_' . $invoice->id,
                            'invoice_number' => $invoice->invoice_number,
                            'amount' => $invoice->total_amount - $invoice->amount_paid,
                            'type' => 'Rent Invoice',
                            'due_date' => $invoice->due_date->format('Y-m-d'),
                        ];
                    });
            }
        }

        return view('payments.create', [
            'properties' => $properties,
            'customers' => $customers,
            'invoices' => $invoices,
            'selectedProperty' => $request->property_id
        ]);
    }

    public function store(Request $request)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        $validated = $request->validate([
            'customer_id' => [
                'required',
                'exists:customer,CustomerID',
                function ($attribute, $value, $fail) use ($companyId) {
                    $customer = Customer::with('unit.property')
                        ->where('CustomerID', $value)
                        ->whereHas('unit.property', function($q) use ($companyId) {
                            $q->where('CompanyID', $companyId);
                        })
                        ->exists();
                    
                    if (!$customer) {
                        $fail('The selected customer is invalid or does not belong to your company.');
                    }
                },
            ],
            'amount' => 'required|numeric|min:0.01',
            'payment_method' => 'required|in:mpesa,bank_transfer,cash,cheque,other',
            'reference_number' => 'nullable|string|max:100',
            'payment_date' => 'required|date',
            'notes' => 'nullable|string',
        ]);

        // Generate receipt number in format: RCPT-YYMMDD-XXX (max 15 chars)
        $receiptNumber = 'RCPT-' . date('ymd') . '-' . strtoupper(Str::random(3));
        
        // Create payment record with the correct field names
        $payment = Payment::create([
            'CustomerID' => $validated['customer_id'],
            'PaymentDate' => $validated['payment_date'],
            'PaymentMode' => $validated['payment_method'],
            'ReceiptNo' => $receiptNumber,
            'TotalPayment' => $validated['amount'],
            'Processed' => 1, // Assuming 1 means processed
            'LastUpdateDate' => now(),
            'LastUpdateUser' =>$this->user()->id,
            'Notes' => $validated['notes'] ?? null,
        ]);

        return redirect()->route('payments.show', $payment)
            ->with('success', 'Payment recorded successfully.');
    }

    public function show($id)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        $payment = Payment::with(['customer.unit.property', 'receivedBy'])
            ->whereHas('customer.unit.property', function($q) use ($companyId) {
                $q->where('CompanyID', $companyId);
            })
            ->findOrFail($id);
            
        return view('payments.show', compact('payment'));
    }

    public function receipt($id)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        // Eager load the customer relationship with the necessary fields and company validation
        $payment = Payment::with([
            'customer' => function($query) {
                $query->select([
                    'CustomerID', 'CustomerName', 'TenantName', 'Address1', 'Address2', 'TelNo', 'Email', 'UnitID'
                ]);
            },
            'receivedBy'
        ])
        ->whereHas('customer.unit.property', function($q) use ($companyId) {
            $q->where('CompanyID', $companyId);
        })
        ->findOrFail($id);
        
        // If customer is not found, handle it gracefully
        if (!$payment->customer) {
            return back()->with('error', 'Customer not found for this payment.');
        }
        
        // Get company details for the logged-in user
        $company = \App\Models\Company::find($companyId);
        
        if (!$company) {
            return back()->with('error', 'Company information not found.');
        }
        
        return view('payments.receipt', [
            'payment' => $payment,
            'company' => $company
        ]);
    }

    /**
     * Download the payment receipt as PDF
     */
    public function download($id)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        $payment = Payment::with(['customer.unit.property', 'receivedBy'])
            ->whereHas('customer.unit.property', function($q) use ($companyId) {
                $q->where('CompanyID', $companyId);
            })
            ->findOrFail($id);
            
        $company = \App\Models\Company::find($companyId);
        
        if (!$company) {
            return back()->with('error', 'Company information not found.');
        }
        
        $pdf = PDF::loadView('payments.receipt', [
            'payment' => $payment,
            'company' => $company,
            'isPdf' => true 
        ]);
        
        $filename = 'receipt-' . $payment->ReceiptNo . '.pdf';
        
        return $pdf->download($filename);
    }
}
