<?php

namespace App\Livewire\Accounting;

use App\Models\Partner;
use App\Models\JournalEntryLine;
use App\Models\Setting;
use App\Services\AccountingService;
use Carbon\Carbon;
use Livewire\Component;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\PartnerLedgerExport;
use App\Exports\PartnerLedgerDetailExport;

class PartnerLedger extends Component
{

    public $dateFrom;
    public $dateTo;
    public $partnerType = 'customer'; // customer, supplier
    public $partnerTypeId = ''; // Specific sub-type filter
    public $search = '';

    // Drill down
    public $showDetailsModal = false;
    public ?Partner $selectedPartner = null;
    public $partnerLines = [];
    public $openingBalance = 0;
    public $closingBalance = 0;

    // ... (existing properties)

    public function mount()
    {
        $this->dateFrom = Carbon::now()->startOfMonth()->format('Y-m-d');
        $this->dateTo = Carbon::now()->endOfMonth()->format('Y-m-d');
    }

    public function getAvailablePartnerTypesProperty()
    {
        // Return ALL types
        return \App\Models\PartnerType::orderBy('name')->get();
    }

    public function viewDetails(Partner $partner)
    {
        $this->selectedPartner = $partner;
        
        // Determine relevant accounts (AR and AP)
        // We want to see ALL transactions for this partner in the ledger accounts
        $accountIds = \App\Models\Account::whereIn('code', [
            AccountingService::ACCOUNTS_RECEIVABLE, 
            AccountingService::ACCOUNTS_PAYABLE
        ])->pluck('id');
        
        if ($accountIds->isEmpty()) {
            $this->partnerLines = [];
            return;
        }

        // Fetch Lines
        $this->partnerLines = JournalEntryLine::query()
            ->whereIn('account_id', $accountIds)
            ->whereHas('journalEntry', function ($q) use ($partner) {
                $q->where('partner_id', $partner->id)
                  ->whereBetween('date', [$this->dateFrom, $this->dateTo]);
            })
            ->with(['journalEntry'])
            ->get()
            ->sortBy(fn($line) => $line->journalEntry->date)
            ->values();

        $this->showDetailsModal = true;
    }

    public function closeDetailsModal()
    {
        $this->showDetailsModal = false;
        $this->selectedPartner = null;
        $this->partnerLines = [];
    }

    public function export()
    {
        $fileName = 'partner-ledger-' . Carbon::now()->format('Y-m-d') . '.xlsx';
        return Excel::download(new PartnerLedgerExport(
            $this->dateFrom, 
            $this->dateTo, 
            $this->partnerTypeId, 
            $this->search
        ), $fileName);
    }

    public function exportDetails()
    {
        if (!$this->selectedPartner) {
            return;
        }
        
        $fileName = 'ledger-' . $this->selectedPartner->slug . '-' . Carbon::now()->format('Y-m-d') . '.xlsx';
        return Excel::download(new PartnerLedgerDetailExport(
            $this->selectedPartner->id,
            $this->dateFrom, 
            $this->dateTo
        ), $fileName);
    }

    public function render()
    {
        $targetGroup = null;
        $partnerTypeFilter = null;
        
        if ($this->partnerTypeId) {
            $type = \App\Models\PartnerType::find($this->partnerTypeId);
            if ($type) {
                if ($type->is_supplier_group && !$type->is_customer_group) {
                    $targetGroup = 'supplier';
                } elseif ($type->is_customer_group && !$type->is_supplier_group) {
                    $targetGroup = 'customer';
                } else {
                    $targetGroup = 'mixed'; // Both or neither
                }
            }
        }
        
        // Determine accounts to query
        $accountCodes = [];
        if ($targetGroup === 'customer') {
            $accountCodes = [AccountingService::ACCOUNTS_RECEIVABLE];
        } elseif ($targetGroup === 'supplier') {
            $accountCodes = [AccountingService::ACCOUNTS_PAYABLE];
        } else {
            // All or Mixed: Query BOTH
            $accountCodes = [
                AccountingService::ACCOUNTS_RECEIVABLE,
                AccountingService::ACCOUNTS_PAYABLE
            ];
        }
        
        $accounts = \App\Models\Account::whereIn('code', $accountCodes)->pluck('id');
        
        $partners = Partner::query()
            ->with(['partnerType']) // Eager load for view logic
            ->when($this->partnerTypeId, function ($q) {
                $q->where('partner_type_id', $this->partnerTypeId);
            })
            // If no specific partner type, we show ALL partners (no category filter)
            ->when($this->search, function ($q) {
                $q->where(function($sub) {
                    $sub->where('name', 'like', '%' . $this->search . '%')
                        ->orWhere('code', 'like', '%' . $this->search . '%')
                        ->orWhere('phone', 'like', '%' . $this->search . '%');
                });
            });
        
        // Add aggregations for period debits and credits
        if ($accounts->isNotEmpty()) {
            $partners
                ->withSum(['journalEntryLines as period_debit' => function($q) use ($accounts) {
                    $q->whereIn('account_id', $accounts)
                      ->whereHas('journalEntry', function($sq) {
                          $sq->whereBetween('date', [$this->dateFrom, $this->dateTo])
                             ->where('partner_id', '!=', null);
                      });
                }], 'debit')
                ->withSum(['journalEntryLines as period_credit' => function($q) use ($accounts) {
                    $q->whereIn('account_id', $accounts)
                      ->whereHas('journalEntry', function($sq) {
                          $sq->whereBetween('date', [$this->dateFrom, $this->dateTo])
                             ->where('partner_id', '!=', null);
                      });
                }], 'credit');
        }
        
        $partners = $partners->orderBy('name')->get();

        return view('livewire.accounting.partner-ledger', [
            'partners' => $partners,
        ]);
    }
}
