<?php

namespace App\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\Ledger;
use App\Models\Party;
use App\Models\Account;
use App\Models\Entity;
use App\Models\Branch;
use App\Models\Center;
use App\Models\Project;
use App\Models\Setting;
use Illuminate\Validation\Rule;

class Ledgers extends Component
{
    use WithPagination;

    public $search = '';
    public $isModalOpen = false;

    // Filters
    public $filter_party_id = '';
    public $filter_account_id = '';
    public $filter_entity_id = '';
    public $filter_branch_id = '';
    public $filter_center_id = '';
    public $filter_project_id = '';
    public $statusFilter = 'all';
    
    // Form fields
    public $ledger_id;
    public $account_id;
    public $party_id; // For filtering
    public $entity_id;
    public $branch_id;
    public $center_id;
    public $project_id;
    public $ledger_number;
    public $code;
    public $name;
    public $description;
    public $is_active = true;

    // Dropdown Data
    public $parties = [];
    public $accounts = [];
    public $entities = [];
    public $branches = [];
    public $centers = [];
    public $projects = [];

    public function mount()
    {
        $this->loadInitialData();
    }

    public function loadInitialData()
    {
        $this->parties = Party::where('is_active', true)->get();
        $this->entities = Entity::where('is_active', true)->get();
        // Load branches and projects if entity is selected, otherwise load all or empty.
        // For standard setup, we can load all initially or empty until entity is selected.
        // Based on user feedback: "تكون ظاهرة في حال تم اختيار كيان فيقوم بلفترة الباقي".
        // This means we should probably load all of them first if no entity is selected,
        // or just load them dynamically. Let's load them dynamically when entity is chosen.
        $this->branches = Branch::where('is_active', true)->get();
        $this->projects = Project::where('is_active', true)->get();
        $this->centers = Center::where('is_active', true)->get();
    }

    public function updatedSearch()
    {
        $this->resetPage();
    }

    public function updatingFilterPartyId()
    {
        $this->filter_account_id = '';
        $this->resetPage();
    }

    public function updatingFilterAccountId() { $this->resetPage(); }

    public function updatingFilterEntityId()
    {
        $this->filter_branch_id = '';
        $this->filter_center_id = '';
        $this->filter_project_id = '';
        $this->resetPage();
    }

    public function updatingFilterBranchId()
    {
        $this->filter_center_id = '';
        $this->resetPage();
    }

    public function updatingFilterCenterId() { $this->resetPage(); }
    public function updatingFilterProjectId() { $this->resetPage(); }
    public function updatingStatusFilter() { $this->resetPage(); }

    // Dynamic Filtering Methods
    public function updatedPartyId($value)
    {
        if ($value) {
            $this->accounts = Account::where('party_id', $value)->where('is_active', true)->get();
        } else {
            $this->accounts = [];
        }
        $this->account_id = null; // Reset account selection
    }

    public function updatedEntityId($value)
    {
        if ($value) {
            $this->branches = Branch::where('entity_id', $value)->where('is_active', true)->get();
            $this->projects = Project::where('entity_id', $value)->where('is_active', true)->get();
        } else {
            $this->branches = Branch::where('is_active', true)->get();
            $this->projects = Project::where('is_active', true)->get();
        }
        $this->branch_id = null;
        $this->project_id = null;
        $this->center_id = null;
    }

    public function updatedBranchId($value)
    {
        if ($value) {
            $this->centers = Center::where('branch_id', $value)->where('is_active', true)->get();
        } else {
            // If branch is reset, but entity is set, get centers of branches of that entity? 
            // Keep it simple: show all or filter based on entity branches
            if ($this->entity_id) {
                $branchIds = Branch::where('entity_id', $this->entity_id)->pluck('id');
                $this->centers = Center::whereIn('branch_id', $branchIds)->where('is_active', true)->get();
            } else {
                $this->centers = Center::where('is_active', true)->get();
            }
        }
        $this->center_id = null;
    }

