<?php

namespace App\Services;

use App\Models\License;
use App\Models\Product;
use App\Models\User;
use App\Services\EnvatoService;
use Illuminate\Support\Facades\Log;

class PurchaseCodeService
{
    protected $envatoService;

    public function __construct(EnvatoService $envatoService)
    {
        $this->envatoService = $envatoService;
    }

    /**
     * Clean and validate purchase code format
     */
    public function cleanPurchaseCode(string $purchaseCode): string
    {
        // Remove all whitespace and dashes, convert to uppercase for consistency
        return strtoupper(str_replace([' ', '-'], '', trim($purchaseCode)));
    }

    /**
     * Validate purchase code format (basic validation)
     */
    public function isValidFormat(string $purchaseCode): bool
    {
        $cleaned = $this->cleanPurchaseCode($purchaseCode);
        
        // Basic format validation - should be alphanumeric and reasonable length
        return preg_match('/^[A-Z0-9]{8,50}$/', $cleaned);
    }

    /**
     * Verify purchase code against our database first, then Envato
     */
    public function verifyPurchaseCode(string $purchaseCode, ?int $productId = null, ?User $user = null): array
    {
        $cleanedCode = $this->cleanPurchaseCode($purchaseCode);
        
        // Validate format first
        if (!$this->isValidFormat($cleanedCode)) {
            return [
                'success' => false,
                'error' => 'Invalid purchase code format',
                'source' => null
            ];
        }

        // 1. Check our database first
        $dbResult = $this->verifyAgainstDatabase($cleanedCode, $productId);
        if ($dbResult['success']) {
            return $dbResult;
        }

        // 2. Check Envato if not found in our database
        $envatoResult = $this->verifyAgainstEnvato($cleanedCode, $productId, $user);
        if ($envatoResult['success']) {
            return $envatoResult;
        }

        return [
            'success' => false,
            'error' => 'Invalid purchase code',
            'source' => null
        ];
    }    /**
     * Verify against our database
     */
    protected function verifyAgainstDatabase(string $purchaseCode, ?int $productId = null): array
    {
        $query = License::where('status', 'active')
            ->where(function ($q) use ($purchaseCode) {
                $q->where('purchase_code', $purchaseCode)
                  ->orWhere('license_key', $purchaseCode);
            })
            ->where(function ($q) {
                $q->whereNull('license_expires_at')
                  ->orWhere('license_expires_at', '>', now());
            });

        // If product ID is specified, ensure the license belongs to that product
        if ($productId) {
            $query->where('product_id', $productId);
        }

        $license = $query->first();

        if ($license) {
            return [
                'success' => true,
                'license' => $license,
                'source' => 'database',
                'product_id' => $license->product_id
            ];
        }

        return [
            'success' => false,
            'error' => 'Purchase code not found in our database',
            'source' => 'database'
        ];
    }

    /**
     * Verify raw code directly against database (no cleaning applied)
     */
    public function verifyRawCode(string $rawCode, ?int $productId = null): array
    {
        // First, find the license by code (regardless of status or expiration)
        $license = License::where(function ($q) use ($rawCode) {
            $q->where('license_key', $rawCode)
              ->orWhere('purchase_code', $rawCode);
        })->first();

        // If license doesn't exist at all
        if (!$license) {
            return [
                'success' => false,
                'error' => 'invalid_code',
                'message' => trans('license_status.license_code_invalid'),
                'source' => 'database_raw'
            ];
        }

        // Check if license belongs to the correct product
        if ($productId && $license->product_id !== $productId) {
            return [
                'success' => false,
                'error' => 'wrong_product',
                'message' => trans('license_status.license_code_not_for_product'),
                'source' => 'database_raw',
                'license_product_id' => $license->product_id
            ];
        }

        // Check if license is active
        if ($license->status !== 'active') {
            $statusMessages = [
                'inactive' => trans('license_status.license_inactive'),
                'suspended' => trans('license_status.license_suspended'),
                'expired' => trans('license_status.license_expired')
            ];

            $message = $statusMessages[$license->status] ?? trans('license_status.license_inactive');

            return [
                'success' => false,
                'error' => 'license_status',
                'message' => $message,
                'license_status' => $license->status,
                'source' => 'database_raw'
            ];
        }

        // Check if license is expired
        if ($license->license_expires_at && now()->greaterThan($license->license_expires_at)) {
            return [
                'success' => false,
                'error' => 'license_expired',
                'message' => trans('license_status.license_expired'),
                'expires_at' => $license->license_expires_at,
                'source' => 'database_raw'
            ];
        }

        // All checks passed
        return [
            'success' => true,
            'license' => $license,
            'source' => 'database_raw',
            'product_id' => $license->product_id
        ];
    }
    protected function verifyAgainstEnvato(string $purchaseCode, ?int $productId = null, ?User $user = null): array
    {
        try {
            $envatoData = $this->envatoService->verifyPurchase($purchaseCode);
            
            if (!$envatoData || !isset($envatoData['item']['id'])) {
                return [
                    'success' => false,
                    'error' => 'Invalid Envato purchase code',
                    'source' => 'envato'
                ];
            }

            $envatoItemId = (string) $envatoData['item']['id'];

            // If product ID is specified, verify it matches the Envato item
            if ($productId) {
                $product = Product::find($productId);
                if (!$product || !$product->envato_item_id || $product->envato_item_id != $envatoItemId) {
                    return [
                        'success' => false,
                        'error' => 'Purchase code does not belong to this product',
                        'source' => 'envato'
                    ];
                }
            }

            // Create license record for authenticated user
            if ($user) {
                $this->createLicenseFromEnvato($user, $purchaseCode, $envatoData, $productId);
            }

            return [
                'success' => true,
                'envato_data' => $envatoData,
                'source' => 'envato',
                'product_id' => $productId
            ];

        } catch (\Exception $e) {
            // Envato API error during purchase verification
            return [
                'success' => false,
                'error' => 'Failed to verify with Envato',
                'source' => 'envato'
            ];
        }
    }

