<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Webklex\IMAP\Facades\Client;
use Webklex\PHPIMAP\ClientManager;
use App\Exceptions\GlobalException;
use App\Mail\AnswerEmail;
use App\Helper\Helper;



class EmailController extends Controller
{


    public function answer(Request $request)
    {
        // Ejemplo de datos de la respuesta. Estos pueden venir del request o definirse manualmente.
        $data = [
            'subject' => 'Respuesta a ' . $request->input('subject'),
            'mensaje' => $request->input('message')
        ];

        $email = $request->input('email');
        if (preg_match('/([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/', $email, $matches)) {
            $email = $matches[1];
        } 
        

        // Envía el correo a la dirección deseada.
        //Mail::to($email)->send(new AnswerEmail($data));
        $failures = $this->dispatchEmailAppointment($email,$data,$request->input('subject'));
        if(is_bool($failures) || (is_array($failures) && count($failures)==0) || is_countable($failures)){
            $this->saveEmail($data,$email);
        }

        // Redirige hacia atrás con un mensaje flash
        return redirect()->back()->with('success', 'Correo enviado satisfactoriamente');
    }

    private function saveEmail($data,$email){
        $cm = new ClientManager('../config/imap.php');
        $client = $cm->account('default');
        // Conecta al servidor IMAP
        $client->connect();
        // Debes generar el contenido completo del correo (cabeceras + cuerpo).
        $rawMessage = "From: ".Helper::MAIL_TO_SEND."\r\n" .
        "To: ".$email."\r\n" .
        "Date: ".date('r')."\r\n" .
        "Subject: ".$data["subject"]."\r\n" .
        "MIME-Version: 1.0\r\n" .
        "Content-Type: text/plain; charset=UTF-8\r\n" .
        "\r\n" .
        $data["mensaje"];
        // Selecciona la carpeta INBOX
        $inbox = $client->getFolder('Sent');
        $inbox->appendMessage($rawMessage);
    }

    /**
     * 
     */
    private function dispatchEmailAppointment($email,$data,$subject){
        return Helper::sendEmail(
            Helper::MAIL_TO_SEND,
            [$email],
            $subject,
            $data,
            AnswerEmail::class); 
    }

    
    private function checkEmail($id,$folder){
        $cm = new ClientManager('../config/imap.php');
            
        $client = $cm->account('default');

        // Conecta al servidor IMAP
        $client->connect();

        // Selecciona la carpeta INBOX
        $inbox = $client->getFolder($folder);

        // Obtiene el mensaje por su ID
        $query = $inbox->query();

        $message = $query->getMessage($id);
        $message->setFlag('Seen');


        return $message;
    }

    private function getDetailsEmail($message) {
        // Accede a los detalles del mensaje
        $subject = imap_utf8($message->getSubject());
        $from = $message->getFrom();
        $body = "";
        $files = [];
    
        // Obtener el cuerpo del correo con sanitización para mayor seguridad
        if ($message->hasHTMLBody()) {
            // Obtenemos el HTML bruto
            $rawBody = $message->getHTMLBody();
            
            // Método radical: convertir todo a texto plano y luego volver a aplicar formato básico
            $plainText = strip_tags($rawBody);
            
            // Detectar párrafos basados en líneas en blanco o saltos de línea
            $paragraphs = preg_split('/\n\s*\n|\r\n\s*\r\n|\r\s*\r/m', $plainText);
            
            // Reconstruir el contenido con formato básico
            $formattedContent = '';
            foreach ($paragraphs as $paragraph) {
                if (trim($paragraph) !== '') {
                    // Reemplazar URLs con enlaces
                    $paragraph = preg_replace('/(https?:\/\/[^\s]+)/', '<a href="$1" target="_blank">$1</a>', $paragraph);
                    // Convertir saltos de línea en <br>
                    $paragraph = nl2br(trim($paragraph));
                    $formattedContent .= "<p>{$paragraph}</p>\n";
                }
            }
            
            $body = $formattedContent;
            
            // Si no hay contenido, mostramos un mensaje
            if (trim($formattedContent) === '') {
                $body = '<p>Este correo no contiene texto legible o solo contiene imágenes.</p>';
            }
        } elseif ($message->hasTextBody()) {
            $body = nl2br(e($message->getTextBody())); // Convertir saltos de línea en <br> y escapar texto
        }
    
        // Obtener la fecha del correo
        $date = $message->getDate();
    
        // Verificar si el correo tiene adjuntos
        if ($message->hasAttachments()) {
            foreach ($message->getAttachments() as $attachment) {
                $files[] = [
                    'name' => $attachment->getName(), // Nombre del archivo
                    'mime' => $attachment->getMimeType(), // Tipo de archivo
                    'data' => base64_encode($attachment->getContent()), // Contenido en base64
                    'is_image' => in_array(strtolower(pathinfo($attachment->getName(), PATHINFO_EXTENSION)), ['jpg', 'jpeg', 'png', 'gif'])
                ];
            }
        }
    
        return [
            'subject' => $subject,
            'from' => $from,
            'body' => $body,
            'date' => $date,
            'files' => $files    
        ];
    }
    


