<?php

namespace App\Classes\Modules\Affiliate\Services;

use App\Models\Affiliate;
use Illuminate\Support\Facades\Cookie;

class TracksAffiliateClick
{
    const COOKIE_NAME = 'affiliate_tracking_code';
    const COOKIE_EXPIRY_DAYS = 30; // Default, can be overridden by settings

    /**
     * Track a click on an affiliate link
     * 
     * @param string $code
     * @return Affiliate|null
     */
    public function execute(string $code): ?Affiliate
    {
        // Validate code format and length
        if (!$this->isValidCode($code)) {
            return null;
        }

        $affiliate = Affiliate::where('code', $code)
            ->where('is_active', true)
            ->first();

        if (!$affiliate) {
            return null;
        }

        // Increment clicks count
        $affiliate->increment('clicks_count');

        // Get binding days from settings
        $bindingDays = $this->getBindingDays();

        // Store in cookie for later use during registration
        // Set secure cookie flags for security
        Cookie::queue(
            cookie(
                self::COOKIE_NAME,
                $code,
                $bindingDays * 24 * 60, // Convert days to minutes
                '/', // path
                null, // domain (null = current domain)
                config('session.secure', false), // secure (HTTPS only)
                true, // httpOnly (prevent JavaScript access)
                false, // raw
                config('session.same_site', 'lax') // sameSite
            )
        );

        return $affiliate;
    }

    /**
     * Validate affiliate code format
     * 
     * @param string $code
     * @return bool
     */
    private function isValidCode(string $code): bool
    {
        // Check length (max 255 chars based on database schema)
        if (strlen($code) > 255 || strlen($code) < 1) {
            return false;
        }

        // Only allow alphanumeric characters, hyphens, and underscores
        return (bool) preg_match('/^[a-zA-Z0-9_-]+$/', $code);
    }

    /**
     * Get code binding days from settings
     * 
     * @return int
     */
    private function getBindingDays(): int
    {
        $settingsService = new GetsAffiliateSettings();
        $settings = $settingsService->execute();
        return $settings['code_binding_days'] ?? self::COOKIE_EXPIRY_DAYS;
    }
}

