<?php

namespace App\Controllers\View;

use CodeIgniter\Controller;
use App\Models\ConfigurationModel;
use App\Models\UserModel;
use App\Models\AuthorizedUserModel;
use App\Models\RoleModel;
use App\Models\ParentModel;
use App\Models\UserRoleModel;
use App\Services\EmailService;
use App\Services\SchoolIdService;
use App\Services\PhoneFormatterService;

class RegisterController extends Controller
{
    protected $db;
    protected $configModel;
    protected $semester;
    protected $schoolYear;
    protected $userRoleModel;
    protected $roleModel;
    protected $userModel;
    protected $parentModel;

    public function __construct()
    {
        // Load the database service
        $this->db = \Config\Database::connect();
        // Check if the database connection is established
        if (!$this->db->connect()) {
            log_message('error', 'Database connection failed.');
            throw new \Exception('Database connection failed.');
        } else {
            log_message('info', 'Database connection successful.');
        }
        $this->configModel = new ConfigurationModel(); 
        $this->userRoleModel = new UserRoleModel();
        $this->roleModel = new RoleModel();
        $this->userModel = new UserModel();
        $this->parentModel = new ParentModel();

        $this->semester = $this->configModel->getConfig('semester');
        $this->schoolYear = $this->configModel->getConfig('school_year');
    }
        
    public function index()
    {
        log_message('debug', 'CAPTCHA session value: ' . session()->get('captcha_answer'));

        // Only generate CAPTCHA if not already set (first visit or after submission)
        if (!session()->has('captcha_answer')) {
            $length = rand(4, 8);
            $captchaText = $this->generateCaptchaText($length);
            session()->set('captcha_answer', $captchaText);
        }

        $data['captchaQuestion'] = session()->get('captcha_answer');

        // ✅ NO need to check policy_accepted here
        return view('user/register', $data);
    }

    private function generateCaptchaText($length)
    {
        $characters = 'ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghjkmnopqrstuvwxyz0123456789';
        $captchaText = '';

        for ($i = 0; $i < $length; $i++) {
            $captchaText .= $characters[rand(0, strlen($characters) - 1)];
        }

        return $captchaText;
    }

    public function success()
    {
        // Start session
        $session = session();

        // Check if the session has 'user_email'
        if (!$session->has('user_email')) {
            // If not, redirect to the registration page
            return redirect()->to('/register');
        }

        // Get 'user_email' from session
        $email = $session->get('user_email');

        // Pass the 'email' variable to the success view
        return view('success', ['email' => $email]);
    }


