<?php
declare(strict_types=1);

namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/permissions.php';

use App\Core\Controller;
use App\Core\Database;
use PDO;

final class RegistrationTenantController extends Controller
{
    private function requireOrgOrRedirect(): void {
        // org must be selected before registration
        if (!function_exists('current_org_id') || (int)current_org_id() <= 0) {
            // if you have /admin/choose-org or /choose-org, change here:
            header('Location: ' . base_path('choose-org'));
            exit;
        }
    }

    private function ensureOrgUsersTable(PDO $db): void {
        $st=$db->prepare("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='org_users'");
        $st->execute();
        if((int)$st->fetchColumn()<=0){
            $db->exec("
              CREATE TABLE IF NOT EXISTS org_users(
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                org_id BIGINT UNSIGNED NOT NULL,
                user_id BIGINT UNSIGNED NOT NULL,
                role_code VARCHAR(50) NOT NULL,
                is_active TINYINT(1) NOT NULL DEFAULT 1,
                created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY(id),
                UNIQUE KEY uk_org_user(org_id,user_id),
                KEY idx_org(org_id),
                KEY idx_user(user_id)
              ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ");
        }
    }

    private function phoneRequired(PDO $db): bool {
        // check custom field "phone" required in registration scope
        $st=$db->prepare("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='custom_fields'");
        $st->execute();
        if((int)$st->fetchColumn()<=0) return true;

        $st=$db->prepare("SELECT COUNT(*) FROM custom_fields WHERE scope='registration' AND field_key='phone' AND is_required=1 AND is_active=1");
        $st->execute();
        return ((int)$st->fetchColumn()>0);
    }

    public function form(): void
    {
        $this->requireOrgOrRedirect();
        $this->view('public/register', []);
    }

    public function submit(): void
    {
        $this->requireOrgOrRedirect();
        if(($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST'){ http_response_code(405); exit; }

        $db = Database::getInstance();
        $orgId = (int) current_org_id();
        $this->ensureOrgUsersTable($db);

        $first = trim((string)($_POST['first_name'] ?? ''));
        $last  = trim((string)($_POST['last_name'] ?? ''));
        $email = trim((string)($_POST['email'] ?? ''));
        $pass  = (string)($_POST['password'] ?? '');
        $phone = trim((string)($_POST['phone'] ?? ''));

        if ($first==='' || $last==='' || $email==='' || $pass==='') {
            if(function_exists('flash_set')) flash_set('danger', 'All fields are required');
            header('Location: '.base_path('register')); exit;
        }

        if ($this->phoneRequired($db) && $phone==='') {
            if(function_exists('flash_set')) flash_set('danger', 'Phone is required');
            header('Location: '.base_path('register')); exit;
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            if(function_exists('flash_set')) flash_set('danger', 'Invalid email');
            header('Location: '.base_path('register')); exit;
        }

        // Ensure email unique (global)
        $st=$db->prepare("SELECT id FROM users WHERE email=:e LIMIT 1");
        $st->execute([':e'=>$email]);
        if((int)$st->fetchColumn()>0){
            if(function_exists('flash_set')) flash_set('danger', 'Email already exists');
            header('Location: '.base_path('register')); exit;
        }

        $hash = password_hash($pass, PASSWORD_BCRYPT);

        // role_id for Author (if exists) else keep existing default
        $roleId = 5;
        $st=$db->prepare("SELECT id FROM roles WHERE code='author' LIMIT 1");
        $st->execute();
        $rid=(int)$st->fetchColumn();
        if($rid>0) $roleId=$rid;

        $st=$db->prepare("INSERT INTO users(role_id,first_name,last_name,email,password_hash,mobile,preferred_lang,is_active) VALUES(:r,:f,:l,:e,:p,:m,'ar',1)");
        $st->execute([':r'=>$roleId,':f'=>$first,':l'=>$last,':e'=>$email,':p'=>$hash,':m'=>($phone!==''?$phone:null)]);
        $userId=(int)$db->lastInsertId();

        // link user to this org as AUTHOR only
        $st=$db->prepare("INSERT INTO org_users(org_id,user_id,role_code,is_active) VALUES(:o,:u,'author',1)");
        $st->execute([':o'=>$orgId,':u'=>$userId]);

        // auto-login
        if(session_status()!==PHP_SESSION_ACTIVE) session_start();
        $_SESSION['user_id']=$userId;

        if(function_exists('flash_set')) flash_set('success', 'Registered successfully');
        header('Location: '.base_path('author')); exit;
    }
}
