<?php

namespace App\Http\Services\Account\Twitter;

use App\Enums\ConnectionType;
use App\Traits\AccountManager;
use App\Enums\AccountType;
use App\Models\Platform;
use App\Models\SocialAccount;
use App\Models\SocialPost;
use Illuminate\Support\Arr;
use Coderjerk\BirdElephant\BirdElephant;
use Illuminate\Support\Facades\Http;


use Illuminate\Support\Facades\File;

class Account
{


    use AccountManager;

    public $twUrl, $params;


    const BASE_URL = 'https://x.com';
    const API_URL = 'https://api.x.com/2';

    const UPLOAD_URL = 'https://api.x.com/2';




    public function __construct()
    {
        $this->twUrl = "https://x.com/";

        $this->params = [
            'expansions' => 'pinned_tweet_id',
            'user.fields' => 'id,name,url,verified,username,profile_image_url'
        ];

    }





    /**
     * Summary of authRedirect
     * @param \App\Models\Platform $mediaPlatform
     * @return string
     */
    public static function authRedirect(Platform $mediaPlatform)
    {

        $configuration = $mediaPlatform->configuration;



        $client_id = $configuration->client_id;
        $redirect_uri = url('/account/twitter/callback?medium=' . $mediaPlatform->slug);

        $scope = 'tweet.read tweet.write users.read offline.access media.write';
        $codeChallenge = 'challenge';
        $state = 'state';

        return "https://x.com/i/oauth2/authorize?response_type=code&client_id=$client_id&redirect_uri=$redirect_uri&scope=$scope&state=$state&code_challenge=$codeChallenge&code_challenge_method=plain";

    }





    /**
     * Summary of getApiUrl
     * @param string $endpoint
     * @param array $params
     * @param mixed $configuration
     * @param bool $isBaseUrl
     * @return mixed
     */
    public static function getApiUrl(string $endpoint, array $params = [], mixed $configuration, bool $isBaseUrl = false, bool $isUploadUrl = false): string
    {
        // API_URL and UPLOAD_URL already contain /2 version, so don't add version again
        // BASE_URL (twitter.com) doesn't need version
        $apiUrl = $isUploadUrl ? self::UPLOAD_URL : ($isBaseUrl ? self::BASE_URL : self::API_URL);

        if (str_starts_with($endpoint, '/')) {
            $endpoint = substr($endpoint, 1);
        }

        $url = $apiUrl . '/' . $endpoint;

        if (count($params)) {
            $url .= '?' . http_build_query($params);
        }

        return $url;
    }





    /**
     * Summary of getAccessToken
     * @param string $code
     * @param \App\Models\Platform $mediaPlatform
     * @return \Illuminate\Http\Client\Response
     */
    public static function getAccessToken(string $code, Platform $mediaPlatform)
    {
        $configuration = $mediaPlatform->configuration;

        $client_id = $configuration->client_id;
        $client_secret = $configuration->client_secret;

        $apiUrl = self::getApiUrl('oauth2/token', [], $configuration);
        
        $basicAuthCredential = base64_encode($client_id . ':' . $client_secret);
        
        return Http::withHeaders([
            'Authorization' => "Basic $basicAuthCredential",
            'Content-Type' => 'application/x-www-form-urlencoded'
        ])->asForm()->post($apiUrl, [
            'code' => $code,
            'grant_type' => 'authorization_code',
            'client_id' => $client_id,
            'redirect_uri' => url('/account/twitter/callback?medium=' . $mediaPlatform->slug),
            'code_verifier' => 'challenge',
        ]);

    }



    /**
     * Summary of refreshAccessToken
     * @param \App\Models\Platform $mediaPlatform
     * @param string $token
     * @return \Illuminate\Http\Client\Response
     */
    public static function refreshAccessToken(Platform $mediaPlatform, string $token): \Illuminate\Http\Client\Response
    {

        $configuration = $mediaPlatform->configuration;

        $client_id = $configuration->client_id;
        $client_secret = $configuration->client_secret;
        $basicAuthCredential = base64_encode($client_id . ':' . $client_secret);


        $apiUrl = self::getApiUrl('oauth2/token', [
            'refresh_token' => $token,
            'grant_type' => 'refresh_token',
            'client_id' => $client_id,
        ], $configuration);

        return Http::withHeaders([
            'Authorization' => "Basic $basicAuthCredential",
            'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
        ])->asForm()->post($apiUrl);
    }





