<?php

namespace MtcPharmacy\ReferAFriend\Classes;

use MtcPharmacy\ReferAFriend\Models\Referral;
use MtcPharmacy\ReferAFriend\Models\ReferralActivityLog;
use Mtc\Modules\Members\Models\Member;

class ReferralFraudChecker
{
    /**
     * Run all fraud checks and return an array of flag strings.
     */
    public function checkAll(Referral $referral, Member $member): array
    {
        $flags = [];

        if ($this->checkSelfReferral($referral, $member)) {
            $flags[] = 'self_referral_suspected';
        }

        if ($this->checkIpVelocity($member)) {
            $flags[] = 'ip_velocity_exceeded';
        }

        if ($this->checkCookieReuse($referral)) {
            $flags[] = 'cookie_reuse_detected';
        }

        return $flags;
    }

    /**
     * Check if the referrer's most recent activity IP matches the new member's IP.
     */
    public function checkSelfReferral(Referral $referral, Member $member): bool
    {
        $referrer = Member::find($referral->referrer_id);
        if (!$referrer) {
            return false;
        }

        $currentIp = request()->ip();
        if (!$currentIp) {
            return false;
        }

        // Load the model so the OptionalEncrypted cast decrypts ip_address.
        $referrerLog = ReferralActivityLog::where('member_id', $referrer->id)
            ->whereNotNull('ip_address')
            ->orderBy('created_at', 'desc')
            ->first();

        if (!$referrerLog || !$referrerLog->ip_address) {
            return false;
        }

        return $referrerLog->ip_address === $currentIp;
    }

    /**
     * Check if too many signups have occurred from the same IP within a day.
     */
    public function checkIpVelocity(Member $member): bool
    {
        $currentIpHash = Referral::hashIp(request()->ip());
        $maxPerDay = config('referrals.fraud.max_signups_per_ip_per_day', 5);

        if ($currentIpHash === null) {
            return false;
        }

        $recentCount = Referral::where('referee_ip_hash', $currentIpHash)
            ->where('created_at', '>=', now()->subDay())
            ->count();

        return $recentCount >= $maxPerDay;
    }

    /**
     * Check if the same referral cookie has been used across multiple signups.
     */
    public function checkCookieReuse(Referral $referral): bool
    {
        $cookie = request()->cookie(config('referrals.fraud.device_cookie_name'));
        if (!$cookie) {
            return false;
        }

        // Check if this cookie value appears on other completed referrals
        $reuseCount = Referral::where('referee_cookie', $cookie)
            ->where('id', '!=', $referral->id)
            ->whereIn('status', ['signed_up', 'shipped', 'rewarded'])
            ->count();

        return $reuseCount > 0;
    }
}
