<?php

namespace App\Http\Controllers\Admin\Communication\Gateway;

use Exception;
use Illuminate\Support\Str;
use Illuminate\View\View;
use App\Traits\ModelAction;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use App\Enums\System\ChannelTypeEnum;
use App\Http\Requests\GatewayRequest;
use Illuminate\Support\Facades\Session;
use App\Exceptions\ApplicationException;
use App\Enums\System\Gateway\WhatsAppGatewayTypeEnum;
use App\Services\System\Communication\GatewayService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use App\Models\Gateway; 

class WhatsappCloudApiControllerBackup extends Controller
{
    use ModelAction;
    protected $gatewayService;

    public function __construct()
    {
        $this->gatewayService = new GatewayService();
    }

    /**
     * index
     *
     * @return View
     */
    public function index(): View
    {
        Session::put("menu_active", true);
        return $this->gatewayService->loadLogs(channel: ChannelTypeEnum::WHATSAPP, type: WhatsAppGatewayTypeEnum::CLOUD);
    }

    /**
     *
     * @param GatewayRequest $request
     * 
     * @return \Illuminate\Http\RedirectResponse
     * 
     */
    public function store(GatewayRequest $request): RedirectResponse {
        
        try {

            $data = $request->all();
            unset($data["_token"]);
            return $this->gatewayService->saveGateway(ChannelTypeEnum::WHATSAPP, $data);

        } catch (ApplicationException $e) {
            
            $notify[] = ["error", translate($e->getMessage())];
            return back()->withNotify($notify);

        } catch (Exception $e) {
            
            $notify[] = ["error", getEnvironmentMessage($e->getMessage())];
            return back()->withNotify($notify);
        }
    }

     /**
     * update
     *
     * @param GatewayRequest $request
     * @param string|int $id
     * 
     * @return RedirectResponse
     */
    public function update(GatewayRequest $request, string|int $id): RedirectResponse {
        
        try {

            $data = $request->all();
            unset($data["_token"]);
            return $this->gatewayService->saveGateway(ChannelTypeEnum::WHATSAPP, $data, $id);

        } catch (ApplicationException $e) {
            
            $notify[] = ["error", translate($e->getMessage())];
            return back()->withNotify($notify);

        } catch (Exception $e) {
            
            $notify[] = ["error", getEnvironmentMessage($e->getMessage())];
            return back()->withNotify($notify);
        }
    }

    /**
     * destroy
     *
     * @param string|int|null|null $id
     * 
     * @return RedirectResponse
     */
    public function destroy(string|int|null $id = null): RedirectResponse
    {
        try {
            return $this->gatewayService->destroyGateway(channel: ChannelTypeEnum::WHATSAPP, type:null, id: $id);

        } catch (ApplicationException $e) {
            
            $notify[] = ["error", translate($e->getMessage())];
            return back()->withNotify($notify);

        } catch (Exception $e) {
            
            $notify[] = ["error", getEnvironmentMessage($e->getMessage())];
            return back()->withNotify($notify);
        }
    }