    /**
     * Summary of getAcccount
     * @return \Illuminate\Http\Client\Response
     */
    public function getAcccount(string $token, Platform $mediaPlatform): \Illuminate\Http\Client\Response
    {

        $configuration = $mediaPlatform->configuration;

        $apiUrl = self::getApiUrl('users/me', [
            'user.fields' => 'name,profile_image_url,username',
        ], $configuration);

        
        return Http::withToken($token)->get($apiUrl);
    }





    /**
     * Summary of saveTwAccount
     * @param mixed $pages
     * @param string $guard
     * @param \App\Models\Platform $mediaPlatform
     * @param string $account_type
     * @param string $is_official
     * @param int|string $dbId
     * @return void
     */
    public static function saveTwAccount(
        mixed $responseData,
        string $guard,
        Platform $mediaPlatform,
        string $account_type,
        string $is_official,
        int|string $dbId = null
    ) {
        $tw = new self();

        // Handle both Response object and array
        if ($responseData instanceof \Illuminate\Http\Client\Response) {
            $responseData = $responseData->json();
        }

        $expireIn = Arr::get($responseData, 'expires_in');
        $token = Arr::get($responseData, 'access_token');
        $refresh_token = Arr::get($responseData, 'refresh_token');


        $response = $tw->getAcccount($token, $mediaPlatform)->throw();



        $user = $response->json('data');



        $accountInfo = [
            'id' => $user['id'],
            'account_id' => $user['id'],
            'name' => Arr::get($user, 'name', null),
            'avatar' => Arr::get($user, 'profile_image_url'),
            'email' => Arr::get($user, 'email'),
            'token' => $token,
            'access_token_expire_at' => now()->addSeconds($expireIn), 
            'refresh_token' => $refresh_token,
            'refresh_token_expire_at' => now()->addMonths(6), 
        ];


        $response = $tw->saveAccount($guard, $mediaPlatform, $accountInfo, $account_type, $is_official, $dbId);

    }






    /**
     * Summary of getPost
     * @param string $tweetId
     * @param string $token
     * @param \App\Models\Platform $mediaPlatform
     * @return \Illuminate\Http\Client\Response
     */
    public static function getPost(string $tweetId, string $token, Platform $mediaPlatform): \Illuminate\Http\Client\Response
    {

        $configuration = $mediaPlatform->configuration;

        $apiUrl = self::getApiUrl("tweets/{$tweetId}", [
            'tweet.fields' => 'public_metrics,organic_metrics,non_public_metrics'
        ], $configuration);

        return Http::withToken($token)->get($apiUrl);
    }


















    /**
     * Instagram account connecton
     *
     * @param Platform $platform
     * @param array $request
     * @param string $guard
     * @return array
     */
    public function twitter(Platform $platform, array $request, string $guard = 'admin'): array
    {


        $responseStatus = response_status(translate('Authentication failed incorrect keys'), 'error');

        try {

            $accountId = Arr::get($request, 'account_id', null);

            $responseStatus = response_status(translate('Api error'), 'error');
            $consumer_key = Arr::get($request, 'consumer_key', null);
            $consumer_secret = Arr::get($request, 'consumer_secret', null);
            $access_token = Arr::get($request, 'access_token', null);
            $token_secret = Arr::get($request, 'token_secret', null);
            $bearer_token = Arr::get($request, 'bearer_token', null);

            $config = array(
                'consumer_key' => $consumer_key,
                'consumer_secret' => $consumer_secret,
                'bearer_token' => $bearer_token,
                'token_identifier' => $access_token,
                'token_secret' => $token_secret
            );


            $twitter = new BirdElephant($config);

            $response = $twitter->me()->myself([
                'expansions' => 'pinned_tweet_id',
                'user.fields' => 'id,name,url,verified,username,profile_image_url'
            ]);

            if ($response->data && $response->data->id) {
                $responseStatus = response_status(translate('Account Created'));
                $config = array_merge($config, (array) $response->data);

                $config['link'] = $this->twUrl . Arr::get($config, 'username');
                $config['avatar'] = Arr::get($config, 'profile_image_url');

                $config['account_id'] = Arr::get($config, 'id');

                $response = $this->saveAccount($guard, $platform, $config, AccountType::PROFILE->value, ConnectionType::OFFICIAL->value, $accountId);
            }



        } catch (\Exception $ex) {

        }


        return $responseStatus;


    }


