<?php

namespace App\Classes\Modules\Affiliate\Services;

use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Affiliate\DataTransferObjects\AffiliateObject;
use App\Models\Affiliate;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

class CreatesAffiliate extends AbstractUpdateRecord
{
    /**
     * @param AffiliateObject $object
     * @return \Illuminate\Database\Eloquent\Model
     * @throws \App\Classes\Exceptions\MalformedRequestException
     */
    public function execute(AffiliateObject $object)
    {
        $code = $object->getCode();
        
        // Auto-generate code if not provided
        if (empty($code)) {
            $code = $this->generateUniqueCode();
        } else {
            // Uppercase the code for consistency
            $code = strtoupper($code);
        }

        $model = new Affiliate();
        $model->code = strtoupper($code);
        $model->campaign_name = $object->getCampaignName();
        $model->campaign_description = $object->getCampaignDescription();
        $model->is_active = $object->getIsActive();
        $model->created_by = Auth::id();
        $model->clicks_count = 0;
        $model->registrations_count = 0;
        $model->orders_count = 0;

        return $this->handler($model);
    }

    /**
     * Generate a unique affiliate code
     * 
     * @return string
     */
    private function generateUniqueCode(): string
    {
        $maxAttempts = 10;
        $attempts = 0;
        
        do {
            // Increased from 12 to 16 characters for better uniqueness
            $code = Str::random(16);
            $attempts++;
            
            if ($attempts >= $maxAttempts) {
                // Fallback to UUID if we can't generate unique code
                $code = strtoupper(Str::substr(str_replace('-', '', Str::uuid()), 0, 16));
                break;
            }
        } while (Affiliate::where('code', $code)->exists());

        return $code;
    }
}

