<?php


namespace WPIS;

use WPIS\ImmosyncClient;

class FormManager {

    private $errors = [];
    private $payload = [];
    private $formdata = [];

    private $contactSavingEnabled = true;
    private $emailRecipientEnabled = true;
    private $emailClientEnabled = true;
    private $emailDefaultSender;
    private $emailDefaultSenderName;
    private $emailDefaultReceiver;

	static public function init() {
        $class = new self();

        DatabaseManager::createContactTable();

        $class->contactSavingEnabled = SettingsManager::get('formEnableContactSaving');
        $class->emailRecipientEnabled = SettingsManager::get('formEnableRecipientEmail');
        $class->emailClientEnabled = SettingsManager::get('formEnableClientEmail');
        $class->emailDefaultSender = SettingsManager::get('formEmailDefaultSender') ?? get_bloginfo('admin_email');
        $class->emailDefaultSenderName = SettingsManager::get('formEmailDefaultSenderName') ?? get_bloginfo('name');
        $class->emailDefaultReceiver = SettingsManager::get('formEmailDefaultReceiver') ?? get_bloginfo('admin_email');

        if( $class->emailRecipientEnabled || $class->emailClientEnabled ){
            add_filter( 'wp_mail_content_type', [$class, 'setEmailContentType']);
        }

        return $class;
    }

    public function handleFormData($payload){

        $this->payload = $payload;

        $this->checkPayload();

        if( !empty($this->errors) ){
            return [
                'success' => false,
                'errors' => $this->errors
            ];
        }

        $this->createFormData();

        $contactId = null;

        if( $this->contactSavingEnabled ){
           $contactId = $this->saveContact();
        }

        $emailRecipientSent = $this->sendRecipientEmail();
        $emailNotificationSent = $this->sendClientEmail();

        $this->updateContactSoftwareId($contactId, [
            'email_recipient' => $emailRecipientSent,
            'email_notification' => $emailNotificationSent,
        ]);

        return [
            'success' => 'true',
            'flow' => [
                'emailRecipientSent' => $emailRecipientSent,
                'emailNotificationSent' => $emailNotificationSent
            ]
        ];
    }

    public function handleContactSync(){

        $wpdb = DatabaseManager::db();
        $table = $wpdb->prefix . WPIS::WP_TABLE_CONTACTS;

        $query = $wpdb->prepare( "SELECT id, software_contact_id, form_data  FROM $table ORDER BY created_at DESC LIMIT 1");
        $contact = $wpdb->get_row($query);

        if( !empty($contact) && is_null($contact->software_contact_id) ){

            $this->formdata = json_decode($contact->form_data);

            $immoSyncDataSent = $this->sendFormDataImmoSync();

            if( ! isset($immoSyncDataSent->success) || ! $immoSyncDataSent->success ){

                $this->sendFailedSyncEmail($immoSyncDataSent);

                return [
                    'success' => 'false',
                ];
            }

            $this->updateContactSoftwareId($contact->id, [
                'software_contact_id' => $immoSyncDataSent->contactId,
            ]);

            return [
                'success' => 'true',
            ];
        }
        else {
            return [
                'success' => 'true',
            ];
        }
    }

    private function checkPayload(){

        $acceptedSource = ['searchForm', 'contactForm', 'estateForm', 'evaluationForm'];
        $payload = (object) $this->payload;

        if( !isset($payload->source) || !in_array($payload->source, $acceptedSource) ){
            $this->errors[]= ['field' => 'source', 'message' => __('Source is not valid, valid source are: ', 'wpis') . implode(', ', $acceptedSource) ];
            return;
        }

        if( !isset($payload->message) || $payload->message === '' || !$payload->message || strlen($payload->message) > 1000 ){
            $this->errors[]= ['field' => 'message', 'message' => __('Message could not be null and should be maximum 1000 characters', 'wpis')];
            return;
        }
    }