    //New Functions
    public function initiateEmbeddedSignup(Request $request): JsonResponse
    {
        try {
            $appId = site_settings(\App\Enums\SettingKey::META_APP_ID->value);
            $appSecret = site_settings(\App\Enums\SettingKey::META_APP_SECRET->value);

            if (empty($appId) || empty($appSecret)) {
                return response()->json([
                    'success' => false,
                    'message' => translate('Meta App credentials not configured. Please configure App ID and App Secret in settings.')
                ], 400);
            }

            $state = base64_encode(json_encode([
                'user_type' => 'admin',
                'timestamp' => now()->timestamp,
                'nonce' => Str::random(16),
            ]));

            $signupUrl = "https://www.facebook.com/v21.0/dialog/oauth?" . http_build_query([
                'client_id' => $appId,
                'redirect_uri' => route('admin.gateway.whatsapp.cloud.api.embedded.callback'),
                'state' => $state,
                'scope' => 'whatsapp_business_messaging,business_management',
                'extras' => json_encode([
                    'feature' => 'whatsapp_embedded_signup',
                    'version' => 2,
                    'setup' => [
                        'solution' => 'whatsapp',
                        'flow' => 'signup'
                    ]
                ])
            ]);

            Log::info('Generated signup URL: ' . $signupUrl);

            return response()->json([
                'success' => true,
                'signup_url' => $signupUrl,
                'message' => translate('Embedded signup URL generated successfully')
            ]);

        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => translate('Failed to initiate embedded signup: ') . $e->getMessage()
            ], 500);
        }
    }

    public function handleEmbeddedCallback(Request $request): View
    {
        // Step 1: Check for OAuth errors
        if ($request->has('error')) {
            Log::error('OAuth error: ' . json_encode($request->all()));
            return view('partials.pop-up.callback', [
                'success' => false,
                'message' => translate('Embedded signup failed: ') . ($request->error_description ?? $request->error)
            ]);
        }

        // Step 2: Validate state
        $stateResult = $this->validateState($request->state);
        if (!$stateResult['success']) {
            Log::error('State validation failed');
            return view('partials.pop-up.callback', [
                'success' => false,
                'message' => $stateResult['message'] ?? translate('Invalid or expired signup session')
            ]);
        }
        $state = $stateResult['data'];

        // Step 3: Exchange code for token
        $tokenResult = $this->exchangeCodeForToken($request->code);
        if (!$tokenResult['success']) {
            Log::error('Token exchange failed');
            return view('partials.pop-up.callback', [
                'success' => false,
                'message' => $tokenResult['message'] ?? translate('Failed to exchange code for token')
            ]);
        }
        $tokenData = $tokenResult['data'];

        // Step 4: Get account info
        $accountResult = $this->getCompleteAccountInfo($tokenData);
        if (!$accountResult['success']) {
            Log::error('Account info fetch failed');
            return view('partials.pop-up.callback', [
                'success' => false,
                'message' => $accountResult['message'] ?? translate('Failed to get account info')
            ]);
        }
        $accountInfo = $accountResult['data'];

        // Step 5: Prepare gateway data
        $gatewayDataResult = $this->prepareGatewayData($state, $tokenData, $accountInfo);
        if (!$gatewayDataResult['success']) {
            Log::error('Gateway data preparation failed');
            return view('partials.pop-up.callback', [
                'success' => false,
                'message' => $gatewayDataResult['message'] ?? translate('Failed to prepare gateway data')
            ]);
        }
        $gatewayData = $gatewayDataResult['data'];

        // Step 6: Save to gateways table
        $saveResult = $this->saveGatewayData($gatewayData);
        if (!$saveResult['success']) {
            Log::error('Gateway save failed');
            return view('partials.pop-up.callback', [
                'success' => false,
                'message' => $saveResult['message'] ?? translate('Failed to save gateway')
            ]);
        }

        // Step 7: Return success
        return view('partials.pop-up.callback', [
            'success' => true,
            'message' => translate('WhatsApp Business Account connected successfully')
        ]);
    }

    private function validateState(string $stateParam): array
    {
        try {
            $state = json_decode(base64_decode($stateParam), true);
            Log::info('Decoded state: ', $state ?? []);

            if (!$state || !is_array($state)) {
                Log::warning('Invalid state structure');
                return ['success' => false, 'message' => 'Invalid state structure'];
            }

            $required = ['user_type', 'timestamp', 'nonce'];
            foreach ($required as $field) {
                if (!isset($state[$field])) {
                    Log::warning("Missing field: $field");
                    return ['success' => false, 'message' => "Missing field: $field"];
                }
            }

            if (now()->timestamp - $state['timestamp'] > 3600) {
                Log::warning('Timestamp expired');
                return ['success' => false, 'message' => 'Timestamp expired'];
            }

            return ['success' => true, 'data' => $state];

        } catch (Exception $e) {
            Log::error('State validation error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'State validation error: ' . $e->getMessage()];
        }
    }

    private function exchangeCodeForToken(string $code): array
    {
        try {
            $appId = site_settings(\App\Enums\SettingKey::META_APP_ID->value);
            $appSecret = site_settings(\App\Enums\SettingKey::META_APP_SECRET->value);
            Log::info('App ID: ' . $appId . ', App Secret: ' . $appSecret);

            $response = Http::asForm()->post("https://graph.facebook.com/oauth/access_token", [
                'client_id' => $appId,
                'client_secret' => $appSecret,
                'code' => $code,
                'redirect_uri' => route('admin.gateway.whatsapp.cloud.api.embedded.callback'),
            ]);

            if (!$response->successful()) {
                Log::error('Token exchange failed: ' . $response->body());
                return ['success' => false, 'message' => 'Token exchange failed'];
            }

            $data = $response->json();
            Log::info('Token response: ' . json_encode($data));
            if (!isset($data['access_token'])) {
                Log::error('No access token in response: ' . json_encode($data));
                return ['success' => false, 'message' => 'No access token in response'];
            }

            return ['success' => true, 'data' => $data];
        } catch (Exception $e) {
            Log::error('Token exchange error: ' . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    private function getCompleteAccountInfo(array $tokenData): array
    {
        try {
            $accessToken = $tokenData['access_token'];
            
            $userResponse = Http::withHeaders([
                'Authorization' => "Bearer $accessToken"
            ])->get("https://graph.facebook.com/v21.0/me", [
                'fields' => 'id,name,whatsapp_business_accounts{id,name,currency,timezone_id,message_template_namespace,account_review_status}'
            ]);

            if (!$userResponse->successful()) {
                Log::error('User info fetch failed: ' . $userResponse->body());
                $error = $userResponse->json()['error'] ?? [];
                Log::error('Error details: ' . json_encode($error));
                return ['success' => false, 'message' => 'Failed to get user information: ' . ($error['message'] ?? 'Unknown error')];
            }

            $userData = $userResponse->json();

            if (empty($userData['whatsapp_business_accounts']['data'])) {
                Log::warning('No WhatsApp Business Account found in response: ' . json_encode($userData));
                return ['success' => false, 'message' => 'No WhatsApp Business Account found'];
            }

            $businessAccount = $userData['whatsapp_business_accounts']['data'][0];

            $phoneResponse = Http::withHeaders([
                'Authorization' => "Bearer $accessToken"
            ])->get("https://graph.facebook.com/v21.0/{$businessAccount['id']}/phone_numbers", [
                'fields' => 'id,display_phone_number,verified_name,quality_rating,status'
            ]);

            if (!$phoneResponse->successful()) {
                Log::error('Phone numbers fetch failed: ' . $phoneResponse->body());
                return ['success' => false, 'message' => 'Failed to get phone numbers'];
            }

            $phoneNumbers = $phoneResponse->json()['data'] ?? [];

            return ['success' => true, 'data' => [
                'user' => $userData,
                'business_account' => $businessAccount,
                'phone_numbers' => $phoneNumbers,
            ]];
        } catch (Exception $e) {
            Log::error('Account info error: ' . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    private function prepareGatewayData(array $state, array $tokenData, array $accountInfo): array
    {
        try {
            $businessAccount = $accountInfo['business_account'];
            $phoneNumbers = $accountInfo['phone_numbers'];
            
            $primaryPhone = $phoneNumbers[0] ?? null;
            
            $metaData = [
                'user_access_token' => $tokenData['access_token'],
                'whatsapp_business_account_id' => $businessAccount['id'],
            ];
            
            if ($primaryPhone) {
                $metaData['phone_number_id'] = $primaryPhone['id'];
            }

            $gatewayData = [
                'uid' => Str::random(32),
                'user_id' => null,
                'type' => 'cloud',
                'channel' => ChannelTypeEnum::WHATSAPP->value,
                'name' => $primaryPhone['verified_name'] ?? $businessAccount['name'] ?? 'WhatsApp Gateway',
                'address' => $primaryPhone['display_phone_number'] ?? null,
                'meta_data' => json_encode($metaData), // Assuming meta_data is stored as JSON
                'payload' => json_encode([
                    'token_data' => $tokenData,
                    'account_info' => $accountInfo,
                    'embedded_signup_completed_at' => now()->toISOString(),
                    'state_info' => $state,
                ]),
                'api_version' => 'v21.0',
                'setup_method' => 'embedded',
                'status' => 'active',
                'per_message_min_delay' => 1.00,
                'per_message_max_delay' => 3.00,
                'delay_after_count' => 10,
                'delay_after_duration' => 60.00,
                'reset_after_count' => 100,
                'bulk_contact_limit' => 1,
                'last_sync_at' => null,
            ];

            return ['success' => true, 'data' => $gatewayData];
        } catch (Exception $e) {
            Log::error('Gateway preparation error: ' . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    private function saveGatewayData(array $gatewayData): array
    {
        try {
            $gateway = new Gateway();
            $gateway->fill($gatewayData);
            $gateway->save();

            Log::info('Gateway saved to database with ID: ' . $gateway->id);
            return ['success' => true];
        } catch (Exception $e) {
            Log::error('Gateway save error: ' . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }
}