    public function checkEmailInbox($id){
        try {
            $message = $this->checkEmail($id,"INBOX");
            $detailsEmail = $this->getDetailsEmail($message);
            return view('check-email', $detailsEmail);
        } catch (Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }

    public function checkEmailOut($id){
        try {
            $message = $this->checkEmail($id,"Sent");
            $detailsEmail = $this->getDetailsEmail($message);
            return view('check-email-out', $detailsEmail);
        } catch (Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }
    public function inbox(Request $request)
    {
        try {
            // Selecciona la cuenta IMAP definida en config/imap.php (normalmente 'default')
            // $client = Client::account('default');
            // or create a new instance manually
            $page = (int) $request->get("page", 1);
            $cm = new ClientManager('../config/imap.php');
            $client = $cm->account('default');
            // Conecta al servidor IMAP
            $client->connect();

            // Selecciona la carpeta INBOX
            $inbox = $client->getFolder('INBOX');
            // Obtiene todos los mensajes. Puedes ajustar el criterio de búsqueda si lo deseas.
            $messages = $inbox->messages()->all()->setFetchBody(false)->limit(100)->get();

             // Ordena los mensajes por fecha de forma descendente (más reciente primero)
            $messages = $messages->sortByDesc(function($message) {
                return $message->getDate();  // Ordena por la fecha
            });
           
            $paginator = $messages->paginate($per_page = 10, $page = null, $page_name = 'page');

           /* $paginatedMessages = new LengthAwarePaginator(
                $currentItems,
                $messages->count(),
                $perPage,
                $currentPage,
                ['path' => $request->url()]
            );*/

            // Retorna la vista y le pasa la variable de mensajes
            return view('view-email', ["paginator"=>$paginator]);
        } catch (Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
       
    }
    public function outbox(Request $request)
    {
        try {
            // Selecciona la cuenta IMAP definida en config/imap.php (normalmente 'default')
            // $client = Client::account('default');
            // or create a new instance manually
            $page = (int) $request->get("page", 1);
            $cm = new ClientManager('../config/imap.php');
            $client = $cm->account('default');
            // Conecta al servidor IMAP
            $client->connect();

            // Selecciona la carpeta INBOX
           // $folders =  $client->getFolders();
           // dd($folders);
           // exit;
            $inbox = $client->getFolder('Sent');
            // Obtiene todos los mensajes. Puedes ajustar el criterio de búsqueda si lo deseas.
            $messages = $inbox->messages()->all()->setFetchBody(false)->limit(100)->get();

             // Ordena los mensajes por fecha de forma descendente (más reciente primero)
            $messages = $messages->sortByDesc(function($message) {
                return $message->getDate();  // Ordena por la fecha
            });
           
            $paginator = $messages->paginate($per_page = 10, $page = null, $page_name = 'page');

           /* $paginatedMessages = new LengthAwarePaginator(
                $currentItems,
                $messages->count(),
                $perPage,
                $currentPage,
                ['path' => $request->url()]
            );*/

            // Retorna la vista y le pasa la variable de mensajes
            return view('view-email-out', ["paginator"=>$paginator]);
        } catch (Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
       
    }
}