    private function createFormData(){

        $payload = (object) $this->payload;

        // TODO : Update the logic
        $searchZips = [];
        foreach( [1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25] as $zipKey ){
            if( isset($payload->{'searchZipCode' . $zipKey}) && $payload->{'searchZipCode' . $zipKey}){
                $searchZips[] = $payload->{'searchZipCode' . $zipKey};
            }
        }

        $gender = trim(strip_tags($payload->gender));
        $gender = $gender !== 'none' ? $gender : null;

        $input = [
            'source'    => $payload->source,
            'url'       => $payload->url,

            'firstname' => trim(strip_tags($payload->firstname)),
            'lastname'  => trim(strip_tags($payload->lastname)),
            'gender'    => $gender,
            'phone'     => trim(strip_tags($payload->phone)),
            'email'     => trim(strip_tags($payload->email)),

            'agreement' => isset($payload->agreement) && $payload->agreement,

            'addressNumber' =>  trim(strip_tags($payload->addressNumber)),
            'addressZip'    =>  trim(strip_tags($payload->addressZip)),
            'addressStreet' =>  trim(strip_tags($payload->addressStreet)),
            'addressCity'   =>  trim(strip_tags($payload->addressCity)),
            'addressBox'    =>  trim(strip_tags($payload->addressBox)),

            'message' => trim(strip_tags($payload->message))
        ];

        if( $payload->officeId ){
            $input['officeId'] = $payload->officeId;
        }

        if( $payload->source === 'searchForm' ){
            $search = (object) $payload->search;
            $input['search'] = [
                'purpose'    => $search->purpose,
                'category'   => $search->category,
                'priceRange' => [$search->priceRange[0], $search->priceRange[1]],
                'rooms'      => $search->rooms,
                'areaMin'    => $search->areaMin,
                'areaMax'    => $search->areaMax,
                'zips'       => $search->zips
            ];
        }

        if( $payload->source === 'estateForm' ){
            $input['estateId'] = $payload->estateId;
            $input['postId'] = $payload->postId;
        }

        $this->formdata = $input;
    }

    private function saveContact(){

        $wpdb = DatabaseManager::db();
        $table = $wpdb->prefix . WPIS::WP_TABLE_CONTACTS;

        $contact = [
            'source' => $this->formdata['source'],
            'firstname' => $this->formdata['firstname'],
            'lastname' => $this->formdata['lastname'],
            'email' => $this->formdata['email'],
            'form_data' => json_encode($this->formdata),
            'email_recipient' => false,
            'email_notification' => false,
            'software_contact_id' => null
        ];

        $wpdb->insert($table, $contact);

        return $wpdb->insert_id;
    }

    private function updateContactSoftwareId($contactId, $data){

        $wpdb = DatabaseManager::db();
        $table = $wpdb->prefix . WPIS::WP_TABLE_CONTACTS;

        $wpdb->update( $table, $data, ['ID' => $contactId ] );
    }

    public function getSavedContacts(){

        $wpdb = DatabaseManager::db();
        $table = $wpdb->prefix . WPIS::WP_TABLE_CONTACTS;

        $contacts = $wpdb->get_results("SELECT * FROM $table");
        $contactMapped = [];

        foreach($contacts as $contact){
            $contact->form_data = json_decode($contact->form_data);
            $contactMapped[] = $contact;
        }

        return [
            'success' => true,
            'data' => $contactMapped,
            'total' => count($contacts)
        ];
    }

    private function sendFormDataImmoSync(){
        return ImmosyncClient::init()->createContact((object) $this->formdata);
    }

