<?php
namespace App\Controllers;

use App\Core\Auth;
use App\Core\Controller;
use App\Core\Csrf;
use App\Core\Permission;
use App\Models\Communication;
use App\Services\CommunicationRecipientResolver;
use App\Services\CommunicationMailer;
use Throwable;

final class CommunicationController extends Controller
{
    public function index(): void
    {
        Auth::requireLogin();
        Permission::require('communications.view');

        $this->view('communications/index',[
            'pageTitle'=>'Communications',
            'campaigns'=>Communication::campaigns(),
        ]);
    }

    public function create(): void
    {
        Auth::requireLogin();
        Permission::require('communications.create');

        $this->view('communications/form',[
            'pageTitle'=>'Nouvelle communication',
            'templates'=>Communication::templates(),
        ]);
    }

    public function store(): void
    {
        Auth::requireLogin();
        Permission::require('communications.create');
        Csrf::verify($_POST['_csrf'] ?? null);

        $id=Communication::createCampaign([
            'organisation_id'=>(int)(Auth::user()['organisation_id'] ?? 1),
            'modele_id'=>(int)($_POST['modele_id'] ?? 0) ?: null,
            'libelle'=>trim((string)$_POST['libelle']),
            'objet'=>trim((string)$_POST['objet']),
            'corps_html'=>(string)$_POST['corps_html'],
            'corps_texte'=>trim((string)($_POST['corps_texte'] ?? '')) ?: null,
            'cible_type'=>(string)$_POST['cible_type'],
            'cible_id'=>(int)($_POST['cible_id'] ?? 0) ?: null,
            'created_by'=>(int)(Auth::user()['id'] ?? 0) ?: null,
        ]);

        $selection=[];

        if(!empty($_POST['email_individuel'])){
            $selection[]=[
                'source_type'=>'manuel',
                'source_id'=>null,
                'nom'=>trim((string)($_POST['nom_individuel'] ?? '')),
                'email'=>trim((string)$_POST['email_individuel']),
            ];
        }

        $recipients=(new CommunicationRecipientResolver())->resolve(
            (string)$_POST['cible_type'],
            (int)($_POST['cible_id'] ?? 0) ?: null,
            $selection
        );

        Communication::replaceRecipients($id,$recipients);

        $_SESSION['success']=
            'La communication a été préparée. Vérifiez les destinataires avant validation.';

        $this->redirect('/communications/voir?id='.$id);
    }

    public function show(): void
    {
        Auth::requireLogin();
        Permission::require('communications.view');

        $campaign=Communication::findCampaign(
            (int)($_GET['id'] ?? 0)
        );

        if(!$campaign){
            http_response_code(404);
            exit('Communication introuvable.');
        }

        $this->view('communications/show',[
            'pageTitle'=>'Aperçu de la communication',
            'campaign'=>$campaign,
            'recipients'=>Communication::recipients(
                (int)$campaign['id']
            ),
        ]);
    }

    public function validate(): void
    {
        Auth::requireLogin();
        Permission::require('communications.validate');
        Csrf::verify($_POST['_csrf'] ?? null);

        Communication::markValidated(
            (int)$_POST['id'],
            (int)(Auth::user()['id'] ?? 0)
        );

        $_SESSION['success']='La campagne est validée.';
        $this->redirect('/communications/voir?id='.(int)$_POST['id']);
    }

    public function send(): void
    {
        Auth::requireLogin();
        Permission::require('communications.send.group');
        Csrf::verify($_POST['_csrf'] ?? null);

        $id=(int)$_POST['id'];
        $campaign=Communication::findCampaign($id);

        if(!$campaign || $campaign['statut']!=='validee'){
            $_SESSION['error']='La campagne doit être validée avant envoi.';
            $this->redirect('/communications/voir?id='.$id);
            return;
        }

        $mailer=new CommunicationMailer();

        foreach(Communication::pendingRecipients($id) as $recipient){
            try{
                $html=str_replace(
                    ['{{nom_destinataire}}'],
                    [(string)$recipient['nom_destinataire']],
                    (string)$campaign['corps_html']
                );

                $mailer->send(
                    (string)$recipient['email_destinataire'],
                    (string)$campaign['objet'],
                    $html,
                    $campaign['corps_texte']
                );

                Communication::markRecipient(
                    (int)$recipient['id'],
                    'envoye'
                );
            }catch(Throwable $error){
                Communication::markRecipient(
                    (int)$recipient['id'],
                    'echec',
                    $error->getMessage()
                );
            }
        }

        Communication::finishCampaign($id);

        $_SESSION['success']='La campagne a été traitée.';
        $this->redirect('/communications/voir?id='.$id);
    }
}
