<?php

namespace App\Core\Repositories;

use App\Models\ChartOfAccount;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;

/**
 * Chart of Accounts Repository
 * Handles all database operations for chart of accounts
 */
class ChartOfAccountRepository
{
    /**
     * Get all accounts
     */
    public function getAll(): Collection
    {
        return ChartOfAccount::with('parent')
            ->orderBy('type')
            ->orderBy('code')
            ->get();
    }

    /**
     * Get paginated accounts
     */
    public function getPaginated(int $perPage = 15, array $filters = []): LengthAwarePaginator
    {
        $query = ChartOfAccount::with('parent');

        if (isset($filters['type'])) {
            $query->where('type', $filters['type']);
        }

        if (isset($filters['category'])) {
            $query->where('category', $filters['category']);
        }

        if (isset($filters['is_active'])) {
            $query->where('is_active', $filters['is_active']);
        }

        if (isset($filters['search'])) {
            $search = $filters['search'];
            $query->where(function ($q) use ($search) {
                $q->where('code', 'like', "%{$search}%")
                    ->orWhere('name', 'like', "%{$search}%");
            });
        }

        return $query->orderBy('type')
            ->orderBy('code')
            ->paginate($perPage);
    }

    /**
     * Get account by ID
     */
    public function getById(int $id): ?ChartOfAccount
    {
        return ChartOfAccount::with(['parent', 'children'])->find($id);
    }

    /**
     * Get account by code
     */
    public function getByCode(string $code): ?ChartOfAccount
    {
        return ChartOfAccount::where('code', $code)->first();
    }

    /**
     * Get accounts by type
     */
    public function getByType(string $type): Collection
    {
        return ChartOfAccount::where('type', $type)
            ->where('is_active', true)
            ->orderBy('code')
            ->get();
    }

    /**
     * Create a new account
     */
    public function create(array $data): ChartOfAccount
    {
        return ChartOfAccount::create($data);
    }

    /**
     * Update an account
     */
    public function update(ChartOfAccount $account, array $data): bool
    {
        return $account->update($data);
    }

    /**
     * Delete an account
     */
    public function delete(ChartOfAccount $account): bool
    {
        if ($account->is_system) {
            throw new \Exception('System accounts cannot be deleted.');
        }

        return $account->delete();
    }

    /**
     * Update account balance
     */
    public function updateBalance(ChartOfAccount $account, float $amount, string $type): bool
    {
        if ($type === 'debit' && $account->isDebitAccount()) {
            $account->increment('current_balance', $amount);
        } elseif ($type === 'credit' && $account->isDebitAccount()) {
            $account->decrement('current_balance', $amount);
        } elseif ($type === 'credit' && $account->isCreditAccount()) {
            $account->increment('current_balance', $amount);
        } elseif ($type === 'debit' && $account->isCreditAccount()) {
            $account->decrement('current_balance', $amount);
        }

        return true;
    }
}