    private function sendRecipientEmail(){

        if( ! $this->emailRecipientEnabled ){
            return false;
        }

        $template = file_get_contents(__DIR__ . '/../templates/email/default.email.html');
        $template = str_replace(["\r", "\n"], '', $template);
        $recipient = $this->formdata['email'];
        $headers = [
            'From: '. $this->emailDefaultSenderName . ' <' . $this->emailDefaultSender . '>'
        ];
        $subject = '[' . get_bloginfo('name') . ']' . ' Nous avons bien reçu votre message';

        $headline = 'Bonjour ' . $this->formdata['firstname'];
        $message = 'Nous avons bien reçu votre message, nous vous répondrons dans les plus brefs délais.';
        $message .= '<h3>Résumé des informations envoyées :</h3>';

        $message .= '<b>Nom :</b> ' . $this->formdata['firstname'];
        $message .= "\n" . '<b>Prénom :</b> ' . $this->formdata['lastname'];
        $message .= "\n" . '<b>Email :</b> ' . $this->formdata['email'];
        $message .= "\n" . '<b>Téléphone :</b> ' . $this->formdata['phone'];

        if( isset($this->formdata['addressStreet']) && $this->formdata['addressStreet'] !== '' ){
            $message .= "\n" . '<b>Rue :</b> ' . $this->formdata['addressStreet'];
            $message .= "\n" . '<b>Numéro :</b> ' . $this->formdata['addressNumber'];
            $message .= "\n" . '<b>Boite :</b> ' . $this->formdata['addressBox'];
            $message .= "\n" . '<b>Code postal :</b> ' . $this->formdata['addressZip'];
            $message .= "\n" . '<b>Ville :</b> ' . $this->formdata['addressCity'];
        }

        $message .= "\n";
        $message .= "\n" . '<b>Message :</b> ' . $this->formdata['message'];

        if( $this->formdata['source'] === 'searchForm' ){
            $message .= "\n";
            $message .= "\n" . '<b>Recherche</b> ';
            $message .= "\n";
            $message .= "\n" . '<b>Type :</b> ' . $this->formdata['search']['purpose'];
            $message .= "\n" . '<b>Catégorie :</b> ' . $this->formdata['search']['category'];
            $message .= "\n" . '<b>Tranche de prix :</b> de ' . $this->formdata['search']['priceRange'][0] . ' à ' . $this->formdata['search']['priceRange'][1];
            $message .= "\n" . '<b>Nombre de pièce :</b> ' . $this->formdata['search']['rooms'];
            $message .= "\n" . '<b>Surface minimale :</b> ' . $this->formdata['search']['areaMin'];
            $message .= "\n" . '<b>Surface maximale :</b> ' . $this->formdata['search']['areaMax'];
            $message .= "\n" . '<b>Région :</b> ' . implode(', ', $this->formdata['search']['zips']);
        }

        if( $this->formdata['source'] === 'estateForm' ){
            $message .= "\n";
            $message .= "\n" . '<b>Contact pour le bien :</b> ';
            $message .= "\n";
            $message .= "\n" . '<b>Id :</b> ' . $this->formdata['estateId'];
            $message .= "\n" . '<b>Reference :</b> ' . $this->getEstateMeta( $this->formdata['postId'], 'wpis_reference');
            $message .= "\n" . '<b>Name :</b> ' . $this->getEstateMeta($this->formdata['postId'], 'wpis_name');
        }

        $signature = 'L\'équipe de ' . get_bloginfo('name');
        $footer = 'Ceci est un message automatique envoyé via ImmoSync';

        $template = str_replace(
            ['{{ email.headline }}', '{{ email.message }}', '{{ email.signature }}', '{{ email.footer }}'],
            [$headline, $message, $signature, $footer],
            $template
        );

        $body = wpautop($template);

        return wp_mail($recipient, $subject, $body, $headers);
    }

