<?php
declare(strict_types=1);

namespace App\Controller\Admin;

use App\Mailer\ContactMailer;
use App\Model\Table\ContactMessagesTable;
use Cake\Http\Response;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
use Throwable;

class ContactMessagesController extends AdminAppController
{
    protected ContactMessagesTable $ContactMessages;

    public function initialize(): void
    {
        parent::initialize();
        $this->ContactMessages = TableRegistry::getTableLocator()->get('ContactMessages');
    }

    public function index(): void
    {
        $query = $this->ContactMessages->find()
            ->contain(['AdminUsers'])
            ->orderBy(['ContactMessages.created' => 'DESC']);

        $status = trim((string)$this->request->getQuery('status'));
        $interest = trim((string)$this->request->getQuery('interest'));
        $search = trim((string)$this->request->getQuery('q'));

        if ($status !== '') {
            $query->where(['ContactMessages.status' => $status]);
        }

        if ($interest !== '') {
            $query->where(['ContactMessages.interest_area' => $interest]);
        }

        if ($search !== '') {
            $query->where([
                'OR' => [
                    'ContactMessages.full_name LIKE' => '%' . $search . '%',
                    'ContactMessages.email LIKE' => '%' . $search . '%',
                    'ContactMessages.subject LIKE' => '%' . $search . '%',
                    'ContactMessages.message_body LIKE' => '%' . $search . '%',
                ],
            ]);
        }

        $statusOptions = [
            'new' => 'New',
            'in_progress' => 'In progress',
            'resolved' => 'Resolved',
            'spam' => 'Spam',
        ];
        $interestOptions = [
            'pottery' => 'Pottery',
            'knitting' => 'Knitting',
            'both' => 'Both',
            'not_sure' => 'Not sure yet',
        ];
        $metrics = [
            'total' => $this->ContactMessages->find()->count(),
            'new' => $this->ContactMessages->find()->where(['status' => 'new'])->count(),
            'in_progress' => $this->ContactMessages->find()->where(['status' => 'in_progress'])->count(),
            'resolved' => $this->ContactMessages->find()->where(['status' => 'resolved'])->count(),
            'spam' => $this->ContactMessages->find()->where(['status' => 'spam'])->count(),
        ];

        // Paginate to keep the page snappy with 1000+ enquiries.
        $this->paginate = [
            'limit' => 25,
            'maxLimit' => 100,
        ];
        $messages = $this->paginate($query);
        $filteredCount = is_object($messages) && method_exists($messages, 'count') ? $messages->count() : count($messages);
        $this->set(compact(
            'messages',
            'statusOptions',
            'interestOptions',
            'status',
            'interest',
            'search',
            'metrics',
            'filteredCount'
        ));
    }

    public function view(int $id): ?Response
    {
        $message = $this->ContactMessages->get($id, contain: ['AdminUsers']);

        if ($this->request->is(['patch', 'post', 'put'])) {
            $data = $this->request->getData();
            $data['reviewed_by_admin_user_id'] = $this->adminId();
            $message = $this->ContactMessages->patchEntity($message, $data, [
                'fields' => ['status', 'admin_notes', 'reviewed_by_admin_user_id'],
            ]);

            if ($this->ContactMessages->save($message)) {
                $this->Flash->success('Message updated.');

                return $this->redirect(['action' => 'view', $id]);
            }

            $this->Flash->error('The message could not be updated.');
        }

        $statusOptions = [
            'new' => 'New',
            'in_progress' => 'In progress',
            'resolved' => 'Resolved',
            'spam' => 'Spam',
        ];
        $this->set(compact('message', 'statusOptions'));

        return null;
    }

    public function reply(int $id): ?Response
    {
        $this->request->allowMethod(['post']);
        $message = $this->ContactMessages->get($id);

        $subject = trim((string)$this->request->getData('subject'));
        $body = trim((string)$this->request->getData('body'));

        if ($subject === '' || $body === '') {
            $this->Flash->error('Reply subject and body are both required.');
            return $this->redirect(['action' => 'view', $id]);
        }

        try {
            $mailer = new ContactMailer();
            $mailer->enquiryReply($message, $body, $subject)->deliver();
        } catch (Throwable $e) {
            Log::error('Reply email failed: ' . $e->getMessage());
            $this->Flash->error('Reply could not be sent: ' . $e->getMessage());
            return $this->redirect(['action' => 'view', $id]);
        }

        // Mark as resolved + record who replied
        $message->status = 'resolved';
        $message->reviewed_by_admin_user_id = $this->adminId();
        $existingNotes = trim((string)($message->admin_notes ?? ''));
        $stamp = date('Y-m-d H:i') . ' — replied via email';
        $message->admin_notes = $existingNotes === '' ? $stamp : ($existingNotes . "\n" . $stamp);
        $this->ContactMessages->save($message);

        $this->Flash->success('Reply sent and enquiry marked resolved.');
        return $this->redirect(['action' => 'view', $id]);
    }
}
