<?php

namespace App\Http\Controllers\Backoffice;

use App\Http\Controllers\Controller;
use App\Models\ActivityLog;
use App\Models\CryptoAccount;
use App\Models\CryptoCoin;
use App\Models\FinanceGroup;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;

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

        if ($request->filled('finance_group_id')) {
            $query->where('finance_group_id', (int) $request->finance_group_id);
        }

        if ($request->filled('crypto_coin_id')) {
            $query->where('crypto_coin_id', (int) $request->crypto_coin_id);
        }

        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 (CryptoAccount $account) {
                    return [
                        'id' => $account->id,
                        'finance_group_id' => $account->finance_group_id,
                        'finance_group_name' => $account->financeGroup ? $account->financeGroup->name : '-',
                        'finance_group_color' => $account->financeGroup ? $account->financeGroup->badge_color : null,
                        'crypto_coin_id' => $account->crypto_coin_id,
                        'coin_name' => $account->coin ? $account->coin->name : '-',
                        'coin_icon' => $this->resolveCoinIconUrl($account->coin ? $account->coin->icon : null),
                        'address' => $account->address,
                        'is_active' => (bool) $account->is_active,
                        'created_by_name' => $account->creator ? $account->creator->full_name : '-',
                        'created_at' => $account->created_at->format('d.m.Y H:i'),
                    ];
                }),
            ]);
        }

        $financeGroups = FinanceGroup::orderBy('name')->get(['id', 'name', 'badge_color', 'min_amount', 'max_amount']);
        $coins = CryptoCoin::orderBy('name')->get(['id', 'name', 'icon']);

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

    public function store(Request $request)
    {
        $validated = $request->validate([
            'finance_group_id' => ['required', 'exists:finance_groups,id'],
            'crypto_coin_id' => ['required', 'exists:crypto_coins,id'],
            'address' => [
                'required',
                'string',
                'max:255',
                Rule::unique('crypto_accounts')->where(function ($query) use ($request) {
                    return $query->where('crypto_coin_id', (int) $request->crypto_coin_id);
                }),
            ],
            'is_active' => ['nullable', 'boolean'],
        ], [
            'finance_group_id.required' => 'Finans grubu secilmelidir.',
            'finance_group_id.exists' => 'Gecersiz finans grubu.',
            'crypto_coin_id.required' => 'Coin secilmelidir.',
            'crypto_coin_id.exists' => 'Gecersiz coin.',
            'address.required' => 'Adres alani zorunludur.',
            'address.unique' => 'Bu coin icin bu adres zaten kayitli.',
        ]);

        DB::beginTransaction();
        try {
            $account = CryptoAccount::create([
                'finance_group_id' => (int) $validated['finance_group_id'],
                'crypto_coin_id' => (int) $validated['crypto_coin_id'],
                'address' => trim((string) $validated['address']),
                'is_active' => $request->has('is_active') ? $request->boolean('is_active') : true,
                'created_by' => auth()->id(),
            ]);

            ActivityLog::log(
                'create_crypto_account',
                'crypto_accounts',
                "Kripto hesabi olusturuldu: {$account->id}",
                null,
                $account->toArray()
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Kripto hesabi basariyla eklendi.',
                'account' => $account,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'Kripto hesabi eklenirken hata olustu: ' . $e->getMessage(),
            ], 500);
        }
    }

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

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

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

        $validated = $request->validate([
            'finance_group_id' => ['required', 'exists:finance_groups,id'],
            'crypto_coin_id' => ['required', 'exists:crypto_coins,id'],
            'address' => [
                'required',
                'string',
                'max:255',
                Rule::unique('crypto_accounts')
                    ->ignore($account->id)
                    ->where(function ($query) use ($request) {
                        return $query->where('crypto_coin_id', (int) $request->crypto_coin_id);
                    }),
            ],
            'is_active' => ['nullable', 'boolean'],
        ], [
            'finance_group_id.required' => 'Finans grubu secilmelidir.',
            'finance_group_id.exists' => 'Gecersiz finans grubu.',
            'crypto_coin_id.required' => 'Coin secilmelidir.',
            'crypto_coin_id.exists' => 'Gecersiz coin.',
            'address.required' => 'Adres alani zorunludur.',
            'address.unique' => 'Bu coin icin bu adres zaten kayitli.',
        ]);

        DB::beginTransaction();
        try {
            $oldData = $account->toArray();

            $account->update([
                'finance_group_id' => (int) $validated['finance_group_id'],
                'crypto_coin_id' => (int) $validated['crypto_coin_id'],
                'address' => trim((string) $validated['address']),
                'is_active' => $request->boolean('is_active'),
            ]);

            ActivityLog::log(
                'update_crypto_account',
                'crypto_accounts',
                "Kripto hesabi guncellendi: {$account->id}",
                $oldData,
                $account->toArray()
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Kripto hesabi basariyla guncellendi.',
                'account' => $account,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'Kripto hesabi guncellenirken hata olustu: ' . $e->getMessage(),
            ], 500);
        }
    }

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

        DB::beginTransaction();
        try {
            $oldData = $account->toArray();
            $account->delete();

            ActivityLog::log(
                'delete_crypto_account',
                'crypto_accounts',
                "Kripto hesabi silindi: {$id}",
                $oldData,
                null
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Kripto hesabi basariyla silindi.',
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'Kripto hesabi silinirken hata olustu: ' . $e->getMessage(),
            ], 500);
        }
    }

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

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

            ActivityLog::log(
                'toggle_crypto_account_status',
                'crypto_accounts',
                "Kripto hesabi durumu degistirildi: {$account->id}",
                ['is_active' => $oldStatus],
                ['is_active' => (bool) $account->is_active]
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => $account->is_active ? 'Hesap aktif edildi.' : 'Hesap pasif edildi.',
                'is_active' => (bool) $account->is_active,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'Durum guncellenirken hata olustu: ' . $e->getMessage(),
            ], 500);
        }
    }

    protected function resolveCoinIconUrl(?string $icon): ?string
    {
        $icon = trim((string) $icon);
        if ($icon === '') {
            return null;
        }

        if (preg_match('/^https?:\/\//i', $icon)) {
            return $icon;
        }

        if (str_starts_with($icon, '/')) {
            return $icon;
        }

        // If only filename is stored (e.g. "btc.png"), default to /coins folder.
        if (!str_contains($icon, '/')) {
            return '/coins/' . ltrim($icon, '/');
        }

        return '/' . ltrim($icon, '/');
    }
}