    public function generateLedgerNumber()
    {
        $prefix = Setting::where('key', 'prefix_ledger')->value('value') ?? 'LDG-';
        
        $lastLedger = Ledger::where('ledger_number', 'like', $prefix . '%')
            ->orderByRaw('CAST(SUBSTRING(ledger_number, LENGTH(?) + 1) AS UNSIGNED) DESC', [$prefix])
            ->first();

        if ($lastLedger) {
            $lastNumber = intval(substr($lastLedger->ledger_number, strlen($prefix)));
            return $prefix . str_pad($lastNumber + 1, 4, '0', STR_PAD_LEFT);
        }
        
        return $prefix . '0001';
    }

    public function openModal()
    {
        abort_if(!auth()->user()->can('create records'), 403);
        $this->resetValidation();
        $this->reset([
            'ledger_id', 'party_id', 'account_id', 'entity_id', 'branch_id', 
            'center_id', 'project_id', 'code', 'name', 'description'
        ]);
        
        $this->ledger_number = $this->generateLedgerNumber();
        $this->is_active = true;
        
        // Reset dynamic lists
        $this->accounts = [];
        $this->loadInitialData(); // Reset hierarchical lists to show all

        $this->isModalOpen = true;
    }

    public function closeModal()
    {
        $this->isModalOpen = false;
    }

    public function toggleStatus($id)
    {
        abort_if(!auth()->user()->can('update records'), 403);
        $ledger = Ledger::findOrFail($id);
        $ledger->is_active = !$ledger->is_active;
        $ledger->save();
        
        session()->flash('message', $ledger->is_active ? 'تم تنشيط الدفتر بنجاح.' : 'تم إيقاف الدفتر بنجاح.');
    }

    public function edit($id)
    {
        abort_if(!auth()->user()->can('update records'), 403);
        $this->resetValidation();
        
        $ledger = Ledger::with('account')->findOrFail($id);
        
        $this->ledger_id = $ledger->id;
        $this->party_id = $ledger->account->party_id ?? null;
        
        // Load accounts for the selected party
        if ($this->party_id) {
            $this->accounts = Account::where('party_id', $this->party_id)->where('is_active', true)->get();
        } else {
            $this->accounts = [];
        }
        
        $this->account_id = $ledger->account_id;
        $this->entity_id = $ledger->entity_id;
        
        // Load filtered lists based on entity/branch
        $this->updatedEntityId($this->entity_id);
        
        // Re-assign because updatedEntityId resets them to null
        $this->branch_id = $ledger->branch_id;
        $this->project_id = $ledger->project_id;
        
        if ($this->branch_id) {
            $this->updatedBranchId($this->branch_id);
            // Re-assign because updatedBranchId resets it to null
            $this->center_id = $ledger->center_id;
        } else {
            $this->center_id = $ledger->center_id;
        }
        
        $this->ledger_number = $ledger->ledger_number;
        $this->code = $ledger->code;
        $this->name = $ledger->name;
        $this->description = $ledger->description;
        $this->is_active = $ledger->is_active ? 1 : 0;
        
        $this->isModalOpen = true;
    }

    protected function rules()
    {
        return [
            'account_id' => ['required', 'exists:accounts,id'],
            'entity_id' => ['nullable', 'exists:entities,id'],
            'branch_id' => ['nullable', 'exists:branches,id'],
            'center_id' => ['nullable', 'exists:centers,id'],
            'project_id' => ['nullable', 'exists:projects,id'],
            'ledger_number' => ['required', 'string', 'max:255', Rule::unique('ledgers')->ignore($this->ledger_id)],
            'code' => ['required', 'string', 'max:255', Rule::unique('ledgers')->ignore($this->ledger_id)],
            'name' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string'],
            'is_active' => ['boolean'],
        ];
    }

    protected function messages()
    {
        return [
            'account_id.required' => 'يجب اختيار الحساب المرتبط بالدفتر.',
            'ledger_number.required' => 'رقم الدفتر التسلسلي مطلوب.',
            'ledger_number.unique' => 'رقم الدفتر هذا مستخدم مسبقاً.',
            'code.required' => 'رمز الدفتر مطلوب.',
            'code.unique' => 'هذا الرمز مسجل مسبقاً، يرجى اختيار رمز آخر.',
            'name.required' => 'حقل اسم الدفتر مطلوب.',
        ];
    }

