<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Helpers\Auth;
use App\Helpers\Mailer;
use App\Helpers\Url;
use App\Models\User;
use App\Models\AuditLog;

class UserController extends Controller
{
    public function __construct()
    {
        parent::__construct();
        Auth::requireLogin();
    }

    private function requireAdmin()
    {
        if (!Auth::isAdmin()) {
            $_SESSION['error'] = 'You do not have permission to access that page.';
            $this->redirect('/dashboard');
        }
    }

    public function index()
    {
        $this->requireAdmin();
        $page = isset($_GET['page']) ? $_GET['page'] : 1;
        $search = isset($_GET['search']) ? $_GET['search'] : '';

        $userModel = new User();

        if ($search) {
            $stmt = $this->db->prepare("SELECT * FROM users WHERE first_name LIKE ? OR last_name LIKE ? OR email LIKE ? ORDER BY id DESC");
            $stmt->execute(array("%$search%", "%$search%", "%$search%"));
            $users = $stmt->fetchAll(\PDO::FETCH_OBJ);
            $total = count($users);
            $lastPage = 1;
        } else {
            $result = $userModel->paginate((int)$page, 10);
            $users = $result->data;
            $total = $result->total;
            $lastPage = $result->lastPage;
        }

        $pendingCount = $userModel->getPendingCount();

        $this->view('users/index', array(
            'users' => $users,
            'total' => $total,
            'page' => (int)$page,
            'lastPage' => $lastPage,
            'search' => $search,
            'pendingCount' => $pendingCount,
        ));
    }

    public function pending()
    {
        $this->requireAdmin();
        $userModel = new User();
        $users = $userModel->getPendingApproval();
        $this->view('users/pending', ['users' => $users]);
    }

    public function review($params)
    {
        $this->requireAdmin();
        $id = isset($params['id']) ? $params['id'] : null;
        $userModel = new User();
        $user = $userModel->find($id);

        if (!$user) {
            $_SESSION['error'] = 'User not found';
            $this->redirect('/users/pending');
        }

        $profile = null;
        $profileStmt = $this->db->prepare("SELECT * FROM member_profiles WHERE user_id = ?");
        $profileStmt->execute([$id]);
        if ($row = $profileStmt->fetch(\PDO::FETCH_OBJ)) {
            $profile = $row;
        }

        $auditStmt = $this->db->prepare("SELECT al.*, u.name AS user_name FROM audit_logs al LEFT JOIN users u ON al.user_id = u.id WHERE al.entity_type = 'users' AND al.entity_id = ? ORDER BY al.created_at DESC LIMIT 20");
        $auditStmt->execute([$id]);
        $auditLogs = $auditStmt->fetchAll(\PDO::FETCH_OBJ);

        $this->view('users/review', [
            'user' => $user,
            'profile' => $profile,
            'auditLogs' => $auditLogs,
        ]);
    }

    public function approve($params)
    {
        $this->requireAdmin();
        $id = isset($params['id']) ? $params['id'] : null;
        $userModel = new User();
        $user = $userModel->find($id);

        if (!$user) {
            $_SESSION['error'] = 'User not found';
            $this->redirect('/users/pending');
        }

        $userModel->update($id, [
            'approval_status' => 'approved',
            'approved_by' => Auth::id(),
            'approved_at' => date('Y-m-d H:i:s'),
        ]);

        // Send approval email
        $recipientName = $user->first_name ? trim($user->first_name . ' ' . $user->last_name) : $user->name;
        Mailer::sendApprovalEmail($user->email, $recipientName);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'user.approve', 'users', $id, "Approved membership for {$recipientName}");

