<?php

namespace App\Modules\Frontend\Controllers;

use CodeIgniter\Controller;
use App\Modules\Frontend\Models\TourModel;
use App\Modules\Frontend\Models\BookingModel;

class BookingController extends Controller
{
    protected $tourModel;
    protected $bookingModel;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->tourModel = new TourModel();
        $this->bookingModel = new BookingModel();
    }

    public function create()
    {
        $tourSlug = $this->request->getGet('tour');
        if (!$tourSlug) {
            return redirect()->to('/tours')->with('error', 'Tour not specified.');
        }

        $tour = $this->tourModel->where('slug', $tourSlug)->first();
        if (!$tour) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }

        return view('App\Modules\Frontend\Views\bookings\create', [
            'tour' => $tour,
            'meta_title' => 'Book: ' . esc($tour['title']),
            'meta_desc' => 'Secure your Mount Kenya trek: ' . esc($tour['meta_desc'] ?? ''),
            'current_currency' => session()->get('currency') ?? 'USD'
        ]);
    }

    public function store()
    {
        if (!$this->validateRateLimit()) {
            return $this->response->setStatusCode(429)->setJSON([
                'error' => 'Too many requests. Please wait 1 minute.'
            ]);
        }

        $rules = [
            'client_name' => 'required|min_length[2]',
            'email' => 'required|valid_email',
            'phone' => 'required',
            'travel_date' => 'required|valid_date',
            'pax' => 'required|integer|greater_than[0]',
            'tour_id' => 'required|integer'
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $tour = $this->tourModel->find($this->request->getPost('tour_id'));
        if (!$tour) {
            return redirect()->back()->with('error', 'Invalid tour selected.');
        }

        $pax = (int)$this->request->getPost('pax');
        $price = (float)$tour['price_usd'];
        $total = $price * $pax;

        // Generate invoice ref
        $year = date('Y');
        $lastBooking = $this->bookingModel->orderBy('id', 'DESC')->first();
        $nextId = $lastBooking ? ((int)substr($lastBooking['invoice_ref'] ?? "MKT-{$year}-000", -3)) + 1 : 1;
        $invoiceRef = 'MKT-' . $year . '-' . str_pad($nextId, 3, '0', STR_PAD_LEFT);

        $bookingData = [
            'tour_id'      => $tour['id'],
            'client_name'  => $this->request->getPost('client_name'),
            'email'        => $this->request->getPost('email'),
            'phone'        => $this->request->getPost('phone'),
            'travel_date'  => $this->request->getPost('travel_date'),
            'pax'          => $pax,
            'currency'     => session()->get('currency') ?? 'USD',
            'total_amount' => $total,
            'status'       => 'pending',
            'invoice_ref'  => $invoiceRef,
        ];

        try {
            $this->bookingModel->insert($bookingData);
            
            // ✅ Trigger the Email
            $bookingData['tour_title'] = $tour['title']; // Pass tour title to email
            $this->sendInvoiceEmail($bookingData);

            return redirect()->to(base_url("booking/success?ref=" . urlencode($invoiceRef)))
                             ->with('success', 'Expedition secured! Please check your inbox for the invoice.');
        } catch (\Exception $e) {
            log_message('error', 'Booking failed: ' . $e->getMessage());
            return redirect()->back()->with('error', 'Booking failed. Please try again later.');
        }
    }

    /**
     * ✅ Handles SMTP Email Dispatch
     */
    private function sendInvoiceEmail(array $data)
    {
        $email = \Config\Services::email();

        $email->setTo($data['email']);
        $email->setSubject('Expedition Invoice: ' . $data['invoice_ref'] . ' | Mount Kenya Treks');
        
        // Prepare data for the view
        $emailViewData = [
            'client_name' => $data['client_name'],
            'tour_title'  => $data['tour_title'],
            'invoice_ref' => $data['invoice_ref'],
            'travel_date' => $data['travel_date'],
            'pax'         => $data['pax'],
            'total_price' => $data['total_amount']
        ];

        $template = view('App\Modules\Frontend\Views\emails\invoice_notification', $emailViewData);
        
        $email->setMessage($template);

        if (!$email->send()) {
            log_message('error', 'Email dispatch failed for ' . $data['invoice_ref'] . '. Debug: ' . $email->printDebugger(['headers']));
        }
    }

    private function validateRateLimit(): bool
    {
        $session = session();
        $ip = $this->request->getIPAddress();
        $key = 'booking_rate_limit_' . $ip;
        $attempts = (int)($session->get($key) ?? 0);
        $now = time();
        $lastAttempt = $session->get("{$key}_ts") ?? 0;

        if ($now - $lastAttempt > 60) {
            $attempts = 0;
        }

        if ($attempts >= 3) {
            return false;
        }

        $session->set($key, $attempts + 1);
        $session->set("{$key}_ts", $now);
        return true;
    }

    public function success()
    {
        $ref = $this->request->getGet('ref');
        if (!$ref) {
            return redirect()->to('/');
        }

        return view('App\Modules\Frontend\Views\bookings\success', [
            'invoice_ref' => esc($ref),
            'meta_title' => 'Booking Confirmed',
            'meta_desc' => 'Thank you for booking with Mount Kenya Treks. Your invoice has been emailed.'
        ]);
    }
}