<?php
declare(strict_types=1);

namespace App\Controller;

use Cake\Core\Configure;
use Cake\Http\Client;
use Cake\Http\Response;
use Cake\Log\Log;
use Cake\Mailer\Mailer;
use Cake\ORM\TableRegistry;
use Throwable;

class TeacherApplicationsController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();
        $this->FormProtection->setConfig('unlockedFields', ['cf-turnstile-response', 'website']);
    }

    public function add(): ?Response
    {
        $applications = TableRegistry::getTableLocator()->get('TeacherApplications');
        $application = $applications->newEmptyEntity();

        if ($this->request->is('post')) {
            $data = $this->request->getData();
            $turnstileToken = trim((string)($data['cf-turnstile-response'] ?? ''));
            $honeypotValue = trim((string)($data['website'] ?? ''));
            unset($data['cf-turnstile-response'], $data['website']);

            $application = $applications->patchEntity($application, $data);

            if ($honeypotValue !== '') {
                $application->setError('turnstile', ['Please review your submission and try again.']);
                $this->Flash->error('Please review your submission and try again.');
            } else {
                [$verified, $verifyMsg] = $this->verifyTurnstile($turnstileToken);
                if (!$verified) {
                    $msg = $verifyMsg ?? 'Security verification failed. Please try again.';
                    $application->setError('turnstile', [$msg]);
                    $this->Flash->error($msg);
                } elseif ($applications->save($application)) {
                    $this->sendApplicationConfirmation($application);
                    $this->Flash->success("Thanks — we've got your application. We'll be in touch within a week.");
                    return $this->redirect(['action' => 'success']);
                } else {
                    $this->Flash->error('Your application could not be sent. Please correct the highlighted fields.');
                }
            }
        }

        $craftOptions = [
            'pottery' => 'Pottery',
            'knitting' => 'Knitting',
            'both' => 'Both',
        ];
        $turnstileSiteKey = (string)Configure::read('Turnstile.siteKey');
        $this->set(compact('application', 'craftOptions', 'turnstileSiteKey'));
        return null;
    }

    public function success(): void
    {
    }

    private function sendApplicationConfirmation($application): void
    {
        try {
            $mailer = new Mailer('default');
            $mailer
                ->setEmailFormat('text')
                ->setTo($application->email, $application->full_name)
                ->setFrom(['hello@candlecraft.local' => 'CandleCraft Academy'])
                ->setSubject('We received your teaching application · CandleCraft Academy')
                ->deliver(
                    "Hi {$application->full_name},\n\n" .
                    "Thank you for applying to teach at CandleCraft Academy. A real person will read your application within a week and reply directly.\n\n" .
                    "We received:\n" .
                    "- Craft: " . ucwords(str_replace('_', ' ', (string)$application->craft)) . "\n" .
                    ($application->years_experience ? "- Years of experience: {$application->years_experience}\n" : '') .
                    "\nWarm regards,\nCandleCraft Academy"
                );
        } catch (Throwable $e) {
            Log::warning('Teacher application confirmation email failed: ' . $e->getMessage());
        }
    }

    /**
     * @return array{0: bool, 1: string|null}
     */
    private function verifyTurnstile(string $token): array
    {
        if ((bool)Configure::read('Turnstile.skipVerification', false)) {
            return [true, null];
        }
        if ($token === '') {
            return [false, 'Please complete the security check before submitting your application.'];
        }
        $secret = (string)Configure::read('Turnstile.secretKey');
        $url = (string)Configure::read('Turnstile.verifyUrl');
        if ($secret === '' || $url === '') {
            return [false, 'Security verification is unavailable right now. Please try again shortly.'];
        }

        try {
            $http = new Client(['timeout' => 8]);
            $resp = $http->post($url, [
                'secret' => $secret,
                'response' => $token,
                'remoteip' => (string)$this->request->clientIp(),
            ], ['type' => 'form']);
        } catch (Throwable) {
            return [false, 'Security verification could not be completed. Please try again.'];
        }
        if (!$resp->isOk()) {
            return [false, 'Security verification could not be completed. Please try again.'];
        }
        $payload = $resp->getJson();
        if (!is_array($payload) || empty($payload['success'])) {
            return [false, 'Security verification failed. Please refresh and try again.'];
        }
        return [true, null];
    }
}
