<?php

namespace App\Http\Controllers\Brand;

use App\Http\Controllers\Controller;
use App\Models\ProviderCredential;
use App\Models\AuditLog;
use App\Services\ProviderCredentialService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

class ProviderCredentialController extends Controller
{
    protected $credentialService;

    public function __construct(ProviderCredentialService $credentialService)
    {
        $this->middleware(['auth', 'role:brand_admin|superadmin']);
        $this->credentialService = $credentialService;
    }

    /**
     * Display a listing of provider credentials.
     */
    public function index(Request $request)
    {
        $brand = auth()->user()->brand;

        if (!$brand) {
            abort(403, 'No brand associated with your account.');
        }

        $credentials = ProviderCredential::where('brand_id', $brand->id)
            ->with(['creator', 'updater'])
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(function ($credential) {
                return [
                    'id' => $credential->id,
                    'provider' => $credential->provider,
                    'provider_display_name' => $credential->provider_display_name,
                    'label' => $credential->label,
                    'use_for_ads' => $credential->use_for_ads,
                    'is_default' => $credential->is_default,
                    'status' => $credential->status,
                    'status_color' => $credential->status_color,
                    'last_tested_at' => $credential->last_tested_at?->diffForHumans(),
                    'token_expires_at' => $credential->token_expires_at?->format('Y-m-d H:i:s'),
                    'is_expiring_soon' => $credential->isExpiringSoon(),
                    'is_expired' => $credential->isExpired(),
                    'last_error' => $credential->last_error,
                    'created_by' => $credential->creator?->name,
                    'updated_by' => $credential->updater?->name,
                    'created_at' => $credential->created_at->format('Y-m-d H:i:s'),
                    'updated_at' => $credential->updated_at->format('Y-m-d H:i:s'),
                    // Masked credentials for display
                    'client_id_masked' => $credential->getMaskedAttribute('client_id'),
                    'access_token_masked' => $credential->getMaskedAttribute('access_token'),
                ];
            });

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'credentials' => $credentials,
            ]);
        }

        return view('brand.integrations.index', compact('credentials'));
    }

    /**
     * Show the form for creating a new provider credential.
     */
    public function create()
    {
        $providers = $this->getAvailableProviders();
        
        return view('brand.integrations.create', compact('providers'));
    }

    /**
     * Store a newly created provider credential.
     */
    public function store(Request $request)
    {
        $brand = auth()->user()->brand;

        if (!$brand) {
            return response()->json([
                'success' => false,
                'message' => 'No brand associated with your account.',
            ], 403);
        }

        $validator = Validator::make($request->all(), [
            'provider' => ['required', 'string', Rule::in($this->getSupportedProviders())],
            'label' => 'nullable|string|max:255',
            'use_for_ads' => 'boolean',
            'is_default' => 'boolean',
            'client_id' => 'nullable|string',
            'client_secret' => 'nullable|string',
            'access_token' => 'required|string',
            'refresh_token' => 'nullable|string',
            'ad_account_id' => 'nullable|string',
            'scopes' => 'nullable|array',
            'redirect_uri' => 'nullable|url',
            'token_expires_at' => 'nullable|date',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors(),
            ], 422);
        }

        $credential = ProviderCredential::create([
            'brand_id' => $brand->id,
            'provider' => $request->provider,
            'label' => $request->label,
            'use_for_ads' => $request->boolean('use_for_ads'),
            'is_default' => $request->boolean('is_default'),
            'client_id' => $request->client_id,
            'client_secret' => $request->client_secret,
            'access_token' => $request->access_token,
            'refresh_token' => $request->refresh_token,
            'ad_account_id' => $request->ad_account_id,
            'scopes' => $request->scopes,
            'redirect_uri' => $request->redirect_uri,
            'token_expires_at' => $request->token_expires_at,
            'status' => 'disconnected',
            'created_by' => auth()->id(),
            'updated_by' => auth()->id(),
        ]);

        // Log audit
        AuditLog::create([
            'actor_id' => auth()->id(),
            'action' => 'provider_credential_created',
            'target_type' => ProviderCredential::class,
            'target_id' => $credential->id,
            'meta' => [
                'provider' => $credential->provider,
                'label' => $credential->label,
                'brand_id' => $brand->id,
            ],
        ]);

        // Test connection if requested
        if ($request->boolean('test_connection', true)) {
            $testResult = $this->credentialService->testConnection($credential);
            
            return response()->json([
                'success' => true,
                'message' => 'Provider credential created successfully',
                'credential' => $credential,
                'test_result' => $testResult,
            ], 201);
        }

        return response()->json([
            'success' => true,
            'message' => 'Provider credential created successfully',
            'credential' => $credential,
        ], 201);
    }

    /**
     * Display the specified provider credential.
     */
    public function show(ProviderCredential $credential)
    {
        $this->authorize('view', $credential);

        return response()->json([
            'success' => true,
            'credential' => [
                'id' => $credential->id,
                'provider' => $credential->provider,
                'provider_display_name' => $credential->provider_display_name,
                'label' => $credential->label,
                'use_for_ads' => $credential->use_for_ads,
                'is_default' => $credential->is_default,
                'status' => $credential->status,
                'status_color' => $credential->status_color,
                'last_tested_at' => $credential->last_tested_at,
                'token_expires_at' => $credential->token_expires_at,
                'is_expiring_soon' => $credential->isExpiringSoon(),
                'is_expired' => $credential->isExpired(),
                'last_error' => $credential->last_error,
                'scopes' => $credential->scopes,
                'redirect_uri' => $credential->redirect_uri,
                // Masked credentials
                'client_id_masked' => $credential->getMaskedAttribute('client_id'),
                'access_token_masked' => $credential->getMaskedAttribute('access_token'),
                'ad_account_id_masked' => $credential->getMaskedAttribute('ad_account_id'),
            ],
        ]);
    }

    /**
     * Update the specified provider credential.
     */
    public function update(Request $request, ProviderCredential $credential)
    {
        $this->authorize('update', $credential);

        $validator = Validator::make($request->all(), [
            'label' => 'nullable|string|max:255',
            'use_for_ads' => 'boolean',
            'is_default' => 'boolean',
            'client_id' => 'nullable|string',
            'client_secret' => 'nullable|string',
            'access_token' => 'nullable|string',
            'refresh_token' => 'nullable|string',
            'ad_account_id' => 'nullable|string',
            'scopes' => 'nullable|array',
            'redirect_uri' => 'nullable|url',
            'token_expires_at' => 'nullable|date',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors(),
            ], 422);
        }

        $oldData = $credential->only(['label', 'use_for_ads', 'is_default']);

        $credential->update(array_merge(
            $request->only([
                'label',
                'use_for_ads',
                'is_default',
                'client_id',
                'client_secret',
                'access_token',
                'refresh_token',
                'ad_account_id',
                'scopes',
                'redirect_uri',
                'token_expires_at',
            ]),
            ['updated_by' => auth()->id()]
        ));

        // Log audit
        AuditLog::create([
            'actor_id' => auth()->id(),
            'action' => 'provider_credential_updated',
            'target_type' => ProviderCredential::class,
            'target_id' => $credential->id,
            'meta' => [
                'provider' => $credential->provider,
                'label' => $credential->label,
                'brand_id' => $credential->brand_id,
                'old_data' => $oldData,
                'new_data' => $request->only(['label', 'use_for_ads', 'is_default']),
            ],
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Provider credential updated successfully',
            'credential' => $credential,
        ]);
    }

    /**
     * Remove the specified provider credential.
     */
    public function destroy(ProviderCredential $credential)
    {
        $this->authorize('delete', $credential);

        // Log audit before deletion
        AuditLog::create([
            'actor_id' => auth()->id(),
            'action' => 'provider_credential_deleted',
            'target_type' => ProviderCredential::class,
            'target_id' => $credential->id,
            'meta' => [
                'provider' => $credential->provider,
                'label' => $credential->label,
                'brand_id' => $credential->brand_id,
            ],
        ]);

        $credential->delete();

        return response()->json([
            'success' => true,
            'message' => 'Provider credential deleted successfully',
        ]);
    }

    /**
     * Test connection for the specified provider credential.
     */
    public function testConnection(ProviderCredential $credential)
    {
        $this->authorize('update', $credential);

        $result = $this->credentialService->testConnection($credential);

        return response()->json($result);
    }

    /**
     * Refresh token for the specified provider credential.
     */
    public function refreshToken(ProviderCredential $credential)
    {
        $this->authorize('update', $credential);

        $success = $this->credentialService->refreshToken($credential);

        if ($success) {
            return response()->json([
                'success' => true,
                'message' => 'Token refreshed successfully',
                'credential' => $credential->fresh(),
            ]);
        }

        return response()->json([
            'success' => false,
            'message' => 'Failed to refresh token. Please reconnect your account.',
        ], 400);
    }

    /**
     * Get available providers with their configuration.
     */
    public function providers()
    {
        $providers = $this->getAvailableProviders();

        return response()->json([
            'success' => true,
            'providers' => $providers,
        ]);
    }

    /**
     * Get list of supported providers.
     */
    protected function getSupportedProviders(): array
    {
        return [
            'youtube',
            'instagram',
            'tiktok',
            'linkedin',
            'twitter',
            'facebook_ads',
            'google_ads',
            'custom',
        ];
    }

    /**
     * Get available providers with their metadata.
     */
    protected function getAvailableProviders(): array
    {
        return [
            [
                'id' => 'youtube',
                'name' => 'YouTube',
                'icon' => 'youtube',
                'color' => 'red',
                'supports_ads' => false,
                'supports_oauth' => true,
                'required_fields' => ['access_token'],
                'optional_fields' => ['client_id', 'client_secret', 'refresh_token'],
                'scopes' => ['https://www.googleapis.com/auth/youtube.readonly'],
                'documentation_url' => '/docs/providers/youtube',
            ],
            [
                'id' => 'instagram',
                'name' => 'Instagram',
                'icon' => 'instagram',
                'color' => 'pink',
                'supports_ads' => false,
                'supports_oauth' => true,
                'required_fields' => ['access_token'],
                'optional_fields' => ['client_id', 'client_secret'],
                'scopes' => ['instagram_basic', 'instagram_content_publish'],
                'documentation_url' => '/docs/providers/instagram',
            ],
            [
                'id' => 'tiktok',
                'name' => 'TikTok',
                'icon' => 'tiktok',
                'color' => 'black',
                'supports_ads' => false,
                'supports_oauth' => true,
                'required_fields' => ['access_token'],
                'optional_fields' => ['client_id', 'client_secret', 'refresh_token'],
                'scopes' => ['user.info.basic', 'video.list'],
                'documentation_url' => '/docs/providers/tiktok',
            ],
            [
                'id' => 'linkedin',
                'name' => 'LinkedIn',
                'icon' => 'linkedin',
                'color' => 'blue',
                'supports_ads' => false,
                'supports_oauth' => true,
                'required_fields' => ['access_token'],
                'optional_fields' => ['client_id', 'client_secret', 'refresh_token'],
                'scopes' => ['r_liteprofile', 'w_member_social'],
                'documentation_url' => '/docs/providers/linkedin',
            ],
            [
                'id' => 'twitter',
                'name' => 'X (Twitter)',
                'icon' => 'twitter',
                'color' => 'blue',
                'supports_ads' => false,
                'supports_oauth' => true,
                'required_fields' => ['access_token'],
                'optional_fields' => ['client_id', 'client_secret', 'refresh_token'],
                'scopes' => ['tweet.read', 'users.read'],
                'documentation_url' => '/docs/providers/twitter',
            ],
            [
                'id' => 'facebook_ads',
                'name' => 'Facebook Ads',
                'icon' => 'facebook',
                'color' => 'blue',
                'supports_ads' => true,
                'supports_oauth' => true,
                'required_fields' => ['access_token', 'ad_account_id'],
                'optional_fields' => ['client_id', 'client_secret'],
                'scopes' => ['ads_management', 'ads_read'],
                'documentation_url' => '/docs/providers/facebook-ads',
            ],
            [
                'id' => 'google_ads',
                'name' => 'Google Ads',
                'icon' => 'google',
                'color' => 'red',
                'supports_ads' => true,
                'supports_oauth' => true,
                'required_fields' => ['access_token'],
                'optional_fields' => ['client_id', 'client_secret', 'refresh_token', 'ad_account_id'],
                'scopes' => ['https://www.googleapis.com/auth/adwords'],
                'documentation_url' => '/docs/providers/google-ads',
            ],
            [
                'id' => 'custom',
                'name' => 'Custom Provider',
                'icon' => 'code',
                'color' => 'gray',
                'supports_ads' => true,
                'supports_oauth' => false,
                'required_fields' => ['access_token'],
                'optional_fields' => ['client_id', 'client_secret', 'ad_account_id', 'redirect_uri'],
                'scopes' => [],
                'documentation_url' => '/docs/providers/custom',
            ],
        ];
    }
}