<?php

namespace CreoCode\ContaoFormSubmissions\Classes;

use Contao\BackendModule;
use Contao\Input;
use Contao\StringUtil;
use Contao\Email;
use Contao\System;
use CreoCode\ContaoFormSubmissions\Model\FormSubmissionsModel;
use CreoCode\ContaoFormSubmissions\Model\FormSubmissionsDataModel;

/**
 * Class FormSubmissionsDataResend
 */
class FormSubmissionsDataResend extends BackendModule
{
	/**
	 * Template
	 * @var string
	 */
	protected $strTemplate = 'form_submissions_data_resend';

	/**
	 * Generate the module
	 */
	protected function compile(): void
	{
		$this->Template->from     = $GLOBALS['TL_ADMIN_EMAIL'] ?? '';
		$this->Template->fromName = $GLOBALS['TL_ADMIN_NAME']  ?? '';

		// ── POST: actually resend ─────────────────────────────────────────────
		$resendIdPost = (int) Input::post('resendForm');

		if ($resendIdPost > 0) {
			$this->Template->mode = 'post';

			// Validate CSRF token
			if (!$this->validateRequestToken()) {
				$this->Template->success = false;
				return;
			}

			$submission = FormSubmissionsModel::findById($resendIdPost);

			if ($submission === null) {
				$this->Template->success = false;
				return;
			}

			$submissionData = FormSubmissionsDataModel::findOneBy('pid', $submission->id);

			$this->Template->submission     = $submission->row();
			$this->Template->submissionData = $submissionData?->row() ?? [];

			// Sanitise POST fields: strip tags, validate e-mail format
			$from      = strip_tags((string) Input::post('from'));
			$fromName  = strip_tags((string) Input::post('fromName'));
			$recipient = strip_tags((string) Input::post('recipient'));
			$subject   = strip_tags((string) Input::post('subject'));

			if (!filter_var($from, FILTER_VALIDATE_EMAIL) || !filter_var($recipient, FILTER_VALIDATE_EMAIL)) {
				$this->Template->success = false;
				return;
			}

			$arrSubmitted = unserialize($submissionData?->arrSubmitted ?? '', ['allowed_classes' => false]);
			$arrLabels    = unserialize($submissionData?->arrLabels    ?? '', ['allowed_classes' => false]);
			$arrFields    = unserialize($submissionData?->arrFields    ?? '', ['allowed_classes' => false]);

			if (is_array($arrSubmitted) && is_array($arrLabels)) {
				$this->resendForm($arrSubmitted, $arrLabels, $arrFields, $from, $fromName, $recipient, $subject);
				$this->Template->success = true;
			} else {
				$this->Template->success = false;
			}

			return;
		}

		// ── GET: show confirmation form ───────────────────────────────────────
		$resendIdGet = (int) Input::get('resendForm');

		if ($resendIdGet > 0) {
			$this->Template->mode = 'confirm';

			$submission = FormSubmissionsModel::findById($resendIdGet);

			if ($submission === null) {
				return;
			}

			$submissionData = FormSubmissionsDataModel::findOneBy('pid', $submission->id);

			$this->Template->submission     = $submission->row();
			$this->Template->submissionData = $submissionData?->row() ?? [];
		}
	}

	/**
	 * Resend form data via e-mail.
	 */
	protected function resendForm(
		array  $arrSubmitted,
		array  $arrLabels,
		?array $arrFields,
		string $from,
		string $fromName,
		string $recipient,
		string $subject
	): void {
		$systemKeys = ['REQUEST_TOKEN', 'FORM_SUBMIT', 'MAX_FILE_SIZE', 'formatted_html', 'cc_save_submissions'];
		$message    = '';

		foreach ($arrSubmitted as $k => $v) {
			if ($k === 'cc' || in_array($k, $systemKeys, true)) {
				continue;
			}
			$v = StringUtil::deserialize($v);
			$message .= ($arrLabels[$k] ?? ucfirst($k)) . ': ' . (is_array($v) ? implode(', ', $v) : $v) . "\n";
		}

		$recipients = StringUtil::splitCsv($recipient);
		foreach ($recipients as $k => $v) {
			$recipients[$k] = str_replace(['[', ']', '"'], ['<', '>', ''], $v);
		}

		$email           = new Email();
		$email->from     = $from;
		$email->fromName = $fromName ?: ($GLOBALS['TL_ADMIN_NAME'] ?? '');
		$email->subject  = $subject ?: 'No subject';
		$email->text     = StringUtil::decodeEntities(trim($message)) . "\n\n";

		try {
			$email->sendTo($recipients);
			System::getContainer()->get('monolog.logger.contao.forms')->info(
				'Form submission has been resent via backend.'
			);
		} catch (\Exception $e) {
			System::getContainer()->get('monolog.logger.contao.forms')->error(
				'Form submission resend failed: ' . $e->getMessage()
			);
			throw $e;
		}
	}
}