    /**
     * Summary of send
     * @param \App\Models\SocialPost $post
     * @return array
     */

    public function send(SocialPost $post): array
    {
        \Log::info('[Twitter/X] ===== SEND START =====', [
            'post_id' => $post->id,
            'post_content' => $post->content,
            'post_link' => $post->link,
            'has_files' => $post->files ? $post->files->count() : 0,
        ]);

        try {
         
            $account = $post->account;
            $accountToken = $account->token;
            $platform = @$account?->platform;
            $configuration = $platform->configuration;

            \Log::info('[Twitter/X] Account & Platform Info', [
                'account_id' => $account->id,
                'account_name' => $account->name,
                'has_token' => !empty($accountToken),
                'token_prefix' => $accountToken ? substr($accountToken, 0, 20) . '...' : 'EMPTY',
                'platform_id' => $platform?->id,
                'platform_slug' => $platform?->slug,
            ]);

            $tweetFeed = '';
            if ($post->content)
                $tweetFeed .= $post->content;
            if ($post->link)
                $tweetFeed .= $post->link;

            $mediaIds = [];

            $uploadUrl = self::getApiUrl('media/upload', [], $configuration, false, true);

            $apiUrl = self::getApiUrl('tweets', [], $configuration);

            \Log::info('[Twitter/X] URLs constructed', [
                'upload_url' => $uploadUrl,
                'api_url' => $apiUrl,
                'tweet_feed_length' => strlen($tweetFeed),
                'has_files' => $post->files && $post->files->count() > 0,
                'file_count' => $post->files ? $post->files->count() : 0,
            ]);

            if ($post->files && $post->files->count() > 0) {
                \Log::info('[Twitter/X] Processing files', [
                    'file_count' => $post->files->count(),
                ]);

                foreach ($post->files as $key => $file) {
                    \Log::info("[Twitter/X] Processing file #{$key}", [
                        'file_id' => $file->id ?? 'N/A',
                        'file_name' => $file->name ?? 'N/A',
                        'file_type' => $file->type ?? 'N/A',
                        'raw_file_data' => json_encode($file),
                    ]);

                    $fileURL = imageURL($file, "gallery");

                    \Log::info("[Twitter/X] File URL generated", [
                        'key' => $key,
                        'file_url' => $fileURL,
                        'url_type' => gettype($fileURL),
                    ]);

                    // Validate file URL
                    if (!$fileURL || !is_string($fileURL)) {
                        \Log::warning("[Twitter/X] Invalid file URL - skipping", [
                            'key' => $key,
                            'file_url' => $fileURL,
                        ]);
                        continue;
                    }

                    // Determine if file is remote
                    $isRemote = str_starts_with($fileURL, 'http');

                    \Log::info("[Twitter/X] File remote check", [
                        'key' => $key,
                        'is_remote' => $isRemote,
                    ]);

                    // Get MIME type
                    $extension = strtolower(pathinfo($fileURL, PATHINFO_EXTENSION));
                    $mimeMap = [
                        'jpg' => 'image/jpeg',
                        'jpeg' => 'image/jpeg',
                        'png' => 'image/png',
                        'gif' => 'image/gif',
                        'mp4' => 'video/mp4',
                        'mov' => 'video/mp4',
                    ];
                    $mime = $mimeMap[$extension] ?? 'application/octet-stream';

                    \Log::info("[Twitter/X] MIME type detection", [
                        'key' => $key,
                        'extension' => $extension,
                        'mime' => $mime,
                        'is_video' => isValidVideoUrl($fileURL),
                    ]);

                    // For videos, validate MIME type with File::mimeType
                    $tempPath = null;
                    if (isValidVideoUrl($fileURL)) {
                        if ($isRemote) {
                            // Download to temp file for MIME detection
                            $tempPath = storage_path('app/temp/' . basename($fileURL));
                            $content = @file_get_contents($fileURL);
                            if ($content === false || file_put_contents($tempPath, $content) === false) {
                                continue;
                            }
                            $fileURL = $tempPath; // Use temp path for MIME detection
                        }

                        try {
                            $mime = File::mimeType($fileURL);
                            if (!$mime) {
                                $mime = $mimeMap[$extension] ?? 'video/mp4';
                            }
                        } catch (\Exception $e) {
                            $mime = $mimeMap[$extension] ?? 'video/mp4';
                        }
                    }

                    // Fetch content for upload
                    \Log::info("[Twitter/X] Fetching file content", [
                        'key' => $key,
                        'file_url' => $fileURL,
                        'is_remote' => $isRemote,
                    ]);

                    $content = $isRemote ? @file_get_contents($fileURL) : file_get_contents($fileURL);
                    if ($content === false) {
                        \Log::error("[Twitter/X] Failed to fetch file content", [
                            'key' => $key,
                            'file_url' => $fileURL,
                            'error' => error_get_last(),
                        ]);
                        if ($tempPath && file_exists($tempPath))
                            unlink($tempPath);
                        continue;
                    }

                    $size = strlen($content);
                    \Log::info("[Twitter/X] File content fetched", [
                        'key' => $key,
                        'size_bytes' => $size,
                        'size_mb' => round($size / 1024 / 1024, 2),
                    ]);

                    if ($size === 0) {
                        \Log::warning("[Twitter/X] File is empty - skipping", [
                            'key' => $key,
                        ]);
                        if ($tempPath && file_exists($tempPath))
                            unlink($tempPath);
                        continue;
                    }

                    $filename = basename($fileURL);

                    \Log::info("[Twitter/X] File ready for upload", [
                        'key' => $key,
                        'filename' => $filename,
                        'size' => $size,
                        'mime' => $mime,
                    ]);

                    if (isValidVideoUrl($fileURL) && $key == 1) {
                        if ($tempPath && file_exists($tempPath))
                            unlink($tempPath);
                        continue;
                    }

                    if (isValidVideoUrl($fileURL)) {
                        // Chunked upload for videos using X API v2 separate endpoints
                        // https://docs.x.com/x-api/media/initialize-media-upload
                        $mediaCategory = 'tweet_video';
                        $initializeUrl = self::API_URL . '/media/upload/initialize';

                        \Log::info("[Twitter/X] VIDEO UPLOAD - Starting INIT", [
                            'key' => $key,
                            'initialize_url' => $initializeUrl,
                            'total_bytes' => $size,
                            'media_type' => $mime,
                            'media_category' => $mediaCategory,
                        ]);

                        // INIT
                        $initResponse = Http::withToken($accountToken)
                            ->post($initializeUrl, [
                                'total_bytes' => $size,
                                'media_type' => $mime,
                                'media_category' => $mediaCategory,
                            ]);

                        \Log::info("[Twitter/X] VIDEO UPLOAD - INIT Response", [
                            'key' => $key,
                            'status' => $initResponse->status(),
                            'successful' => $initResponse->successful(),
                            'body' => $initResponse->body(),
                        ]);

                        if ($initResponse->failed()) {
                            \Log::error("[Twitter/X] VIDEO UPLOAD - INIT FAILED", [
                                'key' => $key,
                                'status' => $initResponse->status(),
                                'body' => $initResponse->body(),
                            ]);
                            if ($tempPath && file_exists($tempPath))
                                unlink($tempPath);
                            throw new \Exception('Media INIT failed: ' . $initResponse->body());
                        }

                        $mediaId = $initResponse->json()['data']['id'];

                        \Log::info("[Twitter/X] VIDEO UPLOAD - Got media ID", [
                            'key' => $key,
                            'media_id' => $mediaId,
                        ]);

                        // APPEND chunks (4MB)
                        // https://docs.x.com/x-api/media/append-media-upload
                        $chunkSize = 4 * 1024 * 1024;
                        $offset = 0;
                        $segment = 0;
                        $appendUrl = self::API_URL . '/media/upload/' . $mediaId . '/append';

                        \Log::info("[Twitter/X] VIDEO UPLOAD - Starting APPEND", [
                            'key' => $key,
                            'append_url' => $appendUrl,
                            'chunk_size' => $chunkSize,
                            'total_size' => $size,
                            'total_chunks' => ceil($size / $chunkSize),
                        ]);

                        while ($offset < $size) {
                            $chunk = substr($content, $offset, $chunkSize);
                            \Log::info("[Twitter/X] VIDEO UPLOAD - APPEND chunk", [
                                'key' => $key,
                                'segment' => $segment,
                                'offset' => $offset,
                                'chunk_size' => strlen($chunk),
                            ]);

                            $appendResponse = Http::withToken($accountToken)
                                ->attach('media', $chunk, 'chunk')
                                ->post($appendUrl, [
                                    'segment_index' => $segment,
                                ]);

                            \Log::info("[Twitter/X] VIDEO UPLOAD - APPEND Response", [
                                'key' => $key,
                                'segment' => $segment,
                                'status' => $appendResponse->status(),
                                'body' => $appendResponse->body(),
                            ]);

                            if ($appendResponse->failed()) {
                                \Log::error("[Twitter/X] VIDEO UPLOAD - APPEND FAILED", [
                                    'key' => $key,
                                    'segment' => $segment,
                                    'status' => $appendResponse->status(),
                                    'body' => $appendResponse->body(),
                                ]);
                                if ($tempPath && file_exists($tempPath))
                                    unlink($tempPath);
                                throw new \Exception('Media APPEND failed: ' . $appendResponse->body());
                            }

                            $offset += $chunkSize;
                            $segment++;
                        }

                        // FINALIZE
                        // https://docs.x.com/x-api/media/finalize-media-upload
                        $finalizeUrl = self::API_URL . '/media/upload/' . $mediaId . '/finalize';

                        \Log::info("[Twitter/X] VIDEO UPLOAD - Starting FINALIZE", [
                            'key' => $key,
                            'finalize_url' => $finalizeUrl,
                        ]);

                        $finalizeResponse = Http::withToken($accountToken)
                            ->post($finalizeUrl);

                        \Log::info("[Twitter/X] VIDEO UPLOAD - FINALIZE Response", [
                            'key' => $key,
                            'status' => $finalizeResponse->status(),
                            'body' => $finalizeResponse->body(),
                        ]);

                        if ($finalizeResponse->failed()) {
                            \Log::error("[Twitter/X] VIDEO UPLOAD - FINALIZE FAILED", [
                                'key' => $key,
                                'status' => $finalizeResponse->status(),
                                'body' => $finalizeResponse->body(),
                            ]);
                            if ($tempPath && file_exists($tempPath))
                                unlink($tempPath);
                            throw new \Exception('Media FINALIZE failed: ' . $finalizeResponse->body());
                        }

                        $finalizeData = $finalizeResponse->json()['data'] ?? [];

                        // Check STATUS for async processing
                        // https://docs.x.com/x-api/media/media-upload-status
                        if (isset($finalizeData['processing_info'])) {
                            $checkAfter = $finalizeData['processing_info']['check_after_secs'] ?? 0;
                            sleep($checkAfter);

                            $maxAttempts = 10;
                            $attempt = 0;
                            $statusUrl = self::API_URL . '/media/upload';

                            while (true) {
                                $statusResponse = Http::withToken($accountToken)
                                    ->get($statusUrl, [
                                        'command' => 'STATUS',
                                        'media_id' => $mediaId,
                                    ]);

                                if ($statusResponse->failed()) {
                                    if ($tempPath && file_exists($tempPath))
                                        unlink($tempPath);
                                    throw new \Exception('Media STATUS failed: ' . $statusResponse->body());
                                }

                                $statusData = $statusResponse->json()['data']['processing_info'] ?? null;

                                if (!$statusData) {
                                    // No processing_info means media is ready
                                    break;
                                }

                                if ($statusData['state'] === 'succeeded') {
                                    break;
                                } elseif ($statusData['state'] === 'failed') {
                                    if ($tempPath && file_exists($tempPath))
                                        unlink($tempPath);
                                    throw new \Exception('Media processing failed: ' . ($statusData['error']['message'] ?? 'Unknown error'));
                                }

                                if ($attempt++ >= $maxAttempts) {
                                    if ($tempPath && file_exists($tempPath))
                                        unlink($tempPath);
                                    throw new \Exception('Media processing timeout');
                                }

                                sleep($statusData['check_after_secs'] ?? 5);
                            }
                        }

                        $mediaIds[] = $mediaId;
                        \Log::info("[Twitter/X] VIDEO UPLOAD - Complete", [
                            'key' => $key,
                            'media_id' => $mediaId,
                        ]);
                    } else {
                        // Simple upload for images/GIFs using X API v2
                        // https://docs.x.com/x-api/media/upload-media
                        // Use chunked upload approach for better reliability
                        $mediaCategory = str_contains($mime, 'gif') ? 'tweet_gif' : 'tweet_image';
                        $initializeUrl = self::API_URL . '/media/upload/initialize';

                        \Log::info("[Twitter/X] IMAGE UPLOAD - Starting INIT", [
                            'key' => $key,
                            'initialize_url' => $initializeUrl,
                            'total_bytes' => $size,
                            'media_type' => $mime,
                            'media_category' => $mediaCategory,
                        ]);

                        // INIT
                        $initResponse = Http::withToken($accountToken)
                            ->post($initializeUrl, [
                                'total_bytes' => $size,
                                'media_type' => $mime,
                                'media_category' => $mediaCategory,
                            ]);

                        \Log::info("[Twitter/X] IMAGE UPLOAD - INIT Response", [
                            'key' => $key,
                            'status' => $initResponse->status(),
                            'successful' => $initResponse->successful(),
                            'body' => $initResponse->body(),
                        ]);

                        if ($initResponse->failed()) {
                            \Log::error("[Twitter/X] IMAGE UPLOAD - INIT FAILED", [
                                'key' => $key,
                                'status' => $initResponse->status(),
                                'body' => $initResponse->body(),
                            ]);
                            if ($tempPath && file_exists($tempPath))
                                unlink($tempPath);
                            throw new \Exception('Media INIT failed: ' . $initResponse->body());
                        }

                        $mediaId = $initResponse->json()['data']['id'] ?? null;
                        if (!$mediaId) {
                            \Log::error("[Twitter/X] IMAGE UPLOAD - No media_id in response", [
                                'key' => $key,
                                'response' => $initResponse->json(),
                            ]);
                            throw new \Exception('Missing media_id in INIT response: ' . $initResponse->body());
                        }

                        \Log::info("[Twitter/X] IMAGE UPLOAD - Got media ID", [
                            'key' => $key,
                            'media_id' => $mediaId,
                        ]);

                        // APPEND - single chunk for images (< 5MB)
                        $appendUrl = self::API_URL . '/media/upload/' . $mediaId . '/append';

                        \Log::info("[Twitter/X] IMAGE UPLOAD - Starting APPEND", [
                            'key' => $key,
                            'append_url' => $appendUrl,
                            'filename' => $filename,
                            'content_size' => strlen($content),
                        ]);

                        $appendResponse = Http::withToken($accountToken)
                            ->attach('media', $content, $filename)
                            ->post($appendUrl, [
                                'segment_index' => 0,
                            ]);

                        \Log::info("[Twitter/X] IMAGE UPLOAD - APPEND Response", [
                            'key' => $key,
                            'status' => $appendResponse->status(),
                            'body' => $appendResponse->body(),
                        ]);

                        if ($appendResponse->failed()) {
                            \Log::error("[Twitter/X] IMAGE UPLOAD - APPEND FAILED", [
                                'key' => $key,
                                'status' => $appendResponse->status(),
                                'body' => $appendResponse->body(),
                            ]);
                            if ($tempPath && file_exists($tempPath))
                                unlink($tempPath);
                            throw new \Exception('Media APPEND failed: ' . $appendResponse->body());
                        }

                        // FINALIZE
                        $finalizeUrl = self::API_URL . '/media/upload/' . $mediaId . '/finalize';

                        \Log::info("[Twitter/X] IMAGE UPLOAD - Starting FINALIZE", [
                            'key' => $key,
                            'finalize_url' => $finalizeUrl,
                        ]);

                        $finalizeResponse = Http::withToken($accountToken)
                            ->post($finalizeUrl);

                        \Log::info("[Twitter/X] IMAGE UPLOAD - FINALIZE Response", [
                            'key' => $key,
                            'status' => $finalizeResponse->status(),
                            'body' => $finalizeResponse->body(),
                        ]);

                        if ($finalizeResponse->failed()) {
                            \Log::error("[Twitter/X] IMAGE UPLOAD - FINALIZE FAILED", [
                                'key' => $key,
                                'status' => $finalizeResponse->status(),
                                'body' => $finalizeResponse->body(),
                            ]);
                            if ($tempPath && file_exists($tempPath))
                                unlink($tempPath);
                            throw new \Exception('Media FINALIZE failed: ' . $finalizeResponse->body());
                        }

                        $mediaIds[] = $mediaId;
                        \Log::info("[Twitter/X] IMAGE UPLOAD - Complete", [
                            'key' => $key,
                            'media_id' => $mediaId,
                        ]);
                    }

                    // Clean up temp file if used
                    if ($tempPath && file_exists($tempPath)) {
                        unlink($tempPath);
                    }
                }
            }

            // Post the tweet
            $postParams = ['text' => $tweetFeed];
            if (count($mediaIds) > 0) {
                $postParams['media'] = ['media_ids' => $mediaIds];
            }

            \Log::info("[Twitter/X] POSTING TWEET", [
                'api_url' => $apiUrl,
                'post_params' => $postParams,
                'media_ids_count' => count($mediaIds),
                'media_ids' => $mediaIds,
            ]);

            $response = Http::withToken($accountToken)
                ->post($apiUrl, $postParams);

            $responseJson = $response->json();

            \Log::info("[Twitter/X] TWEET POST Response", [
                'status' => $response->status(),
                'successful' => $response->successful(),
                'response_json' => $responseJson,
            ]);

            if (isset($responseJson['data']['id'])) {
                \Log::info("[Twitter/X] ===== SEND SUCCESS =====", [
                    'post_id' => $post->id,
                    'tweet_id' => $responseJson['data']['id'],
                    'url' => "https://x.com/i/status/" . $responseJson['data']['id'],
                ]);
                return [
                    'status' => true,
                    'response' => translate("Posted Successfully"),
                    'url' => "https://x.com/i/status/" . $responseJson['data']['id']
                ];
            }

            \Log::error("[Twitter/X] ===== SEND FAILED =====", [
                'post_id' => $post->id,
                'response' => $responseJson,
                'detail' => $responseJson['detail'] ?? 'Failed to post',
            ]);

            return [
                'status' => false,
                'response' => $responseJson['detail'] ?? 'Failed to post'
            ];

        } catch (\Exception $ex) {
            \Log::error("[Twitter/X] ===== SEND EXCEPTION =====", [
                'post_id' => $post->id ?? 'N/A',
                'message' => $ex->getMessage(),
                'file' => $ex->getFile(),
                'line' => $ex->getLine(),
                'trace' => $ex->getTraceAsString(),
            ]);
            return [
                'status' => false,
                'response' => strip_tags($ex->getMessage()),
                'url' => null
            ];
        }
    }

