<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Kiota\Authentication\Oauth\AuthorizationCodeContext;
use Microsoft\Kiota\Http\GuzzleRequestAdapter;
use GuzzleHttp\Client;

use Microsoft\Graph\Core\Authentication\GraphPhpLeagueAuthenticationProvider;
use Microsoft\Graph\Generated\Users\Item\SendMail\SendMailPostRequestBody;
use Microsoft\Graph\Generated\Models\Message;
use Microsoft\Graph\Generated\Models\Recipient;
use Microsoft\Graph\Generated\Models\EmailAddress;
use Microsoft\Graph\Generated\Models\ItemBody;
use Microsoft\Graph\Generated\Models\BodyType;
use Microsoft\Kiota\Authentication\Cache\InMemoryAccessTokenCache;
use League\OAuth2\Client\Token\AccessToken;
use Microsoft\Graph\Generated\Models\AttachmentCollectionResponse;

use Microsoft\Graph\Core\Authentication\GraphPhpLeagueAccessTokenProvider;
use Carbon\Carbon;

class EmailController extends Controller
{
    protected $scopes = ['User.Read', 'Mail.ReadWrite', 'offline_access'];

    public function sendEmail(Request $request)
    {
       
        
        $user = Auth::user();
        
        // ✅ Step 1: Get a valid access token
       // $accessToken = $user->outlook_access_token;
       // $accessToken = (new OutlookController())->refreshAccessToken();
        //echo $accessToken;exit;
        if (!$user->outlook_access_token) {
            return redirect()->route('outlook.auth')->with('error', 'Failed to refresh Outlook token. Please reconnect your account.');
        } // Recreate the Token Request Context
        
        $accessToken = $user->outlook_access_token;
        $refreshToken = $user->outlook_refresh_token;
        $expiresAt = $user->outlook_token_expiry->timestamp;

        $tokenRequestContext = new AuthorizationCodeContext(
            config('services.outlook.tenant_id'),
            config('services.outlook.client_id'),
            config('services.outlook.client_secret'),
            'authCode',
            config('services.outlook.redirect'),
            
        );


        //
            $cache = new InMemoryAccessTokenCache(
                $tokenRequestContext,
                new AccessToken(
                    [
                        'access_token' => $accessToken,
                        'refresh_token' => $refreshToken,
                        'expires' => $expiresAt
                    ]
                )
            );

            $graphServiceClient = GraphServiceClient::createWithAuthenticationProvider(
                GraphPhpLeagueAuthenticationProvider::createWithAccessTokenProvider(
                    GraphPhpLeagueAccessTokenProvider::createWithCache(
                        $cache,
                        $tokenRequestContext,
                        $this->scopes
                    )
                )
            );
        // Create Graph Client with stored access token
        $user = $graphServiceClient->me()->get()->wait();
        // echo $user->getGivenName();exit;
        
        // ✅ Step 3: Render the Email Content from Blade Template
        $emailContent = view('emails.template', ['message' => $request->message])->render();
    
        // ✅ Step 4: Create Message Object
        $emailMessage = new Message();
        $emailMessage->setSubject($request->subject);
    
        // Set Body
        $body = new ItemBody();
        $body->setContentType(new BodyType(BodyType::HTML)); // Use HTML for rich content
        $body->setContent($emailContent);
        $emailMessage->setBody($body);
    
        // Set To Recipients
        $toRecipient = new Recipient();
        $toEmailAddress = new EmailAddress();
        $toEmailAddress->setAddress($request->to);
        $toRecipient->setEmailAddress($toEmailAddress);
        
        $emailMessage->setToRecipients([$toRecipient]);
    
        // Set CC Recipients (Optional)
        if ($request->cc) {
            $ccRecipients = $this->formatCcRecipients($request->cc);
            $emailMessage->setCcRecipients($ccRecipients);
        }
    
        // Set Attachments (Optional)
        if ($request->has('attachments')) {
            $attachments = $this->prepareAttachments($request->attachments);
            $emailMessage->setAttachments($attachments);
        }
    
        // ✅ Step 5: Create SendMail Request Body
        $sendMailBody = new SendMailPostRequestBody();
        $sendMailBody->setMessage($emailMessage);
        $sendMailBody->setSaveToSentItems(true); // Save email in Sent Items
        

       // dd($sendMailBody);
        try {
            // ✅ Step 6: Send Email
            // $user = $graphClient->me()->get()->wait();
            // echo "Hello, I am {$user->getGivenName()}";exit;
             $graphServiceClient->me()->sendMail()->post($sendMailBody)->wait(); // ✅ Corrected!
        
            return redirect()->back()->with('success', 'Email sent successfully!');
        } catch (\Exception $e) {
            dd($e);
            return redirect()->back()->with('error', 'Failed to send email: ' . $e->getMessage());
        }
    }

    private function formatCcRecipients($cc)
    {
        if (!$cc) {
            return [];
        }

        $ccEmails = explode(',', $cc);
        $formatted = [];

        foreach ($ccEmails as $email) {
            $formatted[] = [
                'emailAddress' => [
                    'address' => trim($email),
                ],
            ];
        }

        return $formatted;
    }

    private function prepareAttachments($attachmentIds)
    {
        if (!$attachmentIds) {
            return [];
        }

        $attachments = [];
        foreach ($attachmentIds as $fileId) {
            $file = ProjectFile::find($fileId);

            if ($file && Storage::exists($file->path)) {
                $fileContent = base64_encode(Storage::get($file->path));

                $attachments[] = [
                    '@odata.type' => '#microsoft.graph.fileAttachment',
                    'name' => $file->name,
                    'contentType' => mime_content_type(Storage::path($file->path)),
                    'contentBytes' => $fileContent,
                ];
            }
        }

        return $attachments;
    }
}
