<?php

namespace App\Http\Controllers\Backoffice;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\BankAccount;
use App\Models\FinanceGroup;
use App\Models\FinanceUser;
use App\Models\ActivityLog;
use Illuminate\Support\Facades\DB;

class BankAccountController extends Controller
{
    public function index(Request $request)
    {
        $query = BankAccount::with(['financeGroup', 'creator']);

        // Filter by finance group if provided
        if ($request->filled('finance_group_id')) {
            $query->where('finance_group_id', $request->finance_group_id);
        }

        // Filter by status if provided
        if ($request->filled('is_active')) {
            $query->where('is_active', $request->is_active === '1');
        }

        if ($request->ajax()) {
            $accounts = $query->orderBy('created_at', 'desc')->get();

            return response()->json([
                'data' => $accounts->map(function ($account) {
                    return [
                        'id' => $account->id,
                        'account_name' => $account->account_name,
                        'bank_name' => $account->bank_name,
                        'account_holder' => $account->account_holder,
                        'iban' => $account->iban,
                        'account_number' => $account->account_number,
                        'branch_name' => $account->branch_name,
                        'branch_code' => $account->branch_code,
                        'finance_group_name' => $account->financeGroup ? $account->financeGroup->name : '-',
                        'finance_group_color' => $account->financeGroup ? $account->financeGroup->badge_color : null,
                        'finance_group_range' => $account->financeGroup ?
                            number_format($account->financeGroup->min_amount, 0) . '-' .
                            number_format($account->financeGroup->max_amount, 0) . ' ₺' : '-',
                        'is_active' => $account->is_active,
                        'daily_limit' => $account->daily_limit ? number_format($account->daily_limit, 2) : null,
                        'created_by_name' => $account->creator ? $account->creator->full_name : '-',
                        'created_at' => $account->created_at->format('d.m.Y H:i'),
                    ];
                })
            ]);
        }

        // Get finance groups for filter
        $financeGroups = FinanceGroup::active()->get();

        return view('backoffice.bank-accounts.index', compact('financeGroups'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'finance_user_id' => 'nullable|exists:finance_users,id',
            'finance_group_id' => 'required|exists:finance_groups,id',
            'account_name' => 'required|string|max:255',
            'bank_name' => 'required|string|max:255',
            'account_holder' => 'required|string|max:255',
            'iban' => 'required|string|max:34',
            'account_number' => 'nullable|string|max:50',
            'branch_name' => 'nullable|string|max:255',
            'branch_code' => 'nullable|string|max:50',
            'daily_limit' => 'nullable|numeric|min:0',
            'is_active' => 'boolean',
        ], [
            'finance_group_id.required' => 'Finans grubu seçilmelidir.',
            'finance_group_id.exists' => 'Geçersiz finans grubu.',
            'account_name.required' => 'Hesap adı gereklidir.',
            'bank_name.required' => 'Banka adı gereklidir.',
            'account_holder.required' => 'Hesap sahibi gereklidir.',
            'iban.required' => 'IBAN gereklidir.',
        ]);

        DB::beginTransaction();
        try {
            $financeUserId = $request->finance_user_id;

            if ($financeUserId) {
                $belongsToGroup = FinanceUser::where('id', $financeUserId)
                    ->where('finance_group_id', $request->finance_group_id)
                    ->exists();

                if (!$belongsToGroup) {
                    return response()->json([
                        'success' => false,
                        'message' => 'SeÃ§ilen finans kullanÄ±cÄ±sÄ± bu finans grubuna ait deÄŸil.',
                    ], 422);
                }
            } else {
                $financeUserId = FinanceUser::where('finance_group_id', $request->finance_group_id)
                    ->where('is_active', true)
                    ->orderBy('id')
                    ->value('id');

                if (!$financeUserId) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Bu finans grubu iÃ§in aktif finans kullanÄ±cÄ±sÄ± bulunamadÄ±.',
                    ], 422);
                }
            }

            $financeGroup = FinanceGroup::findOrFail($request->finance_group_id);

            $account = BankAccount::create([
                'finance_user_id' => $financeUserId,
                'finance_group_id' => $request->finance_group_id,
                'account_name' => $request->account_name,
                'bank_name' => $request->bank_name,
                'account_holder' => $request->account_holder,
                'account_holder_name' => $request->account_holder,
                'iban' => $request->iban,
                'account_number' => $request->account_number,
                'branch_name' => $request->branch_name,
                'branch_code' => $request->branch_code,
                'daily_limit' => $request->daily_limit,
                'min_amount' => $financeGroup->min_amount,
                'max_amount' => $financeGroup->max_amount,
                'is_active' => $request->boolean('is_active', true),
                'created_by' => auth()->id(),
            ]);

            ActivityLog::log(
                'create_bank_account',
                'bank_accounts',
                "Banka hesabı oluşturuldu: {$account->account_name}",
                null,
                $account->toArray()
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Banka hesabı başarıyla oluşturuldu.',
                'account' => $account,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Banka hesabı oluşturulurken bir hata oluştu: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function show($id)
    {
        $account = BankAccount::with(['financeGroup', 'creator'])->findOrFail($id);

        return response()->json([
            'success' => true,
            'account' => $account,
        ]);
    }

    public function update(Request $request, $id)
    {
        $account = BankAccount::findOrFail($id);

        $request->validate([
            'finance_user_id' => 'nullable|exists:finance_users,id',
            'finance_group_id' => 'required|exists:finance_groups,id',
            'account_name' => 'required|string|max:255',
            'bank_name' => 'required|string|max:255',
            'account_holder' => 'required|string|max:255',
            'iban' => 'required|string|max:34',
            'account_number' => 'nullable|string|max:50',
            'branch_name' => 'nullable|string|max:255',
            'branch_code' => 'nullable|string|max:50',
            'daily_limit' => 'nullable|numeric|min:0',
            'is_active' => 'boolean',
        ], [
            'finance_group_id.required' => 'Finans grubu seçilmelidir.',
            'account_name.required' => 'Hesap adı gereklidir.',
            'bank_name.required' => 'Banka adı gereklidir.',
            'account_holder.required' => 'Hesap sahibi gereklidir.',
            'iban.required' => 'IBAN gereklidir.',
        ]);

        DB::beginTransaction();
        try {
            $oldData = $account->toArray();
            $financeGroup = FinanceGroup::findOrFail($request->finance_group_id);
            $financeUserId = $account->finance_user_id;

            if ($request->filled('finance_user_id')) {
                $belongsToGroup = FinanceUser::where('id', $request->finance_user_id)
                    ->where('finance_group_id', $request->finance_group_id)
                    ->exists();

                if (!$belongsToGroup) {
                    return response()->json([
                        'success' => false,
                        'message' => 'SeÃ§ilen finans kullanÄ±cÄ±sÄ± bu finans grubuna ait deÄŸil.',
                    ], 422);
                }

                $financeUserId = $request->finance_user_id;
            } elseif ((int) $request->finance_group_id !== (int) $account->finance_group_id) {
                $financeUserId = FinanceUser::where('finance_group_id', $request->finance_group_id)
                    ->where('is_active', true)
                    ->orderBy('id')
                    ->value('id');

                if (!$financeUserId) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Bu finans grubu iÃ§in aktif finans kullanÄ±cÄ±sÄ± bulunamadÄ±.',
                    ], 422);
                }
            }

            $account->update([
                'finance_user_id' => $financeUserId,
                'finance_group_id' => $request->finance_group_id,
                'account_name' => $request->account_name,
                'bank_name' => $request->bank_name,
                'account_holder' => $request->account_holder,
                'account_holder_name' => $request->account_holder,
                'iban' => $request->iban,
                'account_number' => $request->account_number,
                'branch_name' => $request->branch_name,
                'branch_code' => $request->branch_code,
                'daily_limit' => $request->daily_limit,
                'min_amount' => $financeGroup->min_amount,
                'max_amount' => $financeGroup->max_amount,
                'is_active' => $request->boolean('is_active'),
            ]);

            ActivityLog::log(
                'update_bank_account',
                'bank_accounts',
                "Banka hesabı güncellendi: {$account->account_name}",
                $oldData,
                $account->toArray()
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Banka hesabı başarıyla güncellendi.',
                'account' => $account,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Banka hesabı güncellenirken bir hata oluştu: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function destroy($id)
    {
        $account = BankAccount::findOrFail($id);

        // Check if account is used in any transactions
        if ($account->transactions()->count() > 0) {
            return response()->json([
                'success' => false,
                'message' => 'Bu hesap ile ilişkili işlemler var. Hesap silinemez.',
            ], 400);
        }

        DB::beginTransaction();
        try {
            $accountName = $account->account_name;

            $account->delete();

            ActivityLog::log(
                'delete_bank_account',
                'bank_accounts',
                "Banka hesabı silindi: {$accountName}",
                $account->toArray(),
                null
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Banka hesabı başarıyla silindi.',
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Banka hesabı silinirken bir hata oluştu: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function toggleStatus($id)
    {
        $account = BankAccount::findOrFail($id);

        DB::beginTransaction();
        try {
            $oldStatus = $account->is_active;
            $account->update(['is_active' => !$oldStatus]);

            ActivityLog::log(
                'toggle_bank_account_status',
                'bank_accounts',
                "Banka hesabı durumu değiştirildi: {$account->account_name}",
                ['is_active' => $oldStatus],
                ['is_active' => $account->is_active]
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => $account->is_active ? 'Hesap aktif edildi.' : 'Hesap pasif edildi.',
                'is_active' => $account->is_active,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Durum değiştirilirken bir hata oluştu: ' . $e->getMessage(),
            ], 500);
        }
    }
}
