<?php

namespace App\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\Account;
use App\Models\Party;
use App\Models\Currency;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Cache;

class Accounts extends Component
{
    use WithPagination;

    public $search = '';
    public $filter_party_id = '';
    public $statusFilter = 'all';
    public $isModalOpen = false;
    
    // Form fields
    public $account_id;
    public $party_id = '';
    public $currency_id = '';
    public $account_number;
    public $name;
    public $notes;
    public $is_active = true;

    // Searchable Dropdown for Parties
    public $partySearch = '';
    public $isPartyDropdownOpen = false;

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

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

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

    public function selectParty($id)
    {
        $this->party_id = $id;
        $this->isPartyDropdownOpen = false;
        $this->partySearch = '';
    }

    public function generateAccountNumber()
    {
        $prefix = Cache::rememberForever('setting.prefix_account', function () {
            return \App\Models\Setting::where('key', 'prefix_account')->value('value') ?? 'ACC-';
        });

        // Find the latest account ID to generate a new sequential number
        $latestId = Account::max('id') ?? 0;
        $nextId = $latestId + 1;
        
        $this->account_number = $prefix . str_pad($nextId, 4, '0', STR_PAD_LEFT);
    }

    public function openModal()
    {
        abort_if(!auth()->user()->can('create records'), 403);
        $this->resetValidation();
        $this->reset([
            'account_id', 'party_id', 'currency_id', 'account_number', 'name', 'notes', 'partySearch'
        ]);
        
        $this->is_active = true;
        
        // Auto-select base currency if possible
        $baseCurrencyCode = Cache::rememberForever('setting.base_currency', function () {
            return \App\Models\Setting::where('key', 'base_currency')->value('value') ?? 'SAR';
        });
        $baseCurrency = Currency::where('code', $baseCurrencyCode)->first();
        if ($baseCurrency) {
            $this->currency_id = $baseCurrency->id;
        }

        $this->generateAccountNumber();
        $this->isModalOpen = true;
    }

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

    public function edit($id)
    {
        abort_if(!auth()->user()->can('update records'), 403);
        $this->resetValidation();
        $account = Account::findOrFail($id);
        
        $this->account_id = $account->id;
        $this->party_id = $account->party_id;
        $this->currency_id = $account->currency_id;
        $this->account_number = $account->account_number;
        $this->name = $account->name;
        $this->notes = $account->notes;
        $this->is_active = $account->is_active ? 1 : 0;
        
        $this->isModalOpen = true;
    }

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

    protected function rules()
    {
        return [
            'party_id' => ['required', 'exists:parties,id'],
            'currency_id' => ['required', 'exists:currencies,id'],
            'account_number' => ['required', 'string', 'max:255', Rule::unique('accounts')->ignore($this->account_id)],
            'name' => ['required', 'string', 'max:255'],
            'notes' => ['nullable', 'string'],
            'is_active' => ['boolean'],
        ];
    }

    protected function messages()
    {
        return [
            'party_id.required' => 'الرجاء اختيار الطرف صاحب الحساب.',
            'currency_id.required' => 'الرجاء اختيار عملة الحساب.',
            'account_number.required' => 'رقم الحساب مطلوب.',
            'account_number.unique' => 'رقم الحساب مسجل مسبقاً، يرجى اختيار رقم آخر.',
            'name.required' => 'اسم الحساب مطلوب.',
        ];
    }

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

        $data = [
            'party_id' => $this->party_id,
            'currency_id' => $this->currency_id,
            'account_number' => $this->account_number,
            'name' => $this->name,
            'notes' => $this->notes,
            'is_active' => (bool) $this->is_active,
        ];

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

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

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

    public function render()
    {
        $query = Account::with(['party', 'currency']);

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

        if ($this->filter_party_id) {
            $query->where('party_id', $this->filter_party_id);
        }

        if ($this->statusFilter === 'active') {
            $query->where('is_active', true);
        } elseif ($this->statusFilter === 'inactive') {
            $query->where('is_active', false);
        }

        $accounts = $query->latest()->paginate(10);
        $currencies = Currency::where('is_active', true)->get();

        // Parties search query
        $parties = Party::query();
        if ($this->partySearch) {
            $parties->where('name', 'like', '%' . $this->partySearch . '%')
                    ->orWhere('code', 'like', '%' . $this->partySearch . '%');
        }
        $partiesList = $parties->take(10)->get();
        $selectedParty = Party::find($this->party_id);
        
        $allParties = Party::where('is_active', true)->orderBy('name')->get();

        return view('livewire.accounts', [
            'accounts' => $accounts,
            'currencies' => $currencies,
            'partiesList' => $partiesList,
            'selectedParty' => $selectedParty,
            'allParties' => $allParties
        ])->layout('layouts.app');
    }
}