    private function sendClientEmail(){
        if( ! $this->emailClientEnabled ){
            return false;
        }

        $template = file_get_contents(__DIR__ . '/../templates/email/default.email.html');
        $template = str_replace(["\r", "\n"], '', $template);
        $recipient = $this->emailDefaultReceiver;
        $headers = [
            'From: '. $this->emailDefaultSenderName . ' <' . $this->emailDefaultSender . '>'
        ];
        $subject = '[WP Immo Sync]' . ' Nouveau message reçu';

        $headline = 'Bonjour';
        $signature = 'Formulaire ' . get_bloginfo('name');
        $footer = 'Ceci est un message automatique envoyé via ImmoSync';

        $message = 'Vous avez reçu un nouveau message via un formulaire ImmoSync :';
        $message .= "\n";
        $message .= "\n" . '<b>Formulaire :</b> ' . $this->formdata['source'];
        $message .= "\n" . '<b>Page source :</b> ' . $this->formdata['url'];
        $message .= "\n";
        $message .= "\n" . '<b>Nom :</b> ' . $this->formdata['firstname'];
        $message .= "\n" . '<b>Prénom :</b> ' . $this->formdata['lastname'];
        $message .= "\n" . '<b>Email :</b> ' . $this->formdata['email'];
        $message .= "\n" . '<b>Téléphone :</b> ' . $this->formdata['phone'];
        $message .= "\n";

        if( isset($this->formdata['addressStreet']) && $this->formdata['addressStreet'] !== '' ){
            $message .= "\n" . '<b>Rue :</b> ' . $this->formdata['addressStreet'];
            $message .= "\n" . '<b>Numéro :</b> ' . $this->formdata['addressNumber'];
            $message .= "\n" . '<b>Boite :</b> ' . $this->formdata['addressBox'];
            $message .= "\n" . '<b>Code postal :</b> ' . $this->formdata['addressZip'];
            $message .= "\n" . '<b>Ville :</b> ' . $this->formdata['addressCity'];
        }

        $message .= "\n";
        $message .= "\n" . '<b>Message :</b> ' . $this->formdata['message'];

        if( $this->formdata['source'] === 'searchForm' ){
            $message .= "\n";
            $message .= "\n" . '<b>Recherche</b> ';
            $message .= "\n";
            $message .= "\n" . '<b>Type :</b> ' . $this->formdata['search']['purpose'];
            $message .= "\n" . '<b>Catégorie :</b> ' . $this->formdata['search']['category'];
            $message .= "\n" . '<b>Tranche de prix :</b> de ' . $this->formdata['search']['priceRange'][0] . ' à ' . $this->formdata['search']['priceRange'][1];
            $message .= "\n" . '<b>Nombre de pièce :</b> ' . $this->formdata['search']['rooms'];
            $message .= "\n" . '<b>Surface minimale :</b> ' . $this->formdata['search']['areaMin'];
            $message .= "\n" . '<b>Surface maximale :</b> ' . $this->formdata['search']['areaMax'];
            $message .= "\n" . '<b>Région :</b> ' . implode(', ', $this->formdata['search']['zips']);
        }

        if( $this->formdata['source'] === 'estateForm' ){
            $message .= "\n";
            $message .= "\n" . '<b>Contact pour le bien :</b> ';
            $message .= "\n";
            $message .= "\n" . '<b>Id :</b> ' . $this->formdata['estateId'];
            $message .= "\n" . '<b>Reference :</b> ' . $this->getEstateMeta( $this->formdata['postId'], 'wpis_reference');
            $message .= "\n" . '<b>Name :</b> ' . $this->getEstateMeta($this->formdata['postId'], 'wpis_name');
        }

        $template = str_replace(
            ['{{ email.headline }}', '{{ email.message }}', '{{ email.signature }}', '{{ email.footer }}'],
            [$headline, $message, $signature, $footer],
            $template
        );

        $body = wpautop($template);

        return wp_mail($recipient, $subject, $body, $headers);
    }