    public function register()
    {
        helper(['url', 'form']);
        log_message('debug', 'CAPTCHA session value: ' . session()->get('captcha_answer'));

        /* ───────────── 1.  Load services ───────────── */  
        $schoolIdService = new SchoolIdService();

        /* ───────────── 2.  Sanitize & raw data ───────────── */
        $post    = $this->formatUserInput($this->request); // safe / formatted
        $rawPost = $this->request->getPost();              // raw (for flags etc.)
        $captcha = $rawPost['captcha'] ?? '';

        /* ───────────── 3.  Validation rules ───────────── */
        $rules = [
            'firstname'  => 'required|regex_match[/^[a-zA-Z\s-]+$/]|min_length[2]|max_length[30]',
            'lastname'   => 'required|regex_match[/^[a-zA-Z\s-]+$/]|min_length[2]|max_length[30]',
            'gender'     => 'required|in_list[Male,Female]',
            'email'      => 'required|valid_email|max_length[50]',
            'confirm_email' => 'required|matches[email]',
            'cellphone'  => 'required|regex_match[/^[\d\s\-\(\)\.]+$/]|min_length[10]|max_length[20]',
            'address_street' => 'permit_empty|regex_match[/^[a-zA-Z0-9\s\-]+$/]|max_length[150]',
            'apt'        => 'permit_empty|regex_match[/^[a-zA-Z0-9\s-]+$/]|max_length[10]',
            'city'       => 'required|alpha_space|min_length[2]|max_length[30]',
            'state'      => 'required|in_list[CT,ME,MA,NH,NY,RI,VT]',
            'zip'        => 'required|regex_match[/^\d{5}$/]',
            'accept_school_policy' => 'required',
            'captcha'    => 'required|alpha_numeric|min_length[4]|max_length[10]',
        ];

        // 1. Check if "I am a parent" checkbox is ticked
        $isParent = isset($rawPost['is_parent']) && $rawPost['is_parent'] == '1';

        // 2. If parent, handle second parent logic
        if ($isParent) {
            $noSecondParent = isset($rawPost['no_second_parent_info']) && $rawPost['no_second_parent_info'] == '1';

            $secondParentProvided = !empty($rawPost['second_firstname']) ||
                                    !empty($rawPost['second_lastname']) ||
                                    !empty($rawPost['second_gender']) ||
                                    !empty($rawPost['second_email']) ||
                                    !empty($rawPost['second_cellphone']);

            // 3. Error: must provide second parent or check "no second parent"
            if (!$noSecondParent && !$secondParentProvided) {
                return redirect()->back()->withInput()->with('errors', [
                    'second_parent_info' => 'As a parent, please provide second parent information or check "No second parent info".'
                ]);
            }

            // 4. Add second parent field rules only if "no second parent" is NOT checked
            if (!$noSecondParent) {
                $rules += [
                    'second_firstname' => 'required|regex_match[/^[a-zA-Z\s\-]+$/]|min_length[2]|max_length[30]',
                    'second_lastname'  => 'required|regex_match[/^[a-zA-Z\s\-]+$/]|min_length[2]|max_length[30]',
                    'second_gender'    => 'required|in_list[Male,Female]',
                    'second_email'     => 'required|valid_email|max_length[50]',
                    'second_cellphone' => 'required|regex_match[/^[\d\s\-\(\)\.]+$/]|min_length[10]|max_length[20]',
                ];
            }
        }

        log_message('debug', '🧪 Starting validation check...');
        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        /* ───────────── 4.  CAPTCHA check ───────────── */
        if ($captcha !== session()->get('captcha_answer')) {
            return redirect()->back()
                ->withInput()
                ->with('errors', ['captcha' => '']) // keeps input marked as invalid
                ->with('top_error', 'Incorrect CAPTCHA answer. Please try again.');
        }

        /* ───────────── 5.  Unique e-mail ───────────── */
        // Step 1: Check if a user with this email exists
        $existingUser = $this->userModel->where('email', $post['email'])->first();

        if ($existingUser) {
            return redirect()->back()->withInput()->with('error',
                'This email address is already registered. Please check your email or log in.');
        }

        /* ───────────── 6.  Determine role ───────────── */
        $roleName = !empty($rawPost['is_parent']) ? 'parent' : 'guest';
        $role     = $this->roleModel->where('name', $roleName)->first();
        if (!$role) {
            return redirect()->back()->withInput()->with('errors', ['role' => 'Role not found']);
        }

        /* ───────────── 7.  Build & insert user ───────────── */
        $token    = bin2hex(random_bytes(48));
        $tokenHash = hash('sha256', $token);
        $userData = [
            'firstname'  => $post['firstname'],
            'lastname'   => $post['lastname'],
            'gender'     => $post['gender'],
            'email'      => $post['email'],
            'cellphone'  => $post['cellphone'],
            'address_street' => $post['address_street'] ?? null,
            'apt'        => $post['apt'] ?? null,
            'city'       => $post['city'],
            'state'      => $post['state'],
            'zip'        => $post['zip'],
            'token'      => $tokenHash,
            'is_verified'=> 0,
            'accept_school_policy' => (int) $post['accept_school_policy'],
            'status'     => 'Inactive',
            'school_id'  => $schoolIdService->generateUserSchoolId(),
            'semester'   => $this->semester,
            'school_year'=> $this->schoolYear,
        ];

        $this->db->transStart();

        if (!$this->userModel->insert($userData)) {
            $this->db->transRollback();
            return redirect()->back()->withInput()->with('errors', $this->userModel->errors());
        }
        $firstParentId = $this->userModel->getInsertID();

        $this->userRoleModel->insert([
            'user_id'    => $firstParentId,
            'role_id'    => $role['id'],
            'created_at' => utc_now(),
        ]);

        /* ───────────── 8.  Optional second-parent insert ───────────── */
        if ($isParent) {
            if (empty($rawPost['no_second_parent_info'])) {
                $this->parentModel->insert([
                    'secondparent_firstname' => $post['second_firstname'],
                    'secondparent_lastname'  => $post['second_lastname'],
                    'secondparent_gender'    => $post['second_gender'],
                    'secondparent_email'     => $post['second_email'],
                    'secondparent_phone'     => $post['second_cellphone'],
                    'firstparent_id'         => $firstParentId,
                    'semester'               => $this->semester,
                    'school_year'            => $this->schoolYear,
                ]);
            }
        }

        $this->db->transComplete();
        if (!$this->db->transStatus()) {
            return redirect()->back()->withInput()->with('error', 'Registration failed, please try again.');
        }

        /* ───────────── 9.  Confirmation e-mail ───────────── */
        $recipientName   = $post['firstname'] . ' ' . $post['lastname'];
        $activationLink  = site_url('/user/confirm/' . $token);
        $orgName         = 'Al Rahma Sunday School';
        $contactInfo     = 'alrahma.isgl@gmail.com';
        $logoUrl         = 'https://alrahmaisgl.org/assets/images/alrahma_logo.png';

        $emailData = [
            'recipientName'  => $recipientName,
            'activationLink' => $activationLink,
            'orgName'        => $orgName,
            'contactInfo'    => $contactInfo,
            'logoUrl'        => $logoUrl,
            'subject'        => 'Email Confirmation'
        ];

        if ($isParent) {
            $html = view('emails/welcome_parent', $emailData);
        } else {
            $html = view('emails/welcome_staff', $emailData);
        }

        (new EmailService())->send($post['email'], 'Email Confirmation', $html, 'general');


        /* ───────────── 10.  Redirect to success ───────────── */
        session()->set('user_email', $post['email']);
        session()->remove('captcha_answer'); // Clear CAPTCHA after success
        return redirect()->to('/register/success');
    }