        $_SESSION['success'] = "Membership approved for {$recipientName}. Email notification sent.";
        $this->redirect('/users/pending');
    }

    public function reject($params)
    {
        $this->requireAdmin();
        $id = isset($params['id']) ? $params['id'] : null;
        $userModel = new User();
        $user = $userModel->find($id);

        if (!$user) {
            $_SESSION['error'] = 'User not found';
            $this->redirect('/users/pending');
        }

        $reason = $_POST['rejection_reason'] ?? '';

        $userModel->update($id, [
            'approval_status' => 'rejected',
            'approved_by' => Auth::id(),
            'approved_at' => date('Y-m-d H:i:s'),
        ]);

        $recipientName = $user->first_name ? trim($user->first_name . ' ' . $user->last_name) : $user->name;
        Mailer::sendRejectionEmail($user->email, $recipientName, $reason);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'user.reject', 'users', $id, "Rejected membership for {$recipientName}");

        $_SESSION['success'] = "Membership rejected for {$recipientName}.";
        $this->redirect('/users/pending');
    }

    public function create()
    {
        $this->requireAdmin();
        $this->view('users/create');
    }

    public function store()
    {
        $this->requireAdmin();
        $name = isset($_POST['name']) ? $_POST['name'] : '';
        $email = isset($_POST['email']) ? $_POST['email'] : '';
        $password = isset($_POST['password']) ? $_POST['password'] : '';
        $role = (isset($_POST['role']) && $_POST['role'] === 'admin') ? 'admin' : 'member';
        $status = isset($_POST['status']) ? $_POST['status'] : 'active';

        $userModel = new User();
        if ($userModel->findByEmail($email)) {
            $_SESSION['error'] = 'Email already exists';
            $this->redirect('/users/create');
        }

        $userModel->create(array(
            'name' => $name,
            'first_name' => $_POST['first_name'] ?? '',
            'last_name' => $_POST['last_name'] ?? '',
            'email' => $email,
            'password' => password_hash($password, PASSWORD_DEFAULT),
            'role' => $role,
            'status' => $status,
            'approval_status' => 'approved',
        ));

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'user.create', 'users', $userModel->db->lastInsertId(), "Created user {$name}");

        $_SESSION['success'] = 'User created successfully';
        $this->redirect('/users');
    }

    public function edit($params)
    {
        $this->requireAdmin();
        $id = isset($params['id']) ? $params['id'] : null;
        $userModel = new User();
        $user = $userModel->find($id);

        if (!$user) {
            $_SESSION['error'] = 'User not found';
            $this->redirect('/users');
        }

        $this->view('users/edit', array('user' => $user));
    }

    public function update($params)
    {
        $this->requireAdmin();
        $id = isset($params['id']) ? $params['id'] : null;
        $userModel = new User();
        $user = $userModel->find($id);

        if (!$user) {
            $_SESSION['error'] = 'User not found';
            $this->redirect('/users');
        }

        $data = array(
            'name' => isset($_POST['name']) ? $_POST['name'] : $user->name,
            'first_name' => $_POST['first_name'] ?? $user->first_name,
            'last_name' => $_POST['last_name'] ?? $user->last_name,
            'email' => isset($_POST['email']) ? $_POST['email'] : $user->email,
            'role' => ((isset($_POST['role']) && $_POST['role'] === 'admin') ? 'admin' : 'member'),
            'status' => isset($_POST['status']) ? $_POST['status'] : $user->status,
            'approval_status' => $_POST['approval_status'] ?? $user->approval_status,
        );

        if (!empty($_POST['password'])) {
            $data['password'] = password_hash($_POST['password'], PASSWORD_DEFAULT);
        }

        $userModel->update($id, $data);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'user.update', 'users', $id, "Updated user {$user->name}");

        $_SESSION['success'] = 'User updated successfully';
        $this->redirect('/users');
    }

    public function delete($params)
    {
        $this->requireAdmin();
        $id = isset($params['id']) ? $params['id'] : null;
        $userModel = new User();
        $user = $userModel->find($id);

        if ($user) {
            $audit = new AuditLog();
            $audit->log(Auth::id(), 'user.delete', 'users', $id, "Deleted user {$user->name}");
            $userModel->delete($id);
            $_SESSION['success'] = 'User deleted successfully';
        }

        $this->redirect('/users');
    }

    public function profile()
    {
        $userModel = new User();
        $user = $userModel->find(Auth::id());
        $this->view('profile/index', array('user' => $user));
    }

    public function updateProfile()
    {
        $userModel = new User();
        $user = $userModel->find(Auth::id());

        $name = isset($_POST['name']) ? $_POST['name'] : $user->name;
        $email = isset($_POST['email']) ? $_POST['email'] : $user->email;

        $data = array('name' => $name, 'email' => $email);

        if (!empty($_POST['new_password'])) {
            if (!password_verify($_POST['current_password'], $user->password)) {
                $_SESSION['error'] = 'Current password is incorrect';
                $this->redirect('/profile');
            }
            if ($_POST['new_password'] !== $_POST['new_password_confirm']) {
                $_SESSION['error'] = 'New passwords do not match';
                $this->redirect('/profile');
            }
            $data['password'] = password_hash($_POST['new_password'], PASSWORD_DEFAULT);
        }

        $userModel->update(Auth::id(), $data);

        $_SESSION['user_name'] = $name;

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'profile.update', 'users', Auth::id(), 'Profile updated');

        $_SESSION['success'] = 'Profile updated successfully';
        $this->redirect('/profile');
    }

    public function updateAvatar()
    {
        if (!isset($_FILES['avatar']) || $_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
            $_SESSION['error'] = 'No file uploaded';
            $this->redirect('/profile');
        }

        $file = $_FILES['avatar'];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $allowed = array('jpg', 'jpeg', 'png', 'gif');

        if (!in_array($ext, $allowed)) {
            $_SESSION['error'] = 'Invalid file type. Allowed: jpg, jpeg, png, gif';
            $this->redirect('/profile');
        }

        $filename = 'avatar_' . Auth::id() . '_' . time() . '.' . $ext;
        $base = Url::getBaseUrl();
        $dest = $_SERVER['DOCUMENT_ROOT'] . $base . '/uploads/avatars/' . $filename;
        move_uploaded_file($file['tmp_name'], $dest);

        $path = '/uploads/avatars/' . $filename;
        $userModel = new User();
        $userModel->update(Auth::id(), array('avatar' => $path));

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'profile.avatar', 'users', Auth::id(), 'Avatar updated');

        $_SESSION['success'] = 'Profile photo updated successfully';
        $this->redirect('/profile');
    }

    public function reminderCron()
    {
        // This can be called via cron to send profile completion reminders
        $userModel = new User();
        $profileModel = new \App\Models\MemberProfile();

        $members = $userModel->where('approval_status', 'approved');
        $reminded = 0;

        foreach ($members as $member) {
            if ($member->profile_complete) continue;

            // Check if reminder was sent in last 7 days
            if ($member->last_reminder_sent) {
                $lastSent = strtotime($member->last_reminder_sent);
                if ((time() - $lastSent) < 604800) continue;
            }

            $recipientName = $member->first_name ? trim($member->first_name . ' ' . $member->last_name) : $member->name;
            if ($member->email) {
                Mailer::sendProfileReminder($member->email, $recipientName);
                $userModel->update($member->id, ['last_reminder_sent' => date('Y-m-d H:i:s')]);
                $reminded++;
            }
        }

        echo "Reminder sent to {$reminded} members";
    }
}
