<?php

namespace App\Console\Commands;

use App\Mail\Difusion\DifusionMail;
use App\Models\Difusion;
use App\Models\DifusionModulos;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Symfony\Component\Mailer\Exception\TransportException;

class EnviarCorreos extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'difundir-correos';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle(): void
    {
        $limit_span = 10;
        $limit_intentos = 3;

        //Hacemos esto por lista de difusion
        $difusion = Difusion::where('enviar', true)
            ->where('completado', false)
            ->orderBy('updated_at', 'asc')
            ->first();

        if (!$difusion)
            return;

        //Traemos los modulos para generar si existen
        $modulos = DifusionModulos::where('difusion_id', $difusion->id)
            ->get();

        $mostrar = [];

        foreach ($modulos as $item) {
            $class = $item->modulo_type;
            $data = new $class;
            $data = $data->where('id', $item->modulo_id)
                ->first();
            if ($data) {
                $data->enlace = $data->enlace();
                $data->imagen = $data->imagen('large');
                $data->descripcion = limitar_cadena(htmlToPlainText($data->descripcion), 200);
                $mostrar[] = $data;
            }
        }
        $modulos = $mostrar;

        //Generamos un listado de correo
        $correos = DB::table('listas_difusion as ld')
            ->join('difusiones_listas_difusion as dld', 'dld.lista_difusion_id', 'ld.id')
            ->where('dld.difusion_id', $difusion->id)
            //->where('estado', true)
            ->where('enviado', false)
            ->where('cancelado', false)
            ->select(
                'dld.id',
                'ld.nombres',
                'ld.apellidos',
                'ld.nombres_apellidos',
                'ld.correo',
                'ld.estado',
                'dld.enviado',
                'dld.intento',
                'dld.cancelado',
                'dld.lista_difusion_id'
            )
            ->limit($limit_span)
            ->get();

        //?Si no tenemos correos marcamos como operación concluida
        if (!sizeof($correos)) {
            $difusion->update([
                'completado' => true
            ]);
            return;
        }
        //dd($modulos->toArray());
        foreach ($correos as $item) {
            //? CANCELAR => en caso de que sea suscriptor inactivo
            if (!$item->estado) {
                DB::table('difusiones_listas_difusion')
                    ->where('id', $item->id)
                    ->update([
                        'cancelado' => true
                    ]);
                continue;
            }

            $enviado = $this->sendCorreo($item, $modulos, $difusion);

            if ($enviado) {
                DB::table('difusiones_listas_difusion')
                    ->where('id', $item->id)
                    ->update([
                        'enviado' => true
                    ]);
            } else {
                //? CANCELAR => cancelar si excede el limite de intentos
                $cancelar = $item->intento < $limit_intentos;
                DB::table('difusiones_listas_difusion')
                    ->where('id', $item->id)
                    ->update([
                        'intento' => $item->intento + 1,
                        'cancelar' => $cancelar
                    ]);
            }
        }
    }

    private function sendCorreo($data, $modulos, $difusion)
    {
        $data->internas = $modulos;
        $data->difusion = $difusion;
        $correo = $data->correo;

        Log::info("==============================================");
        Log::info("Enviando correo a $correo");
        try {
            Mail::to($correo)->send(new DifusionMail($data));
            return true;
        } catch (TransportException $e) {
            $errorMessage = $e->getMessage();
            Log::error($errorMessage);
        }
        return false;
    }
}
