<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Currency;
use App\Models\CustomerAccount;
use App\Models\Receipt;
use App\Models\CustomerJournal;
use App\Models\CashbookEntry;
use App\Models\CompanySettings;
use PDF;

class SalesCollectionReportController extends Controller
{
    // Display initial form
    public function index()
    {
        $currencies = Currency::orderBy('code')->get();
        
        return view('reports.sales-collection', compact('currencies'));
    }

    // Generate sales collection report
    public function generate(Request $request)
    {
        $request->validate([
            'date_from' => 'required|date',
            'date_to' => 'required|date|after_or_equal:date_from',
            'currency' => 'required',
        ]);

        $dateFrom = $request->date_from;
        $dateTo = $request->date_to;
        $currencyCode = $request->currency;
        $company = CompanySettings::first();

        $currencies = Currency::orderBy('code')->get();
        
        $collectionData = $this->getCollectionData($currencyCode, $dateFrom, $dateTo);

        return view('reports.sales-collection', compact(
            'collectionData',
            'dateFrom',
            'dateTo',
            'currencyCode',
            'currencies',
            'company'
        ));
    }

    // Download PDF
    public function downloadPdf(Request $request)
    {
        $request->validate([
            'date_from' => 'required|date',
            'date_to' => 'required|date|after_or_equal:date_from',
            'currency' => 'required',
        ]);

        $dateFrom = $request->date_from;
        $dateTo = $request->date_to;
        $currencyCode = $request->currency;
        $currency = Currency::where('code', $currencyCode)->first();
        $company = CompanySettings::first();

        $collectionData = $this->getCollectionData($currencyCode, $dateFrom, $dateTo);

        $pdf = PDF::loadView('reports.sales-collection-pdf', compact(
            'collectionData',
            'dateFrom',
            'dateTo',
            'currency',
            'company'
        ));

        return $pdf->download('sales-collection-report-' . $dateFrom . '-to-' . $dateTo . '.pdf');
    }

    // Retrieve collection data from receipts, journals, and cashbook
    private function getCollectionData($currencyCode, $dateFrom, $dateTo)
    {
        $collectionData = [];
        $balance = 0;

        // Get currency ID
        $currency = Currency::where('code', $currencyCode)->first();
        if (!$currency) {
            return $collectionData;
        }
        $currencyId = $currency->id;

        // 1. Receipts
        $receipts = Receipt::with('customer')
            ->where('currency_code', $currencyCode)
            ->whereBetween('receipt_date', [$dateFrom, $dateTo])
            ->orderBy('receipt_date')
            ->get();

        foreach ($receipts as $receipt) {
            $balance += $receipt->total_amount;
            
            $collectionData[] = [
                'date' => $receipt->receipt_date,
                'description' => 'Receipt',
                'reference' => $receipt->receipt_number,
                'customer_code' => $receipt->customer->customer_code ?? '',
                'customer_name' => $receipt->customer->customer_account ?? '',
                'dr' => 0,
                'cr' => $receipt->total_amount,
                'balance' => $balance,
                'source' => 'Receipt'
            ];
        }

        // 2. Customer Journals (CR entries only for collections)
        $journals = CustomerJournal::with('customer')
            ->where('currency_id', $currencyId)
            ->where('tr_code', 'CR') // Only credit entries for collections
            ->whereBetween('date', [$dateFrom, $dateTo])
            ->orderBy('date')
            ->get();

        foreach ($journals as $journal) {
            $balance += $journal->amount;
            
            $collectionData[] = [
                'date' => $journal->date,
                'description' => $journal->narration,
                'reference' => 'JNL' . str_pad($journal->id, 3, '0', STR_PAD_LEFT),
                'customer_code' => $journal->customer->customer_code ?? '',
                'customer_name' => $journal->customer->customer_account ?? '',
                'dr' => 0,
                'cr' => $journal->amount,
                'balance' => $balance,
                'source' => 'Journal'
            ];
        }

        // 3. Cashbook Entries (AR module with Receipt/Payment tr_code)
        $cashbookEntries = CashbookEntry::with(['customer'])
            ->where('module', 'AR')
            ->where('currency_id', $currencyId)
            ->whereBetween('date', [$dateFrom, $dateTo])
            ->orderBy('date')
            ->get();

        foreach ($cashbookEntries as $entry) {
            // Determine if this is a debit or credit transaction
            $drAmount = 0;
            $crAmount = 0;
            
            if ($entry->tr_code == 'Receipt') {
                $drAmount = $entry->amount;
                $balance += $entry->amount;
            } elseif ($entry->tr_code == 'Payment') {
                $crAmount = $entry->amount;
                $balance -= $entry->amount;
            }
            
            $collectionData[] = [
                'date' => $entry->date,
                'description' => $entry->description,
                'reference' => $entry->reference_type . ' ' . $entry->reference_id,
                'customer_code' => $entry->customer->customer_code ?? '',
                'customer_name' => $entry->customer->customer_account ?? '',
                'dr' => $drAmount,
                'cr' => $crAmount,
                'balance' => $balance,
                'source' => 'Cashbook'
            ];
        }

        // Sort by date
        usort($collectionData, function($a, $b) {
            return strtotime($a['date']) - strtotime($b['date']);
        });

        return $collectionData;
    }
}