<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ActivityLog;
use App\Models\Site;
use App\Models\Transaction;
use App\Services\PayGarantiService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PayGarantiDepositCallbackController extends Controller
{
    public function store(Request $request, PayGarantiService $service)
    {
        if (!$this->isIpAllowed($request->ip())) {
            return response()->json([
                'state' => false,
                'message' => 'IP not allowed.',
            ], 403);
        }

        $data = $request->validate([
            'sid' => 'required|string|max:255',
            'key' => 'required|string|max:255',
            'amount' => 'required',
            'currency' => 'required|string|max:10',
            'transaction_id' => 'required|string|max:255',
            'status' => 'required|integer',
            'trx' => 'required|string|max:255',
            'hash' => 'required|string',
        ]);

        $site = Site::where('sid', $data['sid'])
            ->where('api_key', $data['key'])
            ->first();

        if (!$site) {
            return response()->json([
                'state' => false,
                'message' => 'Invalid site credentials.',
            ], 401);
        }

        if (!$site->is_active) {
            return response()->json([
                'state' => false,
                'message' => 'Site is inactive.',
            ], 403);
        }

        $secret = (string) ($site->secret_key ?? '');
        if ($secret === '') {
            return response()->json([
                'state' => false,
                'message' => 'Site secret is missing.',
            ], 400);
        }

        if (!$service->verifyDepositHash($data, $secret)) {
            return response()->json([
                'state' => false,
                'message' => 'Invalid hash.',
            ], 401);
        }

        $status = ((int) $data['status'] === 1) ? 'approved' : 'failed';

        DB::beginTransaction();
        try {
            $transaction = Transaction::deposits()
                ->where('transaction_id', $data['trx'])
                ->orWhere('merchant_trx_id', $data['trx'])
                ->first();

            if ($transaction) {
                $transaction->update([
                    'status' => $status,
                    'amount' => (float) $data['amount'],
                    'currency' => $data['currency'],
                    'external_transaction_id' => $data['transaction_id'],
                    'merchant_trx_id' => $data['trx'],
                    'sid' => $data['sid'],
                    'api_key' => $data['key'],
                    'hash' => $data['hash'],
                    'callback_response' => $data,
                    'approved_at' => $status === 'approved' ? now() : null,
                    'site_id' => $site ? $site->id : $transaction->site_id,
                ]);
            } else {
                $transactionId = Transaction::generateUniqueTransactionId('D');

                $transaction = Transaction::create([
                    'transaction_id' => $transactionId,
                    'external_transaction_id' => $data['transaction_id'],
                    'merchant_trx_id' => $data['trx'],
                    'type' => 'deposit',
                    'source' => 'api',
                    'status' => $status,
                    'amount' => (float) $data['amount'],
                    'currency' => $data['currency'],
                    'customer_name' => 'PayGaranti',
                    'sid' => $data['sid'],
                    'api_key' => $data['key'],
                    'hash' => $data['hash'],
                    'callback_response' => $data,
                    'ip_address' => $request->ip(),
                    'approved_at' => $status === 'approved' ? now() : null,
                    'created_by_name' => 'API',
                    'site_id' => $site ? $site->id : null,
                ]);
            }

            ActivityLog::log(
                'deposit_callback',
                'deposits',
                "PayGaranti deposit callback: {$transaction->transaction_id}",
                null,
                $transaction->toArray()
            );

            DB::commit();

            return response()->json([
                'state' => 200,
                'message' => 'işlem başarılı',
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'state' => false,
                'message' => $e->getMessage(),
            ], 500);
        }
    }

    private function isIpAllowed(?string $ip): bool
    {
        $whitelist = trim((string) setting('api_ip_whitelist'));
        if ($whitelist === '') {
            return true;
        }

        $allowed = preg_split('/\s+/', $whitelist);
        return $ip && in_array($ip, $allowed, true);
    }
}
