<?php
session_start();
require_once 'config/database.php';
require_once 'includes/functions.php';
require_once 'includes/email_templates.php';

try {
    // Get database connection
    $database = new Database();
    $db = $database->getConnection();
    
    // Start transaction
    $db->beginTransaction();

    // Validate required fields
    $requiredFields = [
        'firstName', 'lastName', 'email', 'phone', 'dob', 'gender', 
        'country', 'address', 'accountType', 'currency', 'username', 
        'password', 'pin', 'kinName', 'kinEmail', 'kinPhone', 'kinAddress',
        'employmentStatus', 'incomeSource', 'ssn', 'mothersMaidenName'
    ];

    foreach ($requiredFields as $field) {
        if (!isset($_POST[$field]) || empty($_POST[$field])) {
            $_SESSION['error'] = ucfirst(str_replace('_', ' ', $field)) . ' is required';
            header('Location: register.php');
            exit;
        }
    }

    // Validate email format
    if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
        $_SESSION['error'] = 'Invalid email format';
        header('Location: register.php');
        exit;
    }

    // Check if email exists
    $stmt = $db->prepare("SELECT id FROM users WHERE email = ?");
    $stmt->execute([$_POST['email']]);
    if ($stmt->fetch()) {
        $_SESSION['error'] = 'Email already registered';
        header('Location: register.php');
        exit;
    }

    // Check if username exists
    $stmt = $db->prepare("SELECT id FROM users WHERE username = ?");
    $stmt->execute([$_POST['username']]);
    if ($stmt->fetch()) {
        $_SESSION['error'] = 'Username already taken';
        header('Location: register.php');
        exit;
    }

    // Generate account number
    $accountNumber = date('Y') . mt_rand(100000, 999999);

    // Handle profile picture upload
    $profilePicture = '';
    $targetPath = '';
    if (isset($_FILES['profilePicture']) && $_FILES['profilePicture']['error'] === 0) {
        $uploadDir = 'uploads/profiles/';
        if (!file_exists($uploadDir)) {
            mkdir($uploadDir, 0777, true);
        }

        $allowedTypes = ['image/jpeg', 'image/png'];
        $fileInfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimeType = finfo_file($fileInfo, $_FILES['profilePicture']['tmp_name']);
        finfo_close($fileInfo);

        if (!in_array($mimeType, $allowedTypes)) {
            $_SESSION['error'] = 'Invalid file type. Only JPG and PNG files are allowed.';
            header('Location: register.php');
            exit;
        }

        if ($_FILES['profilePicture']['size'] > 5 * 1024 * 1024) {
            $_SESSION['error'] = 'File size too large. Maximum size is 5MB.';
            header('Location: register.php');
            exit;
        }

        $extension = strtolower(pathinfo($_FILES['profilePicture']['name'], PATHINFO_EXTENSION));
        $fileName = uniqid() . '_' . time() . '.' . $extension;
        $targetPath = $uploadDir . $fileName;

        if (!move_uploaded_file($_FILES['profilePicture']['tmp_name'], $targetPath)) {
            $_SESSION['error'] = 'Error uploading profile picture.';
            header('Location: register.php');
            exit;
        }

        $profilePicture = $fileName;
    }

    // Handle utility bill upload if provided
    $utilityBillPath = '';
    if (isset($_FILES['utilityBill']) && $_FILES['utilityBill']['error'] === 0) {
        $uploadDir = 'uploads/documents/';
        if (!file_exists($uploadDir)) {
            mkdir($uploadDir, 0777, true);
        }

        $extension = strtolower(pathinfo($_FILES['utilityBill']['name'], PATHINFO_EXTENSION));
        $fileName = 'utility_' . uniqid() . '_' . time() . '.' . $extension;
        $utilityBillPath = $uploadDir . $fileName;

        if (!move_uploaded_file($_FILES['utilityBill']['tmp_name'], $utilityBillPath)) {
            $_SESSION['error'] = 'Error uploading utility bill.';
            header('Location: register.php');
            exit;
        }

        $utilityBillPath = $fileName;
    }

    // Handle ID document upload if provided
    $idDocumentPath = '';
    if (isset($_FILES['idDocument']) && $_FILES['idDocument']['error'] === 0) {
        $uploadDir = 'uploads/documents/';
        if (!file_exists($uploadDir)) {
            mkdir($uploadDir, 0777, true);
        }

        $extension = strtolower(pathinfo($_FILES['idDocument']['name'], PATHINFO_EXTENSION));
        $fileName = 'id_' . uniqid() . '_' . time() . '.' . $extension;
        $idDocumentPath = $uploadDir . $fileName;

        if (!move_uploaded_file($_FILES['idDocument']['tmp_name'], $idDocumentPath)) {
            $_SESSION['error'] = 'Error uploading ID document.';
            header('Location: register.php');
            exit;
        }

        $idDocumentPath = $fileName;
    }

    // Hash password and PIN
    $hashedPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
    $hashedPin = password_hash($_POST['pin'], PASSWORD_DEFAULT);

    // Generate email verification code
    $verificationCode = bin2hex(random_bytes(16));
    $verificationExpiry = date('Y-m-d H:i:s', strtotime('+24 hours'));

    // Prepare additional fields
    $ssn = isset($_POST['ssn']) ? $_POST['ssn'] : '';
    $mothersMaidenName = isset($_POST['mothersMaidenName']) ? $_POST['mothersMaidenName'] : '';
    $city = isset($_POST['city']) ? $_POST['city'] : '';
    $state = isset($_POST['state']) ? $_POST['state'] : '';
    $zipCode = isset($_POST['zipCode']) ? $_POST['zipCode'] : '';
    $fullAddress = $_POST['address'];
    
    // Add city, state, zip if provided
    if (!empty($city) || !empty($state) || !empty($zipCode)) {
        $fullAddress .= ", " . $city;
        if (!empty($state)) $fullAddress .= ", " . $state;
        if (!empty($zipCode)) $fullAddress .= " " . $zipCode;
    }

    // Insert user data with additional fields
    $stmt = $db->prepare("
        INSERT INTO users (
            first_name, last_name, email, phone, date_of_birth, 
            gender, country, address, account_type, currency, 
            username, password, pin, account_number, profile_picture,
            employment_status, income_source, status, verification_code, verification_expiry,
            ssn, mothers_maiden_name, city, state, zip_code, created_at
        ) VALUES (
            :firstName, :lastName, :email, :phone, :dob,
            :gender, :country, :address, :accountType, :currency,
            :username, :password, :pin, :accountNumber, :profilePicture,
            :employmentStatus, :incomeSource, 'pending', :verificationCode, :verificationExpiry,
            :ssn, :mothersMaidenName, :city, :state, :zipCode, NOW()
        )
    ");

    $stmt->execute([
        ':firstName' => $_POST['firstName'],
        ':lastName' => $_POST['lastName'],
        ':email' => $_POST['email'],
        ':phone' => $_POST['phone'],
        ':dob' => $_POST['dob'],
        ':gender' => $_POST['gender'],
        ':country' => $_POST['country'],
        ':address' => $fullAddress,
        ':accountType' => $_POST['accountType'],
        ':currency' => $_POST['currency'],
        ':username' => $_POST['username'],
        ':password' => $hashedPassword,
        ':pin' => $hashedPin,
        ':accountNumber' => $accountNumber,
        ':profilePicture' => $profilePicture,
        ':employmentStatus' => $_POST['employmentStatus'],
        ':incomeSource' => $_POST['incomeSource'],
        ':verificationCode' => $verificationCode,
        ':verificationExpiry' => $verificationExpiry,
        ':ssn' => $ssn,
        ':mothersMaidenName' => $mothersMaidenName,
        ':city' => $city,
        ':state' => $state,
        ':zipCode' => $zipCode
    ]);

    $userId = $db->lastInsertId();

    // Insert next of kin data
    $stmt = $db->prepare("
        INSERT INTO next_of_kin (
            user_id, full_name, email, phone, address, relationship, created_at
        ) VALUES (
            :userId, :fullName, :email, :phone, :address, :relationship, NOW()
        )
    ");

    $stmt->execute([
        ':userId' => $userId,
        ':fullName' => $_POST['kinName'],
        ':email' => $_POST['kinEmail'],
        ':phone' => $_POST['kinPhone'],
        ':address' => $_POST['kinAddress'],
        ':relationship' => $_POST['kinRelationship'] ?? ''
    ]);

    // Create initial balance record
    $stmt = $db->prepare("
        INSERT INTO account_balances (
            user_id, account_number, currency, balance, last_updated
        ) VALUES (
            :userId, :accountNumber, :currency, 0, NOW()
        )
    ");

    $stmt->execute([
        ':userId' => $userId,
        ':accountNumber' => $accountNumber,
        ':currency' => $_POST['currency']
    ]);

    // Store financial profile information if provided
    if (isset($_POST['hasOtherBankAccounts']) && $_POST['hasOtherBankAccounts'] === 'yes' && !empty($_POST['otherBankAccounts'])) {
        $stmt = $db->prepare("
            INSERT INTO user_financial_profile (
                user_id, field_name, field_value, created_at
            ) VALUES (
                :userId, 'other_bank_accounts', :value, NOW()
            )
        ");
                $stmt->execute([
            ':userId' => $userId,
            ':value' => $_POST['otherBankAccounts']
        ]);
    }

    if (isset($_POST['hasOtherCreditCards']) && $_POST['hasOtherCreditCards'] === 'yes') {
        $creditCardInfo = !empty($_POST['otherCreditCards']) ? $_POST['otherCreditCards'] : '';
        $creditCardCount = !empty($_POST['creditCardCount']) ? $_POST['creditCardCount'] : '0';
        
        $stmt = $db->prepare("
            INSERT INTO user_financial_profile (
                user_id, field_name, field_value, created_at
            ) VALUES 
            (:userId, 'other_credit_cards', :value, NOW()),
            (:userId, 'credit_card_count', :count, NOW())
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':value' => $creditCardInfo,
            ':count' => $creditCardCount
        ]);
    }

    if (isset($_POST['hasInvestmentAccounts']) && $_POST['hasInvestmentAccounts'] === 'yes' && !empty($_POST['investmentAccounts'])) {
        $stmt = $db->prepare("
            INSERT INTO user_financial_profile (
                user_id, field_name, field_value, created_at
            ) VALUES (
                :userId, 'investment_accounts', :value, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':value' => $_POST['investmentAccounts']
        ]);
    }

    if (isset($_POST['has401k']) && $_POST['has401k'] === 'yes' && !empty($_POST['401kAccounts'])) {
        $stmt = $db->prepare("
            INSERT INTO user_financial_profile (
                user_id, field_name, field_value, created_at
            ) VALUES (
                :userId, '401k_accounts', :value, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':value' => $_POST['401kAccounts']
        ]);
    }

    if (isset($_POST['hasHomeEquity']) && $_POST['hasHomeEquity'] === 'yes' && !empty($_POST['homeEquityAccounts'])) {
        $stmt = $db->prepare("
            INSERT INTO user_financial_profile (
                user_id, field_name, field_value, created_at
            ) VALUES (
                :userId, 'home_equity_accounts', :value, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':value' => $_POST['homeEquityAccounts']
        ]);
    }

    if (isset($_POST['hasBusinessAccount']) && $_POST['hasBusinessAccount'] === 'yes' && !empty($_POST['businessAccounts'])) {
        $stmt = $db->prepare("
            INSERT INTO user_financial_profile (
                user_id, field_name, field_value, created_at
            ) VALUES (
                :userId, 'business_accounts', :value, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':value' => $_POST['businessAccounts']
        ]);
    }

    if (isset($_POST['hasMortgage']) && $_POST['hasMortgage'] === 'yes' && !empty($_POST['mortgageAccounts'])) {
        $stmt = $db->prepare("
            INSERT INTO user_financial_profile (
                user_id, field_name, field_value, created_at
            ) VALUES (
                :userId, 'mortgage_accounts', :value, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':value' => $_POST['mortgageAccounts']
        ]);
    }

    // Store document information if uploaded
    if (!empty($utilityBillPath)) {
        $stmt = $db->prepare("
            INSERT INTO user_documents (
                user_id, document_type, file_path, uploaded_at
            ) VALUES (
                :userId, 'utility_bill', :filePath, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':filePath' => $utilityBillPath
        ]);
    }

    if (!empty($idDocumentPath)) {
        $stmt = $db->prepare("
            INSERT INTO user_documents (
                user_id, document_type, file_path, uploaded_at
            ) VALUES (
                :userId, 'id_document', :filePath, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':filePath' => $idDocumentPath
        ]);
    }

    // Store security questions and answers if provided
    if (!empty($_POST['securityQuestion1']) && !empty($_POST['securityAnswer1'])) {
        $stmt = $db->prepare("
            INSERT INTO security_questions (
                user_id, question_key, answer, created_at
            ) VALUES (
                :userId, :questionKey, :answer, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':questionKey' => $_POST['securityQuestion1'],
            ':answer' => password_hash($_POST['securityAnswer1'], PASSWORD_DEFAULT)
        ]);
    }

    if (!empty($_POST['securityQuestion2']) && !empty($_POST['securityAnswer2'])) {
        $stmt = $db->prepare("
            INSERT INTO security_questions (
                user_id, question_key, answer, created_at
            ) VALUES (
                :userId, :questionKey, :answer, NOW()
            )
        ");
        $stmt->execute([
            ':userId' => $userId,
            ':questionKey' => $_POST['securityQuestion2'],
            ':answer' => password_hash($_POST['securityAnswer2'], PASSWORD_DEFAULT)
        ]);
    }

    // Update two-factor authentication preference
    if (isset($_POST['enableTwoFactor'])) {
        $twoFactorEnabled = ($_POST['enableTwoFactor'] === 'on') ? 1 : 0;
        $stmt = $db->prepare("UPDATE users SET two_factor_enabled = ? WHERE id = ?");
        $stmt->execute([$twoFactorEnabled, $userId]);
    }

    // Create admin notification for new user registration
    if (function_exists('notifyAdminNewUser')) {
        try {
            notifyAdminNewUser(
                $db, 
                $userId, 
                $_POST['firstName'] . ' ' . $_POST['lastName'], 
                $_POST['email']
            );
        } catch (Exception $e) {
            // Log but don't stop the process
            error_log("Failed to create admin notification: " . $e->getMessage());
        }
    }

    // Commit transaction
    $db->commit();

    // Send registration confirmation email
    $userName = $_POST['firstName'] . ' ' . $_POST['lastName'];
    
    try {
        // Log email attempt
        error_log("Attempting to send registration email to: " . $_POST['email']);
        
        // Send the email
        $emailSent = sendRegistrationEmail($_POST['email'], $userName, $accountNumber, $verificationCode);
        
        // Log the result
        if ($emailSent) {
            error_log("Registration email sent successfully to: " . $_POST['email']);
            $_SESSION['email_sent'] = true;
        } else {
            error_log("Failed to send registration email to: " . $_POST['email']);
            $_SESSION['email_sent'] = false;
        }
    } catch (Exception $e) {
        // Log the exception but continue with the registration process
        error_log("Exception when sending registration email: " . $e->getMessage());
        $_SESSION['email_sent'] = false;
    }

    // Store success message and account details in session
    $_SESSION['success'] = true;
    $_SESSION['account_number'] = $accountNumber;
    $_SESSION['registered_email'] = $_POST['email'];
    
    // Add debug information if email sending failed
    if (!isset($_SESSION['email_sent']) || $_SESSION['email_sent'] === false) {
        $_SESSION['email_debug'] = [
            'attempted' => true,
            'time' => date('Y-m-d H:i:s'),
            'to' => $_POST['email']
        ];
    }

    // Redirect to success page
    header('Location: registration_success.php');
    exit;

} catch (Exception $e) {
    // Rollback transaction on error
    if (isset($db) && $db->inTransaction()) {
        $db->rollBack();
    }

    // Delete uploaded files if they exist
    if (!empty($targetPath) && file_exists($targetPath)) {
        unlink($targetPath);
    }
    if (!empty($utilityBillPath) && file_exists($utilityBillPath)) {
        unlink($utilityBillPath);
    }
    if (!empty($idDocumentPath) && file_exists($idDocumentPath)) {
        unlink($idDocumentPath);
    }

    // Log detailed error
    error_log("Registration error: " . $e->getMessage());
    error_log("Error trace: " . $e->getTraceAsString());

    // Store error message and redirect
    $_SESSION['error'] = "Registration failed: " . $e->getMessage();
    header('Location: register.php');
    exit;
}
?>