<?php
/**
 * ===========================================
 * FLOWBOT DCI - USER MODEL
 * ===========================================
 * Handles user_myhashtag table operations
 */

declare(strict_types=1);

namespace FlowbotDCI\Models;

use FlowbotDCI\Core\Database;

class User
{
    private Database $db;
    private string $table = 'user_myhashtag';
    private array $defaults;

    public function __construct(Database $db, array $defaults = [])
    {
        $this->db = $db;
        $this->defaults = $defaults;
    }

    /**
     * Get or create user by username
     */
    public function getOrCreate(string $username): int
    {
        // Try to find existing
        $existing = $this->findByUsername($username);
        if ($existing) {
            return (int)$existing['ID'];
        }

        // Create new user
        return $this->createFromUsername($username);
    }

    /**
     * Find user by username
     */
    public function findByUsername(string $username): ?array
    {
        $stmt = $this->db->query(
            "SELECT * FROM {$this->table} WHERE username = ?",
            [$username]
        );
        $result = $stmt->fetch();
        return $result ?: null;
    }

    /**
     * Find user by ID
     */
    public function find(int $id): ?array
    {
        $stmt = $this->db->query(
            "SELECT * FROM {$this->table} WHERE ID = ?",
            [$id]
        );
        $result = $stmt->fetch();
        return $result ?: null;
    }

    /**
     * Create user from username (auto-generate other fields)
     * BUG-001 FIX: Added unique suffix to prevent email collisions
     * SECURITY FIX v1.1: Now uses cryptographically secure random_bytes()
     */
    private function createFromUsername(string $username): int
    {
        $parts = explode(' ', $username);
        $firstName = ucfirst($parts[0]);
        $lastName = ucfirst($parts[1] ?? 'User');

        // BUG-001: Generate unique email to prevent collisions
        // "John Doe" and "JohnDoe" would otherwise both become johndoe@digupdog.com
        // SECURITY FIX: Use cryptographically secure random_bytes()
        $baseEmail = strtolower(str_replace(' ', '', $username));
        $uniqueSuffix = bin2hex(random_bytes(4)); // 8 hex chars, cryptographically secure
        $email = $baseEmail . '_' . $uniqueSuffix . '@digupdog.com';

        $data = [
            'username'         => $username,
            'email'            => $email,
            'senha'            => password_hash($this->defaults['user_password'] ?? 'ChangeMe123!', PASSWORD_DEFAULT),
            'first_name'       => $firstName,
            'last_name'        => $lastName,
            'address'          => '123 Generated Street, Virtual City',
            'phone_number'     => '+1' . random_int(1000000000, 9999999999),
            'birthdate'        => date('Y-m-d', strtotime('-' . random_int(18, 50) . ' years')),
            'profile_picture'  => $this->defaults['profile_picture'] ?? 'https://example.com/default_profile.jpg',
            'bio'              => "Bio generated for $firstName $lastName",
            'gender'           => random_int(0, 1) === 0 ? 'male' : 'female',
            'status'           => 'active',
            'user_role'        => 'user',
            'privacy_settings' => json_encode(['visibility' => 'public']),
            'social_links'     => json_encode(['facebook' => '', 'twitter' => '']),
            'preferences'      => json_encode(['theme' => 'dark', 'notifications' => true]),
        ];

        return $this->insert($data);
    }

    /**
     * Insert new user
     */
    public function insert(array $data): int
    {
        $sql = "INSERT INTO {$this->table} (
            username, email, senha, first_name, last_name,
            address, phone_number, created_at, birthdate,
            profile_picture, bio, gender, status, user_role,
            privacy_settings, social_links, preferences
        ) VALUES (
            ?, ?, ?, ?, ?,
            ?, ?, NOW(), ?,
            ?, ?, ?, ?, ?,
            ?, ?, ?
        )";

        $this->db->query($sql, [
            $data['username'],
            $data['email'],
            $data['senha'],
            $data['first_name'],
            $data['last_name'],
            $data['address'],
            $data['phone_number'],
            $data['birthdate'],
            $data['profile_picture'],
            $data['bio'],
            $data['gender'],
            $data['status'],
            $data['user_role'],
            $data['privacy_settings'],
            $data['social_links'],
            $data['preferences'],
        ]);

        return (int)$this->db->lastInsertId();
    }

    /**
     * Update user
     */
    public function update(int $id, array $data): bool
    {
        $fields = [];
        $values = [];

        foreach ($data as $key => $value) {
            $fields[] = "$key = ?";
            $values[] = $value;
        }

        $values[] = $id;
        $sql = "UPDATE {$this->table} SET " . implode(', ', $fields) . " WHERE ID = ?";

        $this->db->query($sql, $values);
        return true;
    }

    /**
     * Delete user
     */
    public function delete(int $id): bool
    {
        $this->db->query("DELETE FROM {$this->table} WHERE ID = ?", [$id]);
        return true;
    }

    /**
     * Count total users
     */
    public function count(): int
    {
        $stmt = $this->db->query("SELECT COUNT(*) FROM {$this->table}");
        return (int)$stmt->fetchColumn();
    }

    /**
     * Get recent users
     */
    public function getRecent(int $limit = 10): array
    {
        $stmt = $this->db->query(
            "SELECT * FROM {$this->table} ORDER BY created_at DESC LIMIT ?",
            [$limit]
        );
        return $stmt->fetchAll();
    }
}
