<?php
declare(strict_types=1);

namespace App\Controller\Admin;

use Cake\Http\Response;
use Cake\Log\Log;
use Cake\Mailer\Mailer;
use Cake\ORM\TableRegistry;
use Cake\Utility\Text;
use Throwable;

class TeacherApplicationsController extends AdminAppController
{
    public function index(): void
    {
        $applications = TableRegistry::getTableLocator()->get('TeacherApplications');
        $query = $applications->find()->orderBy(['created' => 'DESC']);

        $status = trim((string)$this->request->getQuery('status'));
        if ($status !== '') {
            $query->where(['status' => $status]);
        }

        $this->paginate = ['limit' => 25];
        $rows = $this->paginate($query);

        $metrics = [
            'total' => $applications->find()->count(),
            'new' => $applications->find()->where(['status' => 'new'])->count(),
            'reviewing' => $applications->find()->where(['status' => 'reviewing'])->count(),
            'approved' => $applications->find()->where(['status' => 'approved'])->count(),
            'rejected' => $applications->find()->where(['status' => 'rejected'])->count(),
        ];

        $this->set(compact('rows', 'metrics', 'status'));
    }

    public function view(int $id): ?Response
    {
        $applications = TableRegistry::getTableLocator()->get('TeacherApplications');
        $application = $applications->get($id, contain: ['Teachers']);

        if ($this->request->is(['post', 'put', 'patch'])) {
            $action = (string)$this->request->getData('action', 'update');

            if ($action === 'approve') {
                $teacherId = $this->promoteToTeacher($application);
                if ($teacherId !== null) {
                    $application->status = 'approved';
                    $application->promoted_teacher_id = $teacherId;
                    $application->reviewed_by_admin_user_id = $this->adminId();
                    $applications->save($application);
                    $this->sendApplicationDecision($application, true);
                    $this->Flash->success('Application approved and teacher created.');
                    return $this->redirect(['action' => 'view', $id]);
                }
                $this->Flash->error('Could not promote application — please check the details.');
            } elseif ($action === 'reject') {
                $application->status = 'rejected';
                $application->reviewed_by_admin_user_id = $this->adminId();
                $applications->save($application);
                $this->sendApplicationDecision($application, false);
                $this->Flash->success('Application marked as rejected.');
                return $this->redirect(['action' => 'view', $id]);
            } else {
                $data = $this->request->getData();
                $data['reviewed_by_admin_user_id'] = $this->adminId();
                $application = $applications->patchEntity($application, $data, [
                    'fields' => ['status', 'admin_notes', 'reviewed_by_admin_user_id'],
                ]);
                if ($applications->save($application)) {
                    $this->Flash->success('Application updated.');
                    return $this->redirect(['action' => 'view', $id]);
                }
                $this->Flash->error('Could not update.');
            }
        }

        $this->set(compact('application'));
        return null;
    }

    private function promoteToTeacher($application): ?int
    {
        $teachers = TableRegistry::getTableLocator()->get('Teachers');

        $slug = Text::slug(strtolower((string)$application->full_name), '-');
        $base = $slug;
        $suffix = 1;
        while ($teachers->exists(['slug' => $slug])) {
            $slug = $base . '-' . (++$suffix);
        }

        $craftLabel = match ((string)$application->craft) {
            'pottery' => 'Pottery · New instructor',
            'knitting' => 'Knitting · New instructor',
            'both' => 'Pottery & knitting',
            default => 'Instructor',
        };

        $teacher = $teachers->newEntity([
            'slug' => $slug,
            'full_name' => (string)$application->full_name,
            'role' => $craftLabel,
            'bio' => (string)$application->about,
            'specialties' => (string)($application->specialties ?? ''),
            'photo_path' => null,
            'hourly_rate_cents' => 6500,
            'is_active' => true,
            'sort_order' => 100,
        ]);
        if ($teachers->save($teacher)) {
            return (int)$teacher->id;
        }
        return null;
    }

    private function sendApplicationDecision($application, bool $approved): void
    {
        try {
            $mailer = new Mailer('default');
            $mailer
                ->setEmailFormat('text')
                ->setTo($application->email, $application->full_name)
                ->setFrom(['hello@candlecraft.local' => 'CandleCraft Academy'])
                ->setSubject($approved
                    ? 'Welcome to CandleCraft — your application is approved'
                    : 'Update on your CandleCraft teaching application')
                ->deliver(
                    $approved
                        ? "Hi {$application->full_name},\n\nThank you for applying to teach at CandleCraft Academy. We'd love to have you on board. We'll follow up shortly with onboarding details, including how to set your availability and rates.\n\n— CandleCraft Academy"
                        : "Hi {$application->full_name},\n\nThank you for applying. We're not able to bring you on right now, but we appreciate the time you took to share your work.\n\n— CandleCraft Academy"
                );
        } catch (Throwable $e) {
            Log::warning('Application decision email failed: ' . $e->getMessage());
        }
    }
}
