<?php

class AuthController
{
    private $pdo;

    public function __construct($pdo)
    {
        error_log("=== AUTH CONTROLLER CONSTRUCTOR ===");
        $this->pdo = $pdo;

        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
    }

    // ==================== PUBLIC AUTH METHODS ====================

    public function showLogin()
    {
        if (!empty($_SESSION['user_id'])) {
            header('Location: /lead-management/public/app');
            exit;
        }

        $view = new View();
        $error = $_SESSION['flash_error'] ?? null;
        $success = $_SESSION['flash_success'] ?? null;
        unset($_SESSION['flash_error'], $_SESSION['flash_success']);

        return $view->render('auth/login', [
            'title' => 'Login',
            'error' => $error,
            'success' => $success,
            'baseUrl' => '/lead-management/public'
        ]);
    }

    public function login($request)
    {
        $email = trim($request->post('email') ?? '');
        $password = trim($request->post('password') ?? '');

        if (empty($email) || empty($password)) {
            $_SESSION['flash_error'] = 'Please enter email and password';
            header('Location: /lead-management/public/login');
            exit;
        }

        try {
            // Find user by email
            $stmt = $this->pdo->prepare("SELECT * FROM users WHERE email = ?");
            $stmt->execute([$email]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($user && password_verify($password, $user['password'])) {
                // Check if email is verified
                if (empty($user['email_verified_at'])) {
                    $_SESSION['flash_error'] = 'Please verify your email address before logging in. Check your inbox for the verification link.';
                    header('Location: /lead-management/public/login');
                    exit;
                }

                // Login successful
                $_SESSION['user_id'] = $user['id'];
                $_SESSION['user_email'] = $user['email'];
                $_SESSION['user_name'] = $user['first_name'] . ' ' . $user['last_name'];
                $_SESSION['user_role'] = $user['role'];
                $_SESSION['tenant_id'] = $user['tenant_id'];
                $_SESSION['account_type'] = $user['account_type'];

                $_SESSION['flash_success'] = 'Welcome back, ' . $user['first_name'] . '!';
                header('Location: /lead-management/public/app');
                exit;
            } else {
                $_SESSION['flash_error'] = 'Invalid email or password';
                header('Location: /lead-management/public/login');
                exit;
            }
        } catch (Exception $e) {
            error_log("Login error: " . $e->getMessage());
            $_SESSION['flash_error'] = 'Login failed. Please try again.';
            header('Location: /lead-management/public/login');
            exit;
        }
    }

    public function showRegister()
    {
        if (!empty($_SESSION['user_id'])) {
            header('Location: /lead-management/public/app');
            exit;
        }

        $view = new View();
        $error = $_SESSION['flash_error'] ?? null;
        $success = $_SESSION['flash_success'] ?? null;
        $old = $_SESSION['old_form'] ?? [];
        unset($_SESSION['flash_error'], $_SESSION['flash_success'], $_SESSION['old_form']);

        return $view->render('auth/register', [
            'title' => 'Register',
            'error' => $error,
            'success' => $success,
            'old' => $old,
            'baseUrl' => '/lead-management/public'
        ]);
    }

    public function register($request)
    {
        // Get form data
        $firstName = trim($request->post('first_name') ?? '');
        $lastName = trim($request->post('last_name') ?? '');
        $email = trim($request->post('email') ?? '');
        $password = trim($request->post('password') ?? '');
        $confirmPassword = trim($request->post('confirm_password') ?? '');
        $companyName = trim($request->post('company_name') ?? '');
        $accountType = trim($request->post('account_type') ?? 'individual');
        $agreeTerms = !empty($request->post('agree_terms'));

        // Store for form persistence
        $_SESSION['old_form'] = [
            'first_name' => $firstName,
            'last_name' => $lastName,
            'email' => $email,
            'company_name' => $companyName,
            'account_type' => $accountType,
            'agree_terms' => $agreeTerms
        ];

        // Validation
        $error = $this->validateRegistration($firstName, $lastName, $email, $password, $confirmPassword, $companyName, $accountType, $agreeTerms);
        if ($error) {
            $_SESSION['flash_error'] = $error;
            header('Location: /lead-management/public/register');
            exit;
        }

        try {
            // Check if email exists
            $stmt = $this->pdo->prepare("SELECT id FROM users WHERE email = ?");
            $stmt->execute([$email]);
            if ($stmt->fetch()) {
                $_SESSION['flash_error'] = 'Email already registered';
                header('Location: /lead-management/public/register');
                exit;
            }

            // Start transaction
            $this->pdo->beginTransaction();

            // Generate verification token
            $verificationToken = bin2hex(random_bytes(32));
            $verificationExpires = date('Y-m-d H:i:s', strtotime('+24 hours'));

            // Create tenant
            $tenantId = null;
            if ($accountType === 'company') {
                // Generate unique slug for company
                $slug = $this->generateSlug($companyName);
                $stmt = $this->pdo->prepare("INSERT INTO tenants (name, slug, created_at) VALUES (?, ?, NOW())");
                $stmt->execute([$companyName, $slug]);
                $tenantId = $this->pdo->lastInsertId();
            } else {
                // Get or create default individual tenant
                $stmt = $this->pdo->prepare("SELECT id FROM tenants WHERE is_global_personal = 1 LIMIT 1");
                $stmt->execute();
                $tenant = $stmt->fetch(PDO::FETCH_ASSOC);

                if ($tenant) {
                    $tenantId = $tenant['id'];
                } else {
                    // Generate unique slug for individual tenant
                    $slug = $this->generateSlug('individual-users');
                    $stmt = $this->pdo->prepare("INSERT INTO tenants (name, slug, is_global_personal, created_at) VALUES (?, ?, 1, NOW())");
                    $stmt->execute(['Individual Users', $slug]);
                    $tenantId = $this->pdo->lastInsertId();
                }
            }

            // Create user
            $stmt = $this->pdo->prepare("
                INSERT INTO users (
                    tenant_id, first_name, last_name, email, password, 
                    account_type, company_name, email_verified_at, 
                    verification_token, verification_expires, created_at
                ) 
                VALUES (?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, NOW())
            ");
            $stmt->execute([
                $tenantId,
                $firstName,
                $lastName,
                $email,
                password_hash($password, PASSWORD_DEFAULT),
                $accountType,
                $accountType === 'company' ? $companyName : null,
                $verificationToken,
                $verificationExpires
            ]);

            // Commit transaction
            $this->pdo->commit();

            // Send verification email
            $this->sendVerificationEmail($email, $firstName, $verificationToken);

            // Clear old form data and show success
            unset($_SESSION['old_form']);
            $_SESSION['flash_success'] = 'Registration successful! Please check your email to verify your account before logging in.';
            header('Location: /lead-management/public/register');
            exit;
        } catch (Exception $e) {
            // Rollback on error
            if ($this->pdo->inTransaction()) {
                $this->pdo->rollBack();
            }
            error_log("Registration error: " . $e->getMessage());
            $_SESSION['flash_error'] = 'Registration failed. Please try again.';
            header('Location: /lead-management/public/register');
            exit;
        }
    }

    public function verifyEmail($request)
    {
        $token = $request->get('token') ?? '';

        if (empty($token)) {
            $_SESSION['flash_error'] = 'Invalid verification link.';
            header('Location: /lead-management/public/login');
            exit;
        }

        try {
            // Find user by token
            $stmt = $this->pdo->prepare("
                SELECT * FROM users 
                WHERE verification_token = ? 
                AND email_verified_at IS NULL
            ");
            $stmt->execute([$token]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$user) {
                $_SESSION['flash_error'] = 'Invalid or expired verification link.';
                header('Location: /lead-management/public/login');
                exit;
            }

            // Check if token expired
            if (strtotime($user['verification_expires']) < time()) {
                $_SESSION['flash_error'] = 'Verification link has expired. Please register again.';
                header('Location: /lead-management/public/login');
                exit;
            }

            // Verify email
            $stmt = $this->pdo->prepare("
                UPDATE users 
                SET email_verified_at = NOW(), 
                    verification_token = NULL, 
                    verification_expires = NULL 
                WHERE id = ?
            ");
            $success = $stmt->execute([$user['id']]);

            if ($success) {
                $_SESSION['flash_success'] = 'Email verified successfully! You can now log in to your account.';
            } else {
                $_SESSION['flash_error'] = 'Failed to verify email. Please try again.';
            }
            header('Location: /lead-management/public/login');
            exit;
        } catch (Exception $e) {
            error_log("Verification error: " . $e->getMessage());
            $_SESSION['flash_error'] = 'Verification failed. Please try again.';
            header('Location: /lead-management/public/login');
            exit;
        }
    }

    public function showForgotPassword()
    {
        if (!empty($_SESSION['user_id'])) {
            header('Location: /lead-management/public/app');
            exit;
        }

        $view = new View();
        $error = $_SESSION['flash_error'] ?? null;
        $success = $_SESSION['flash_success'] ?? null;
        unset($_SESSION['flash_error'], $_SESSION['flash_success']);

        return $view->render('auth/forgot-password', [
            'title' => 'Forgot Password',
            'error' => $error,
            'success' => $success,
            'baseUrl' => '/lead-management/public'
        ]);
    }

    public function forgotPassword($request)
    {
        $email = $request->post('email') ?? '';

        if (empty($email)) {
            $_SESSION['flash_error'] = 'Please enter your email address';
            header('Location: /lead-management/public/forgot-password');
            exit;
        }

        try {
            $stmt = $this->pdo->prepare("
                SELECT id, first_name, email 
                FROM users 
                WHERE email = ? 
                AND email_verified_at IS NOT NULL
            ");
            $stmt->execute([$email]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($user) {
                // Generate reset token
                $resetToken = bin2hex(random_bytes(32));
                $expiresAt = date('Y-m-d H:i:s', strtotime('+1 hour'));

                // Store token
                $stmt = $this->pdo->prepare("
                    INSERT INTO password_resets (user_id, token, expires_at) 
                    VALUES (?, ?, ?)
                ");
                $stmt->execute([$user['id'], $resetToken, $expiresAt]);

                // Send reset email
                $this->sendPasswordResetEmail($user['email'], $user['first_name'], $resetToken);
            }

            // Always show success (security best practice)
            $_SESSION['flash_success'] = 'If an account exists with that email, a password reset link has been sent.';
            header('Location: /lead-management/public/login');
            exit;
        } catch (Exception $e) {
            error_log("Forgot password error: " . $e->getMessage());
            $_SESSION['flash_error'] = 'Failed to process request. Please try again.';
            header('Location: /lead-management/public/forgot-password');
            exit;
        }
    }

    public function showResetPassword()
    {
        $token = $_GET['token'] ?? '';

        if (empty($token)) {
            $_SESSION['flash_error'] = 'Invalid reset link';
            header('Location: /lead-management/public/login');
            exit;
        }

        try {
            $stmt = $this->pdo->prepare("
                SELECT pr.*, u.email 
                FROM password_resets pr 
                JOIN users u ON pr.user_id = u.id 
                WHERE pr.token = ? 
                AND pr.expires_at > NOW() 
                AND pr.used = 0
            ");
            $stmt->execute([$token]);
            $resetRequest = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$resetRequest) {
                $_SESSION['flash_error'] = 'Invalid or expired reset link';
                header('Location: /lead-management/public/login');
                exit;
            }

            $view = new View();
            return $view->render('auth/reset-password', [
                'token' => $token,
                'email' => $resetRequest['email'],
                'title' => 'Reset Password',
                'baseUrl' => '/lead-management/public'
            ]);
        } catch (Exception $e) {
            error_log("Reset password error: " . $e->getMessage());
            $_SESSION['flash_error'] = 'Invalid reset link';
            header('Location: /lead-management/public/login');
            exit;
        }
    }

    public function resetPassword($request)
    {
        $token = $request->post('token') ?? '';
        $password = $request->post('password') ?? '';
        $confirmPassword = $request->post('confirm_password') ?? '';

        if (empty($token) || empty($password)) {
            $_SESSION['flash_error'] = 'All fields are required';
            header('Location: /lead-management/public/reset-password?token=' . $token);
            exit;
        }

        if ($password !== $confirmPassword) {
            $_SESSION['flash_error'] = 'Passwords do not match';
            header('Location: /lead-management/public/reset-password?token=' . $token);
            exit;
        }

        try {
            // Validate token
            $stmt = $this->pdo->prepare("
                SELECT pr.*, u.id as user_id 
                FROM password_resets pr 
                JOIN users u ON pr.user_id = u.id 
                WHERE pr.token = ? 
                AND pr.expires_at > NOW() 
                AND pr.used = 0
            ");
            $stmt->execute([$token]);
            $resetRequest = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$resetRequest) {
                $_SESSION['flash_error'] = 'Invalid or expired reset link';
                header('Location: /lead-management/public/login');
                exit;
            }

            $this->pdo->beginTransaction();

            // Update password
            $passwordHash = password_hash($password, PASSWORD_DEFAULT);
            $stmt = $this->pdo->prepare("UPDATE users SET password = ? WHERE id = ?");
            $stmt->execute([$passwordHash, $resetRequest['user_id']]);

            // Mark token as used
            $stmt = $this->pdo->prepare("UPDATE password_resets SET used = 1 WHERE token = ?");
            $stmt->execute([$token]);

            $this->pdo->commit();

            $_SESSION['flash_success'] = 'Password reset successfully! You can now login with your new password.';
            header('Location: /lead-management/public/login');
            exit;
        } catch (Exception $e) {
            if ($this->pdo->inTransaction()) {
                $this->pdo->rollBack();
            }
            error_log("Reset password error: " . $e->getMessage());
            $_SESSION['flash_error'] = 'Failed to reset password';
            header('Location: /lead-management/public/reset-password?token=' . $token);
            exit;
        }
    }

    public function resendVerification()
    {
        if (empty($_SESSION['user_id'])) {
            header('Location: /lead-management/public/login');
            exit;
        }

        try {
            $stmt = $this->pdo->prepare("
                SELECT email, first_name, last_name, verification_token 
                FROM users 
                WHERE id = ? 
                AND email_verified_at IS NULL
            ");
            $stmt->execute([$_SESSION['user_id']]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($user && !empty($user['verification_token'])) {
                $this->sendVerificationEmail(
                    $user['email'],
                    $user['first_name'] . ' ' . $user['last_name'],
                    $user['verification_token']
                );

                $_SESSION['flash_success'] = 'Verification email sent! Please check your inbox.';
            } else {
                $_SESSION['flash_error'] = 'Unable to resend verification email.';
            }
        } catch (Exception $e) {
            error_log("Resend verification error: " . $e->getMessage());
            $_SESSION['flash_error'] = 'Failed to resend verification email.';
        }

        header('Location: /lead-management/public/app');
        exit;
    }

    public function logout()
    {
        session_destroy();
        header('Location: /lead-management/public/login');
        exit;
    }

    // ==================== PRIVATE HELPER METHODS ====================

    private function validateRegistration($firstName, $lastName, $email, $password, $confirmPassword, $companyName, $accountType, $agreeTerms)
    {
        if (!$agreeTerms) {
            return 'You must agree to the terms and conditions';
        }
        if (empty($firstName) || empty($lastName)) {
            return 'First name and last name are required';
        }
        if (empty($email)) {
            return 'Email is required';
        }
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return 'Please enter a valid email address';
        }
        if (empty($password)) {
            return 'Password is required';
        }
        if (strlen($password) < 8) {
            return 'Password must be at least 8 characters';
        }
        if ($password !== $confirmPassword) {
            return 'Passwords do not match';
        }
        if ($accountType === 'company' && empty($companyName)) {
            return 'Company name is required for business accounts';
        }
        return null;
    }

    private function generateSlug($name, $counter = 0)
    {
        // Convert to lowercase and replace non-alphanumeric with hyphens
        $slug = strtolower(trim($name));
        $slug = preg_replace('/[^a-z0-9-]/', '-', $slug);
        $slug = preg_replace('/-+/', '-', $slug);
        $slug = trim($slug, '-');

        // Add counter if needed for uniqueness
        if ($counter > 0) {
            $slug = $slug . '-' . $counter;
        }

        // Check if slug exists
        try {
            $stmt = $this->pdo->prepare("SELECT id FROM tenants WHERE slug = ?");
            $stmt->execute([$slug]);
            $existing = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($existing) {
                return $this->generateSlug($name, $counter + 1);
            }
        } catch (Exception $e) {
            // If check fails, return with timestamp for uniqueness
            return $slug . '-' . time();
        }

        return $slug;
    }

    private function sendVerificationEmail($email, $name, $token)
    {
        try {
            $verificationUrl = '/lead-management/public/verify-email?token=' . $token;
            $fullUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'] . $verificationUrl;

            $subject = "Verify Your Email - LeadIntelligence AI";
            $message = "Hello {$name},\n\nPlease verify your email by clicking this link:\n{$fullUrl}\n\nThis link expires in 24 hours.";

            $headers = "From: no-reply@leadintelligence.ai";
            return mail($email, $subject, $message, $headers);
        } catch (Exception $e) {
            error_log("Email error: " . $e->getMessage());
            return false;
        }
    }

    private function sendPasswordResetEmail($email, $name, $token)
    {
        try {
            $resetUrl = '/lead-management/public/reset-password?token=' . $token;
            $fullUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'] . $resetUrl;

            $subject = "Reset Your Password - LeadIntelligence AI";
            $message = "Hello {$name},\n\nYou requested a password reset. Click this link to reset your password:\n{$fullUrl}\n\nThis link expires in 1 hour.\n\nIf you didn't request this, please ignore this email.";

            $headers = "From: no-reply@leadintelligence.ai";
            return mail($email, $subject, $message, $headers);
        } catch (Exception $e) {
            error_log("Password reset email error: " . $e->getMessage());
            return false;
        }
    }
}