    /**
     * Create license record from Envato data
     */
    protected function createLicenseFromEnvato(User $user, string $purchaseCode, array $envatoData, ?int $productId = null): ?License
    {
        // Check if license already exists
        $existingLicense = $user->licenses()
            ->where('purchase_code', $purchaseCode)
            ->first();

        if ($existingLicense) {
            return $existingLicense;
        }

        // Create new license
        $licenseData = [
            'user_id' => $user->id,
            'purchase_code' => $purchaseCode,
            'license_key' => 'envato_' . $purchaseCode,
            'license_type' => 'regular',
            'status' => 'active',
            'purchase_date' => data_get($envatoData, 'sold_at') ? date('Y-m-d H:i:s', strtotime(data_get($envatoData, 'sold_at'))) : now(),
            'support_expires_at' => data_get($envatoData, 'supported_until') ? date('Y-m-d H:i:s', strtotime(data_get($envatoData, 'supported_until'))) : null,
            'license_expires_at' => null, // Lifetime license
        ];

        // Add product ID if specified
        if ($productId) {
            $licenseData['product_id'] = $productId;
        }

        // Add user ID
        $licenseData['user_id'] = $user->id;

        try {
            return License::create($licenseData);
        } catch (\Exception $e) {
            // Failed to create license from Envato data
            return null;
        }
    }

    /**
     * Check if user has access to specific product via any license
     */
    public function userHasProductAccess(User $user, int $productId): bool
    {
        return $user->licenses()
            ->where('product_id', $productId)
            ->where('status', 'active')
            ->where(function ($q) {
                $q->whereNull('license_expires_at')
                  ->orWhere('license_expires_at', '>', now());
            })
            ->exists();
    }

    /**
     * Check if user has access to KB content via product license
     */
    public function userHasKbAccess(User $user, $kbItem): bool
    {
        // If KB item is not linked to any product, allow access
        if (!$kbItem->product_id) {
            return true;
        }

        // Check if user has license for the linked product
        return $this->userHasProductAccess($user, $kbItem->product_id);
    }

    /**
     * Get accessible KB content for user based on their licenses
     */
    public function getAccessibleKbContent(User $user)
    {
        $userProductIds = $user->licenses()
            ->where('status', 'active')
            ->where(function ($q) {
                $q->whereNull('license_expires_at')
                  ->orWhere('license_expires_at', '>', now());
            })
            ->pluck('product_id')
            ->toArray();

        return [
            'categories' => \App\Models\KbCategory::where(function ($query) use ($userProductIds) {
                $query->whereNull('product_id')
                      ->orWhereIn('product_id', $userProductIds);
            })->where('is_published', true)->get(),
            
            'articles' => \App\Models\KbArticle::where(function ($query) use ($userProductIds) {
                $query->whereNull('product_id')
                      ->orWhereIn('product_id', $userProductIds);
            })->where('is_published', true)->get()
        ];
    }

    /**
     * Check if user has access to KB category via product license
     */
    public function userHasCategoryAccess(User $user, $category): bool
    {
        // If category is not linked to any product, allow access
        if (!$category->product_id) {
            return true;
        }

        // Check if user has license for the linked product
        return $this->userHasProductAccess($user, $category->product_id);
    }

    /**
     * Check if user has access to KB article considering both direct product and category product
     */
    public function userHasArticleAccess(User $user, $article): bool
    {
        // If article has direct product link, check that first
        if ($article->product_id) {
            return $this->userHasProductAccess($user, $article->product_id);
        }

        // If article doesn't have direct product but category does, check category access
        if ($article->category && $article->category->product_id) {
            return $this->userHasCategoryAccess($user, $article->category);
        }

        // No product restrictions
        return true;
    }
}