    public function save()
    {
        $this->validate();

        $data = [
            'account_id' => $this->account_id,
            'entity_id' => $this->entity_id ?: null,
            'branch_id' => $this->branch_id ?: null,
            'center_id' => $this->center_id ?: null,
            'project_id' => $this->project_id ?: null,
            'ledger_number' => $this->ledger_number,
            'code' => $this->code,
            'name' => $this->name,
            'description' => $this->description,
            'is_active' => (bool) $this->is_active,
        ];

        if (!$this->ledger_id) {
            $data['created_by'] = auth()->id();
        }

        Ledger::updateOrCreate(['id' => $this->ledger_id], $data);

        session()->flash('message', $this->ledger_id ? 'تم تحديث بيانات الدفتر بنجاح.' : 'تم إضافة الدفتر الجديد بنجاح.');
        
        $this->closeModal();
    }

    public function render()
    {
        $query = Ledger::with(['account.party', 'entity', 'branch', 'center', 'project']);

        if ($this->search) {
            $query->where(function($q) {
                $q->where('name', 'like', '%'.$this->search.'%')
                  ->orWhere('code', 'like', '%'.$this->search.'%')
                  ->orWhere('ledger_number', 'like', '%'.$this->search.'%')
                  ->orWhereHas('account', function($q) {
                      $q->where('account_number', 'like', '%'.$this->search.'%')
                        ->orWhere('name', 'like', '%'.$this->search.'%')
                        ->orWhereHas('party', function($q) {
                            $q->where('name', 'like', '%'.$this->search.'%')
                              ->orWhere('code', 'like', '%'.$this->search.'%');
                        });
                  });
            });
        }

        if ($this->filter_party_id) {
            $query->whereHas('account', function($q) {
                $q->where('party_id', $this->filter_party_id);
            });
        }
        if ($this->filter_account_id) {
            $query->where('account_id', $this->filter_account_id);
        }
        if ($this->filter_entity_id) {
            $query->where('entity_id', $this->filter_entity_id);
        }
        if ($this->filter_branch_id) {
            $query->where('branch_id', $this->filter_branch_id);
        }
        if ($this->filter_center_id) {
            $query->where('center_id', $this->filter_center_id);
        }
        if ($this->filter_project_id) {
            $query->where('project_id', $this->filter_project_id);
        }
        if ($this->statusFilter === 'active') {
            $query->where('is_active', true);
        } elseif ($this->statusFilter === 'inactive') {
            $query->where('is_active', false);
        }

        $ledgers = $query->latest()->paginate(10);

        $allParties = Party::where('is_active', true)->orderBy('name')->get();
        
        $accountsQuery = Account::where('is_active', true);
        if ($this->filter_party_id) {
            $accountsQuery->where('party_id', $this->filter_party_id);
        }
        $allAccounts = $accountsQuery->orderBy('name')->get();

        $allEntities = Entity::where('is_active', true)->orderBy('name')->get();
        
        $branchesQuery = Branch::where('is_active', true);
        if ($this->filter_entity_id) {
            $branchesQuery->where('entity_id', $this->filter_entity_id);
        }
        $allBranches = $branchesQuery->orderBy('name')->get();

        $centersQuery = Center::where('is_active', true);
        if ($this->filter_branch_id) {
            $centersQuery->where('branch_id', $this->filter_branch_id);
        } elseif ($this->filter_entity_id) {
            $centersQuery->whereHas('branch', function($q) {
                $q->where('entity_id', $this->filter_entity_id);
            });
        }
        $allCenters = $centersQuery->orderBy('name')->get();

        $projectsQuery = Project::where('is_active', true);
        if ($this->filter_entity_id) {
            $projectsQuery->where('entity_id', $this->filter_entity_id);
        }
        $allProjects = $projectsQuery->orderBy('name')->get();

        return view('livewire.ledgers', [
            'ledgers' => $ledgers,
            'allParties' => $allParties,
            'allAccounts' => $allAccounts,
            'allEntities' => $allEntities,
            'allBranches' => $allBranches,
            'allCenters' => $allCenters,
            'allProjects' => $allProjects
        ])->layout('layouts.app');
    }
}