    /**
     * Get account-level insights (followers count)
     * https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me
     *
     * @param SocialAccount $account
     * @return array
     */
    public function getAccountInsights(SocialAccount $account): array
    {
        try {
            $token = $account->token ?? $account->access_token ?? null;

            if (!$token) {
                return [
                    'status' => false,
                    'message' => 'Missing access token',
                    'data' => [],
                ];
            }

            // Get user info with public_metrics (includes followers_count)
            $apiUrl = self::API_URL . "/users/me?user.fields=public_metrics";

            $response = Http::withToken($token)->get($apiUrl);
            $data = $response->json();

            if ($response->failed() || isset($data['errors'])) {
                $errorMsg = $data['errors'][0]['message'] ?? $data['detail'] ?? 'API request failed';
                return [
                    'status' => false,
                    'message' => $errorMsg,
                    'data' => [],
                ];
            }

            $publicMetrics = $data['data']['public_metrics'] ?? [];

            return [
                'status' => true,
                'message' => 'Account insights fetched successfully',
                'data' => [
                    'followers' => $publicMetrics['followers_count'] ?? 0,
                ],
            ];

        } catch (\Throwable $e) {
            return [
                'status' => false,
                'message' => 'Error fetching account insights: ' . $e->getMessage(),
                'data' => [],
            ];
        }
    }