    private function formatName(string $name): string
    {
        $name = trim($name);
        return ucwords(strtolower($name), " -");
    }

    private function formatEmail(?string $email): string
    {
        $email = strtolower(trim($email));
/*
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new \InvalidArgumentException('Please enter a valid email address.');
        }*/
        return $email;
    }

    private function formatAddress(string $address): string
    {
        return ucwords(strtolower(trim($address)));
    }

    private function formatUserInput($request): array
{
    $formatter = new PhoneFormatterService();
    $post = (array) $request->getPost();

    // tiny helper: safe getter + trim + cast to string
    $g = static function (string $key) use ($post): string {
        return trim((string) ($post[$key] ?? ''));
    };

    $data = [
        'firstname'            => $this->formatName($g('firstname')),
        'lastname'             => $this->formatName($g('lastname')),
        'email'                => $this->formatEmail($g('email')),
        'gender'               => $g('gender'),
        'city'                 => $this->formatName($g('city')),
        'cellphone'            => $formatter->formatPhoneNumber($g('cellphone')),   // ✅ safe
        'address_street'       => $this->formatAddress($g('address_street')),
        'apt'                  => strtoupper($g('apt')),
        'state'                => strtoupper($g('state')),
        'zip'                  => $g('zip'),
        'accept_school_policy' => (int) ($post['accept_school_policy'] ?? 0),
    ];

    // if user says "no second parent info", skip entirely
    $noSecondInfo = !empty($post['no_second_parent_info']);

    // collect (safely) and see if anything was provided
    $second_firstname = $this->formatName($g('second_firstname'));
    $second_lastname  = $this->formatName($g('second_lastname'));
    $second_gender    = $g('second_gender');
    $second_email     = $this->formatEmail($g('second_email'));
    $second_cellphone = $formatter->formatPhoneNumber($g('second_cellphone'));      // ✅ safe

    $secondProvided = !$noSecondInfo && (
        $second_firstname !== '' ||
        $second_lastname  !== '' ||
        $second_gender    !== '' ||
        $second_email     !== '' ||
        preg_replace('/\D/', '', $second_cellphone) !== ''
    );

    if ($secondProvided) {
        $data['second_firstname'] = $second_firstname;
        $data['second_lastname']  = $second_lastname;
        $data['second_gender']    = $second_gender;
        $data['second_email']     = $second_email;
        $data['second_cellphone'] = $second_cellphone;
    }

    return $data;
}




}
