<?php

namespace App\Http\Controllers;

use App\Models\Bank;
use App\Models\BankAccount;
use App\Models\ChartOfAccount;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class BankAccountController extends Controller
{
    /**
     * Display a listing of the bank accounts.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $this->authorize('view_bank_accounts');

        $user = auth()->user();
        $query = BankAccount::query();

        if (!$user->isSystemAdmin()) {
            $query->where('company_id', $user->company_id);
        }

        $bankAccounts = $query->with(['bank', 'chartOfAccount'])
            ->paginate(10);
        return view('banking.accounts.index', compact('bankAccounts'));
    }

    /**
     * Show the form for creating a new bank account.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $this->authorize('create_bank_accounts');

        $user = auth()->user();
        $query = Bank::query();

        if (!$user->isSystemAdmin()) {
            $query->where('company_id', $user->company_id);
        }

        $banks = $query->where('is_active', true)
            ->get();

        return view('banking.accounts.create', compact('banks'));
    }

    /**
     * Store a newly created bank account in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->authorize('create_bank_accounts');

        $validated = $request->validate([
            'bank_id' => 'required|exists:banks,id',
            'account_number' => 'required|string|max:50|unique:bank_accounts',
            'account_name' => 'required|string|max:255',
            'currency' => 'required|string|max:10',
            'opening_balance' => 'required|numeric',
            'opening_date' => 'required|date',
            'description' => 'nullable|string',
            'is_active' => 'required|boolean',
        ]);

        // Get bank to determine company_id
        $bank = Bank::findOrFail($request->bank_id);

        // Set current_balance equal to opening_balance when creating a new account
        $validated['current_balance'] = $validated['opening_balance'];

        // Add company_id to validated data
        $validated['company_id'] = $bank->company_id;

        try {
            DB::beginTransaction();

            // إنشاء حساب في شجرة الحسابات للحساب البنكي تلقائيًا
            $chartAccount = $this->createBankChartAccount($request->account_name, $request->currency, $request->opening_balance, $request->is_active, $request->bank_id, $bank->company_id);

            // إذا لم يتم إنشاء الحساب في شجرة الحسابات، نعود إلى الصفحة السابقة مع رسالة الخطأ
            if (!$chartAccount) {
                DB::rollBack();
                return redirect()->back()->withInput();
            }

            // تعيين معرف الحساب المنشأ
            $validated['chart_account_id'] = $chartAccount->id;

            // إنشاء الحساب البنكي
            $bankAccount = BankAccount::create($validated);

            // Log to system log instead of activity log
            Log::info('Created new bank account: ' . $bankAccount->account_name, [
                'user_id' => auth()->id(),
                'bank_account_id' => $bankAccount->id,
                'chart_account_id' => $chartAccount->id
            ]);

            DB::commit();

            return redirect()->route('bank-accounts.index')
                ->with('success', 'تم إنشاء الحساب البنكي بنجاح وربطه بشجرة الحسابات.');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error creating bank account: ' . $e->getMessage());

            return redirect()->back()
                ->withInput()
                ->with('error', 'حدث خطأ أثناء إنشاء الحساب البنكي. الرجاء المحاولة مرة أخرى.');
        }
    }

    /**
     * Display the specified bank account.
     *
     * @param  \App\Models\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function show(BankAccount $bankAccount)
    {
        $this->authorize('view_bank_accounts');

        // Verify bank account belongs to current company
        $user = auth()->user();
        if (!$user->isSystemAdmin() && $bankAccount->company_id !== $user->company_id) {
            abort(403, 'Unauthorized access to this bank account.');
        }

        // Load related transactions
        $transactions = $bankAccount->transactions()
            ->orderBy('transaction_date', 'desc')
            ->paginate(15);

        return view('banking.accounts.show', compact('bankAccount', 'transactions'));
    }

    /**
     * Show the form for editing the specified bank account.
     *
     * @param  \App\Models\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function edit(BankAccount $bankAccount)
    {
        $this->authorize('edit_bank_accounts');

        $user = auth()->user();
        // Verify bank account belongs to current company
        if (!$user->isSystemAdmin() && $bankAccount->company_id !== $user->company_id) {
            abort(403, 'Unauthorized access to this bank account.');
        }

        // Filter banks by current company
        $query = Bank::query();
        if (!$user->isSystemAdmin()) {
            $query->where('company_id', $user->company_id);
        }
        $banks = $query->where('is_active', true)
            ->get();
        
        $caQuery = ChartOfAccount::where('account_type', 'asset');
        if (!$user->isSystemAdmin()) {
            $caQuery->where('company_id', $user->company_id);
        }
        $chartAccounts = $caQuery->get();

        return view('banking.accounts.edit', compact('bankAccount', 'banks', 'chartAccounts'));
    }

    /**
     * Update the specified bank account in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, BankAccount $bankAccount)
    {
        $this->authorize('edit_bank_accounts');

        $user = auth()->user();
        // Verify bank account belongs to current company
        if (!$user->isSystemAdmin() && $bankAccount->company_id !== $user->company_id) {
            abort(403, 'Unauthorized access to this bank account.');
        }

        $validated = $request->validate([
            'bank_id' => 'required|exists:banks,id',
            'account_number' => 'required|string|max:50|unique:bank_accounts,account_number,' . $bankAccount->id,
            'account_name' => 'required|string|max:255',
            'currency' => 'required|string|max:10',
            'chart_account_id' => 'required|exists:chart_of_accounts,id',
            'description' => 'nullable|string',
            'is_active' => 'required|boolean',
        ]);

        try {
            DB::beginTransaction();

            $bankAccount->update($validated);

            // تحديث الحساب في شجرة الحسابات
            if ($bankAccount->chart_account_id) {
                $chartAccount = ChartOfAccount::find($bankAccount->chart_account_id);
                if ($chartAccount) {
                    // التحقق من أن الحساب تحت حساب البنك الصحيح
                    $bank = Bank::find($bankAccount->bank_id);
                    $bankParentAccount = ChartOfAccount::where('company_id', $bankAccount->company_id)
                        ->where('account_type', 'asset')
                        ->where('is_bank_account', true)
                        ->where('name', $bank->name)
                        ->where('is_parent', true)
                        ->first();

                    // إذا وجدنا حساب البنك الأب ولكن الحساب البنكي ليس تحته، نقوم بتحديث parent_id
                    if ($bankParentAccount && $chartAccount->parent_id != $bankParentAccount->id) {
                        $chartAccount->parent_id = $bankParentAccount->id;
                        $chartAccount->level = $bankParentAccount->level + 1;
                    }

                    // تحديث بيانات الحساب
                    $chartAccount->update([
                        'name' => $bankAccount->account_name,
                        'name_en' => $bankAccount->account_name,
                        'description' => 'حساب بنكي: ' . $bankAccount->account_name,
                        'is_active' => $bankAccount->is_active,
                        'currency' => $bankAccount->currency,
                        'parent_id' => $chartAccount->parent_id,
                        'level' => $chartAccount->level
                    ]);
                } else {
                    // إذا لم يتم العثور على الحساب، نقوم بإنشاء حساب جديد
                    $newChartAccount = $this->createBankChartAccount($bankAccount->account_name, $bankAccount->currency, 0, $bankAccount->is_active, $bankAccount->bank_id);
                    if ($newChartAccount) {
                        $bankAccount->chart_account_id = $newChartAccount->id;
                        $bankAccount->save();
                    }
                }
            } else {
                // إذا لم يكن هناك حساب مرتبط، نقوم بإنشاء حساب جديد
                $newChartAccount = $this->createBankChartAccount($bankAccount->account_name, $bankAccount->currency, 0, $bankAccount->is_active, $bankAccount->bank_id);
                if ($newChartAccount) {
                    $bankAccount->chart_account_id = $newChartAccount->id;
                    $bankAccount->save();
                }
            }

            // Log to system log instead of activity log
            Log::info('Updated bank account: ' . $bankAccount->account_name, [
                'user_id' => auth()->id(),
                'bank_account_id' => $bankAccount->id
            ]);

            DB::commit();

            return redirect()->route('bank-accounts.index')
                ->with('success', 'تم تحديث الحساب البنكي وحسابه في شجرة الحسابات بنجاح.');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error updating bank account: ' . $e->getMessage());

            return redirect()->back()
                ->withInput()
                ->with('error', 'حدث خطأ أثناء تحديث الحساب البنكي. الرجاء المحاولة مرة أخرى.');
        }
    }

    /**
     * Remove the specified bank account from storage.
     *
     * @param  \App\Models\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function destroy(BankAccount $bankAccount)
    {
        $this->authorize('delete_bank_accounts');

        $user = auth()->user();
        // Security check: Ensure the bank account belongs to the current company
        if (!$user->isSystemAdmin() && $bankAccount->company_id !== $user->company_id) {
            abort(403, 'Unauthorized action.');
        }

        try {
            DB::beginTransaction();

            // Check if bank account has any transactions
            if ($bankAccount->transactions()->count() > 0) {
                return redirect()->back()
                    ->with('error', 'لا يمكن حذف الحساب البنكي المرتبط بمعاملات.');
            }

            // حفظ معرف الحساب المحاسبي قبل حذف الحساب البنكي
            $chartAccountId = $bankAccount->chart_account_id;

            // تسجيل في سجل النظام بدلاً من سجل النشاط
            Log::info('تم حذف الحساب البنكي: ' . $bankAccount->account_name, [
                'user_id' => auth()->id(),
                'bank_account_id' => $bankAccount->id,
                'account_name' => $bankAccount->account_name,
                'chart_account_id' => $chartAccountId
            ]);

            // حذف الحساب البنكي
            $bankAccount->delete();

            // حذف الحساب المحاسبي المرتبط إذا كان موجوداً
            if ($chartAccountId) {
                $chartAccount = ChartOfAccount::find($chartAccountId);
                if ($chartAccount) {
                    // التحقق مما إذا كان الحساب المحاسبي له حركات
                    $hasJournalItems = $chartAccount->journalItems()->exists();

                    if (!$hasJournalItems) {
                        $chartAccount->delete();
                        Log::info('تم حذف الحساب المحاسبي المرتبط', [
                            'user_id' => auth()->id(),
                            'chart_account_id' => $chartAccountId
                        ]);
                    } else {
                        // إذا كان له حركات، نقوم فقط بتعطيله
                        $chartAccount->update(['is_active' => false]);
                        Log::info('تم تعطيل الحساب المحاسبي المرتبط (له حركات)', [
                            'user_id' => auth()->id(),
                            'chart_account_id' => $chartAccountId
                        ]);
                    }
                }
            }

            DB::commit();

            return redirect()->route('bank-accounts.index')
                ->with('success', 'تم حذف الحساب البنكي بنجاح.');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error deleting bank account: ' . $e->getMessage());

            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء حذف الحساب البنكي. الرجاء المحاولة مرة أخرى.');
        }
    }

    /**
     * Display the bank account statement.
     *
     * @param  \App\Models\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function statement(BankAccount $bankAccount, Request $request)
    {
        $this->authorize('view_bank_accounts');

        $user = auth()->user();
        if (!$user->isSystemAdmin() && $bankAccount->company_id !== $user->company_id) {
            abort(403, 'Unauthorized access to this bank account.');
        }

        $startDate = $request->input('from_date', now()->subMonths(1)->format('Y-m-d'));
        $endDate = $request->input('to_date', now()->format('Y-m-d'));

        // Apply type filter if provided
        $query = $bankAccount->transactions()
            ->whereBetween('transaction_date', [$startDate, $endDate]);

        if ($request->has('type') && $request->type) {
            $query->where('transaction_type', $request->type);
        }

        $transactions = $query->orderBy('transaction_date')->paginate(15);

        // Get all transactions for totals calculation (without pagination)
        $allTransactions = $bankAccount->transactions()
            ->whereBetween('transaction_date', [$startDate, $endDate])
            ->where('status', 'completed')
            ->get();

        // Calculate totals from all transactions
        $totalDeposits = $allTransactions->whereIn('transaction_type', ['deposit', 'transfer_in'])->sum('amount');
        $totalWithdrawals = $allTransactions->whereIn('transaction_type', ['withdrawal', 'transfer_out'])->sum('amount');

        $openingBalance = $bankAccount->getBalanceAsOf($startDate);

        return view('banking.accounts.statement', compact(
            'bankAccount',
            'transactions',
            'startDate',
            'endDate',
            'openingBalance',
            'totalDeposits',
            'totalWithdrawals'
        ));
    }

    /**
     * إنشاء حساب في شجرة الحسابات للحساب البنكي
     *
     * @param string $accountName اسم الحساب البنكي
     * @param string $currency عملة الحساب
     * @param float $openingBalance الرصيد الافتتاحي
     * @param bool $isActive حالة الحساب (نشط/غير نشط)
     * @param int $bankId معرف البنك الذي ينتمي إليه الحساب
     * @return \App\Models\ChartOfAccount
     */
    private function createBankChartAccount($accountName, $currency, $openingBalance, $isActive, $bankId = null, $companyId = null)
    {
        if (!$companyId) {
            $companyId = auth()->user()->company_id;
        }

        // الحصول على معلومات البنك
        $bank = null;
        if ($bankId) {
            $bank = Bank::find($bankId);
        }

        if (!$bank) {
            // إذا لم يتم العثور على البنك، نعرض رسالة خطأ
            session()->flash('error', 'لا يمكن إنشاء الحساب البنكي. لم يتم العثور على البنك المحدد.');
            return null;
        }

        // البحث عن حساب الأب باسم البنك
        $bankParentAccount = ChartOfAccount::where('company_id', $companyId)
            ->where('account_type', 'asset')
            ->where('is_bank_account', true)
            ->where('name', $bank->name)
            ->where('is_parent', true)
            ->first();

        // إذا لم يوجد حساب أب باسم البنك، نبحث عن حساب البنوك الرئيسي
        if (!$bankParentAccount) {
            // البحث عن حساب البنوك الرئيسي
            $mainBankAccount = ChartOfAccount::where('company_id', $companyId)
                ->where('account_type', 'asset')
                ->where('is_bank_account', true)
                ->where('parent_id', null)
                ->first();

            // إذا لم يوجد حساب البنوك الرئيسي، نقوم بإنشائه
            if (!$mainBankAccount) {
                $mainBankAccount = ChartOfAccount::create([
                    'company_id' => $companyId,
                    'account_code' => 'BANK',
                    'name' => 'حسابات بنكية',
                    'name_en' => 'Bank Accounts',
                    'account_type' => 'asset',
                    'sub_type' => 'bank',
                    'parent_id' => null,
                    'description' => 'حساب الأصول البنكية الرئيسي',
                    'is_active' => true,
                    'is_system' => true,
                    'opening_balance' => 0,
                    'current_balance' => 0,
                    'currency' => $currency,
                    'balance_type' => 'debit',
                    'is_cash_account' => false,
                    'is_bank_account' => true,
                    'level' => 1,
                    'is_parent' => true
                ]);
            }

            // نعرض رسالة خطأ للمستخدم
            session()->flash('error', 'لا يوجد حساب باسم البنك "' . $bank->name . '" في شجرة الحسابات. يرجى إنشاء حساب البنك أولاً.');
            return null;
        }

        // توليد رمز فريد للحساب
        $accountCode = 'BANK-' . time();

        // إنشاء الحساب البنكي تحت حساب البنك الأب
        $account = ChartOfAccount::create([
            'company_id' => $companyId,
            'account_code' => $accountCode,
            'name' => $accountName,
            'name_en' => $accountName,
            'account_type' => 'asset',
            'sub_type' => 'bank',
            'parent_id' => $bankParentAccount->id,
            'description' => 'حساب بنكي: ' . $accountName,
            'is_active' => $isActive,
            'is_system' => false,
            'opening_balance' => $openingBalance,
            'current_balance' => $openingBalance,
            'currency' => $currency,
            'balance_type' => 'debit',
            'is_cash_account' => false,
            'is_bank_account' => true,
            'level' => $bankParentAccount->level + 1,
            'is_parent' => false
        ]);

        return $account;
    }
}
