<?php

namespace Modules\AppManager\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\AppManager\Entities\License;
use Modules\AppManager\Entities\ManagedScript;
use Illuminate\Validation\Rule;
use Illuminate\Support\Str;

class LicenseController extends Controller
{
    public function index(Request $request)
    {
        $query = License::with('managedScript')->orderBy('created_at', 'desc');

        if ($request->filled('search')) {
            $searchTerm = $request->input('search');
            $query->where(function ($q) use ($searchTerm) {
                $q->where('license_key', 'like', "%{$searchTerm}%")
                  ->orWhere('customer_email', 'like', "%{$searchTerm}%")
                  ->orWhere('purchase_code', 'like', "%{$searchTerm}%")
                  ->orWhereHas('managedScript', function ($sq) use ($searchTerm) {
                      $sq->where('name', 'like', "%{$searchTerm}%");
                  });
            });
        }
        if ($request->filled('managed_script_id')) {
            $query->where('managed_script_id', $request->input('managed_script_id'));
        }
        if ($request->filled('status') && $request->status !== 'all') {
            $query->where('status', $request->input('status'));
        }

        $licenses = $query->paginate(15)->withQueryString();
        $scripts = ManagedScript::orderBy('name')->pluck('name', 'id');
        $statuses = ['pending' => 'Pending', 'active' => 'Active', 'suspended' => 'Suspended', 'expired' => 'Expired', 'revoked' => 'Revoked'];

        return view('appmanager::admin.licenses.index', compact('licenses', 'scripts', 'statuses'));
    }

    public function create()
    {
        $scripts = ManagedScript::orderBy('name')->pluck('name', 'id');
        $types = ['internal' => 'Internal', 'codecanyon' => 'CodeCanyon', 'subscription' => 'Subscription'];
        $statuses = ['pending' => 'Pending', 'active' => 'Active', 'suspended' => 'Suspended', 'expired' => 'Expired', 'revoked' => 'Revoked'];
        return view('appmanager::admin.licenses.create', compact('scripts', 'types', 'statuses'));
    }

    public function store(Request $request)
    {
        $rules = [
            'managed_script_id' => 'required|exists:am_managed_scripts,id',
            'auto_generate_key' => 'nullable|boolean',
            'type' => 'required|in:internal,codecanyon,subscription',
            'customer_email' => 'nullable|email|max:255',
            'customer_name' => 'nullable|string|max:255',
            'purchase_code' => [
                'nullable', 'string', 'max:255',
                Rule::unique('am_licenses')->where(function ($query) use ($request) {
                    return $query->where('type', 'codecanyon'); // Ensures uniqueness among CodeCanyon type licenses if purchase_code is provided
                }),
            ],
            'activation_limit' => 'required|integer|min:0', // 0 for unlimited
            'status' => 'required|in:pending,active,suspended,expired,revoked',
            'expires_at' => 'nullable|date',
            'does_not_expire' => 'nullable|boolean',
            'supported_until' => 'nullable|date',
            'metadata' => 'nullable|json',
            'notes' => 'nullable|string',
        ];
        
        // Conditionally add rules for license_key
        if ($request->boolean('auto_generate_key')) {
            // If auto-generating, license_key is optional from input. If provided, validate it.
            $rules['license_key'] = [
                'nullable',
                'string',
                'max:255',
                Rule::unique('am_licenses', 'license_key'), // Corrected: unique rule on nullable field handles "unique if filled"
            ];
        } else {
            // If not auto-generating, license_key is required and must be unique.
            $rules['license_key'] = [
                'required',
                'string',
                'max:255',
                Rule::unique('am_licenses', 'license_key'),
            ];
        }
        $request->validate($rules);

        $data = $request->except(['auto_generate_key', 'does_not_expire']);

        if ($request->boolean('auto_generate_key') && empty($request->input('license_key'))) {
            $data['auto_generate_key_flag'] = true; // Model will handle generation
        }

        if ($request->boolean('does_not_expire')) {
            $data['expires_at'] = null;
        }

        if ($data['type'] !== 'codecanyon') {
            $data['purchase_code'] = null; // Ensure purchase code is null if not CodeCanyon type
        }


        License::create($data);

        return redirect()->route('admin.appmanager.licenses.index')
                         ->with('success', 'License created successfully.');
    }

        public function show(License $license)
        {
            $license->load(['managedScript', 'activationLogs' => function ($query) {
                $query->orderBy('activated_at', 'desc');
            }]);
            return view('appmanager::admin.licenses.show', compact('license'));
        }
    public function edit(License $license)
    {
        $scripts = ManagedScript::orderBy('name')->pluck('name', 'id');
        $types = ['internal' => 'Internal', 'codecanyon' => 'CodeCanyon', 'subscription' => 'Subscription'];
        $statuses = ['pending' => 'Pending', 'active' => 'Active', 'suspended' => 'Suspended', 'expired' => 'Expired', 'revoked' => 'Revoked'];
        return view('appmanager::admin.licenses.edit', compact('license', 'scripts', 'types', 'statuses'));
    }

    public function update(Request $request, License $license)
    {
        $rules = [
            'managed_script_id' => 'required|exists:am_managed_scripts,id',
            'type' => 'required|in:internal,codecanyon,subscription',
            'customer_email' => 'nullable|email|max:255',
            'customer_name' => 'nullable|string|max:255',
            'purchase_code' => [
                'nullable', 'string', 'max:255',
                Rule::unique('am_licenses')->where(function ($query) use ($request) {
                    return $query->where('type', 'codecanyon');
                })->ignore($license->id),
            ],
            'activation_limit' => 'required|integer|min:0',
            'status' => 'required|in:pending,active,suspended,expired,revoked',
            'expires_at' => 'nullable|date',
            'does_not_expire' => 'nullable|boolean',
            'supported_until' => 'nullable|date',
            'metadata' => 'nullable|json',
            'notes' => 'nullable|string',
        ];
        
        // Conditionally add rules for license_key for update
        if ($request->boolean('auto_generate_key')) {
            // If user checks auto_generate_key on update (perhaps after clearing the key)
            $rules['license_key'] = [
                'nullable',
                'string',
                'max:255',
                Rule::unique('am_licenses', 'license_key')->ignore($license->id), // Corrected: unique rule on nullable field handles "unique if filled"
            ];
        } else {
            $rules['license_key'] = [
                'required',
                'string',
                'max:255',
                Rule::unique('am_licenses', 'license_key')->ignore($license->id),
            ];
        }
        $request->validate($rules);

        $data = $request->except(['auto_generate_key', 'does_not_expire']);

        if ($request->boolean('does_not_expire')) {
            $data['expires_at'] = null;
        }

        // If user cleared the key and wants to auto-generate a new one on update
        if ($request->boolean('auto_generate_key') && empty($request->input('license_key'))) {
            $data['auto_generate_key_flag'] = true; // Model's 'updating' hook will handle generation
        }

        if ($data['type'] !== 'codecanyon') {
            $data['purchase_code'] = null;
        }

        $license->update($data);

        return redirect()->route('admin.appmanager.licenses.index')
                         ->with('success', 'License updated successfully.');
    }

    public function destroy(License $license)
    {
        $license->delete();
        return redirect()->route('admin.appmanager.licenses.index')
                         ->with('success', 'License deleted successfully.');
    }
}