    private function sendFailedSyncEmail( $errorImmoSyncData ){

        $template = file_get_contents(__DIR__ . '/../templates/email/default.email.html');
        $template = str_replace(["\r", "\n"], '', $template);
        $headers = [
            'From: '. $this->emailDefaultSenderName . ' <' . $this->emailDefaultSender . '>'
        ];
        $recipients = [WPIS::EMAIL_CONTACT_FAILURE, get_bloginfo('admin_email')];
        $this->formdata = (array) $this->formdata;

        $subject = '[WP Immo Sync] ' . get_bloginfo('name') . ' - Contact non synchronisé avec le logiciel';

        $headline = 'Bonjour';
        $signature = 'Systeme de synchronisation ImmoSync de ' . get_bloginfo('name');
        $footer = 'Ceci est un message automatique envoyé via ImmoSync';
        $message = 'Un Contact ne s\'est pas synchronisé avec le logiciel immobilier';
        $message .= "\n";
        $message .= "\n" . '<b style="color:#fa8072;">Données du contact :</b> ';
        $message .= "\n";
        $message .= "\n" . '<b>Formulaire :</b> ' . $this->formdata['source'];
        $message .= "\n" . '<b>Page source :</b> ' . $this->formdata['url'];
        $message .= "\n";
        $message .= "\n" . '<b>Nom :</b> ' . $this->formdata['firstname'];
        $message .= "\n" . '<b>Prénom :</b> ' . $this->formdata['lastname'];
        $message .= "\n" . '<b>Email :</b> ' . $this->formdata['email'];
        $message .= "\n" . '<b>Téléphone :</b> ' . $this->formdata['phone'];
        $message .= "\n";

        if( isset($this->formdata['addressStreet']) && $this->formdata['addressStreet'] !== '' ){
            $message .= "\n" . '<b>Rue :</b> ' . $this->formdata['addressStreet'];
            $message .= "\n" . '<b>Numéro :</b> ' . $this->formdata['addressNumber'];
            $message .= "\n" . '<b>Boite :</b> ' . $this->formdata['addressBox'];
            $message .= "\n" . '<b>Code postal :</b> ' . $this->formdata['addressZip'];
            $message .= "\n" . '<b>Ville :</b> ' . $this->formdata['addressCity'];
        }

        $message .= "\n" . '<b>Message :</b> ' . $this->formdata['message'];

        if( $this->formdata['source'] === 'searchForm' ){
            $message .= "\n";
            $message .= "\n" . '<b>Recherche</b> ';
            $message .= "\n";
            $message .= "\n" . '<b>Type :</b> ' . $this->formdata['search']['purpose'];
            $message .= "\n" . '<b>Catégorie :</b> ' . $this->formdata['search']['category'];
            $message .= "\n" . '<b>Tranche de prix :</b> de ' . $this->formdata['search']['priceRange'][0] . ' à ' . $this->formdata['search']['priceRange'][1];
            $message .= "\n" . '<b>Nombre de pièce :</b> ' . $this->formdata['search']['rooms'];
            $message .= "\n" . '<b>Surface minimale :</b> ' . $this->formdata['search']['areaMin'];
            $message .= "\n" . '<b>Surface maximale :</b> ' . $this->formdata['search']['areaMax'];
            $message .= "\n" . '<b>Région :</b> ' . implode(', ', $this->formdata['search']['zips']);
        }

        if( $this->formdata['source'] === 'estateForm' ){
            $message .= "\n";
            $message .= "\n" . '<b>Contact pour le bien :</b> ';
            $message .= "\n";
            $message .= "\n" . '<b>Id :</b> ' . $this->formdata['estateId'];
            $message .= "\n" . '<b>Reference :</b> ' . $this->getEstateMeta( $this->formdata['postId'], 'wpis_reference');
            $message .= "\n" . '<b>Name :</b> ' . $this->getEstateMeta($this->formdata['postId'], 'wpis_name');
        }

        $message .= "\n";
        $message .= "\n" . '<b style="color:#fa8072;">Message d\'erreur :</b> ';
        $message .= "\n";
        $message .= "\n" . '<code>' . json_encode($errorImmoSyncData) . '</code>';

        $template = str_replace(
            ['{{ email.headline }}', '{{ email.message }}', '{{ email.signature }}', '{{ email.footer }}'],
            [$headline, $message, $signature, $footer],
            $template
        );

        $body = wpautop($template);

        return wp_mail($recipients, $subject, $body, $headers);
    }

    private function getEstateMeta($postId, $meta) {
        return get_post_meta($postId, $meta, true);
    }

    public function setEmailContentType(){
        return 'text/html';
    }
}