    /**
     * Get metrics/insights for a Twitter/X post
     *
     * Note: public_metrics.impression_count often returns 0
     * non_public_metrics and organic_metrics require OAuth 2.0 User Context
     * and the tweet must be authored by the authenticated user
     *
     * @param SocialPost $post
     * @param SocialAccount $account
     * @return array
     */
    public function getInsight(SocialPost $post, SocialAccount $account): array
    {
        try {
            $token = $account->token ?? $account->access_token ?? null;

            if (!$token || !$post->platform_post_id) {
                return [
                    'status' => false,
                    'message' => 'Missing access token or post ID',
                    'metrics' => [],
                ];
            }

            // Request all available metrics: public, non_public, and organic
            // non_public_metrics includes impression_count which is more reliable
            // organic_metrics includes engagement metrics for non-promoted tweets
            $tweetFields = 'public_metrics,non_public_metrics,organic_metrics';
            $apiUrl = self::API_URL . "/tweets/{$post->platform_post_id}?tweet.fields={$tweetFields}";

            $response = Http::withToken($token)->get($apiUrl);
            $data = $response->json();

            // Handle rate limiting (429)
            if ($response->status() === 429) {
                $resetTime = $response->header('x-rate-limit-reset');
                $waitTime = $resetTime ? (int)$resetTime - time() : 60;
                return [
                    'status' => false,
                    'message' => "Rate limited. Try again in {$waitTime} seconds.",
                    'metrics' => [],
                    'rate_limited' => true,
                ];
            }

            if ($response->failed() || isset($data['errors'])) {
                // If non_public_metrics fails (requires tweet owner auth), fallback to public only
                $apiUrl = self::API_URL . "/tweets/{$post->platform_post_id}?tweet.fields=public_metrics";
                $response = Http::withToken($token)->get($apiUrl);
                $data = $response->json();

                // Check rate limit again on fallback
                if ($response->status() === 429) {
                    return [
                        'status' => false,
                        'message' => 'Rate limited by X API. Please try again later.',
                        'metrics' => [],
                        'rate_limited' => true,
                    ];
                }
            }

            if ($response->failed() || isset($data['errors'])) {
                $errorMsg = $data['errors'][0]['message'] ?? $data['detail'] ?? 'API request failed';
                return [
                    'status' => false,
                    'message' => $errorMsg,
                    'metrics' => [],
                ];
            }

            $tweetData = $data['data'] ?? [];
            $publicMetrics = $tweetData['public_metrics'] ?? [];
            $nonPublicMetrics = $tweetData['non_public_metrics'] ?? [];
            $organicMetrics = $tweetData['organic_metrics'] ?? [];

            // Prefer non_public_metrics for impressions (more accurate)
            // Fallback chain: non_public -> organic -> public
            $impressions = $nonPublicMetrics['impression_count']
                ?? $organicMetrics['impression_count']
                ?? $publicMetrics['impression_count']
                ?? 0;

            // Use organic metrics for engagement if available (excludes promoted)
            $likes = $organicMetrics['like_count'] ?? $publicMetrics['like_count'] ?? 0;
            $retweets = $organicMetrics['retweet_count'] ?? $publicMetrics['retweet_count'] ?? 0;
            $replies = $organicMetrics['reply_count'] ?? $publicMetrics['reply_count'] ?? 0;
            $quotes = $publicMetrics['quote_count'] ?? 0;

            // URL and profile clicks from non_public_metrics
            $urlClicks = $nonPublicMetrics['url_link_clicks'] ?? $organicMetrics['url_link_clicks'] ?? 0;
            $profileClicks = $nonPublicMetrics['user_profile_clicks'] ?? $organicMetrics['user_profile_clicks'] ?? 0;

            $engagements = $likes + $retweets + $replies + $quotes + $urlClicks + $profileClicks;

            $metrics = [
                'impressions' => $impressions,
                'engagements' => $engagements,
                'likes' => $likes,
                'shares' => $retweets + $quotes,
                'comments' => $replies,
                'reactions' => $likes,
                'reach' => $impressions, // X doesn't differentiate reach from impressions
            ];

            return [
                'status' => true,
                'message' => 'Metrics fetched successfully',
                'metrics' => $metrics,
            ];

        } catch (\Throwable $e) {
            return [
                'status' => false,
                'message' => 'Error fetching X metrics: ' . $e->getMessage(),
                'metrics' => [],
            ];
        }
    }
}
