<?php

namespace App\Controllers\User;

use App\Controllers\BaseController;
use App\Models\User\UserModel;
use App\Traits\PatchValidationTrait;
use App\Traits\ResponseTrait;

/**
 * User Management Controller
 * Handles CRUD operations for users
 */
class UserController extends BaseController
{
    use ResponseTrait;
    use PatchValidationTrait;

    protected $model;
    protected $db;

    public function __construct()
    {
        $this->db = \Config\Database::connect();
        $this->model = new UserModel();
    }

    /**
     * List users with pagination and search
     * GET /api/user?page=1&per_page=20&search=term
     */
    public function index()
    {
        try {
            $page = (int)($this->request->getGet('page') ?? 1);
            $perPage = (int)($this->request->getGet('per_page') ?? 20);
            $search = $this->request->getGet('search');

            // Build query
            $builder = $this->model->where('DelDate', null);

            // Apply search if provided
            if ($search) {
                $builder->groupStart()
                    ->like('Username', $search)
                    ->orLike('Email', $search)
                    ->orLike('Name', $search)
                    ->groupEnd();
            }

            // Get total count for pagination
            $total = $builder->countAllResults(false);

            // Get paginated results
            $users = $builder
                ->orderBy('UserID', 'DESC')
                ->limit($perPage, ($page - 1) * $perPage)
                ->findAll();

            return $this->respond([
                'status' => 'success',
                'message' => 'Users retrieved successfully',
                'data' => [
                    'users' => $users,
                    'pagination' => [
                        'current_page' => $page,
                        'per_page' => $perPage,
                        'total' => $total,
                        'total_pages' => ceil($total / $perPage)
                    ]
                ]
            ], 200);

        } catch (\Exception $e) {
            log_message('error', 'UserController::index error: ' . $e->getMessage());
            return $this->respond([
                'status' => 'failed',
                'message' => 'Failed to retrieve users',
                'data' => null
            ], 500);
        }
    }

    /**
     * Get single user by ID
     * GET /api/user/(:num)
     */
    public function show($id)
    {
        try {
            $user = $this->model->where('UserID', $id)
                ->where('DelDate', null)
                ->first();

            if (empty($user)) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'User not found',
                    'data' => null
                ], 404);
            }

            return $this->respond([
                'status' => 'success',
                'message' => 'User retrieved successfully',
                'data' => $user
            ], 200);

        } catch (\Exception $e) {
            log_message('error', 'UserController::show error: ' . $e->getMessage());
            return $this->respond([
                'status' => 'failed',
                'message' => 'Failed to retrieve user',
                'data' => null
            ], 500);
        }
    }

    /**
     * Create new user
     * POST /api/user
     */
    public function create()
    {
        try {
            $data = $this->request->getJSON(true);

            // Validation rules
            $rules = [
                'Username' => 'required|min_length[3]|max_length[50]|is_unique[users.Username]',
                'Email' => 'required|valid_email|is_unique[users.Email]',
            ];

            if (!$this->validateData($data, $rules)) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'Validation failed',
                    'data' => $this->validator->getErrors()
                ], 400);
            }

            // Set default values
            $data['IsActive'] = $data['IsActive'] ?? true;
            $data['CreatedAt'] = date('Y-m-d H:i:s');

            $userId = $this->model->insert($data);

            if (!$userId) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'Failed to create user',
                    'data' => null
                ], 500);
            }

            return $this->respond([
                'status' => 'success',
                'message' => 'User created successfully',
                'data' => [
                    'UserID' => $userId,
                    'Username' => $data['Username'],
                    'Email' => $data['Email']
                ]
            ], 201);

        } catch (\Exception $e) {
            log_message('error', 'UserController::create error: ' . $e->getMessage());
            return $this->respond([
                'status' => 'failed',
                'message' => 'Failed to create user',
                'data' => null
            ], 500);
        }
    }

    /**
     * Update existing user
     * PATCH /api/user/(:num)
     */
    public function update($id)
    {
        try {
            $data = $this->requirePatchPayload($this->request->getJSON(true));
            if ($data === null) {
                return;
            }

            if (empty($id) || !ctype_digit((string) $id)) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'UserID is required',
                    'data' => null
                ], 400);
            }

            if (isset($data['UserID']) && (string) $data['UserID'] !== (string) $id) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'UserID in URL does not match body',
                    'data' => null
                ], 400);
            }

            $userId = (int) $id;

            // Check if user exists
            $user = $this->model->where('UserID', $userId)
                ->where('DelDate', null)
                ->first();

            if (empty($user)) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'User not found',
                    'data' => null
                ], 404);
            }

            // Remove UserID from data array
            unset($data['UserID']);

            // Don't allow updating these fields
            unset($data['CreatedAt']);
            unset($data['Username']); // Username should not change

            $data['UpdatedAt'] = date('Y-m-d H:i:s');

            $updated = $this->model->update($userId, $data);

            if (!$updated) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'Failed to update user',
                    'data' => null
                ], 500);
            }

            return $this->respond([
                'status' => 'success',
                'message' => 'User updated successfully',
                'data' => [
                    'UserID' => $userId,
                    'updated_fields' => array_keys($data)
                ]
            ], 200);

        } catch (\Exception $e) {
            log_message('error', 'UserController::update error: ' . $e->getMessage());
            return $this->respond([
                'status' => 'failed',
                'message' => 'Failed to update user',
                'data' => null
            ], 500);
        }
    }

    /**
     * Delete user (soft delete)
     * DELETE /api/user/(:num)
     */
    public function delete($id)
    {
        try {
            // Check if user exists
            $user = $this->model->where('UserID', $id)
                ->where('DelDate', null)
                ->first();

            if (empty($user)) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'User not found',
                    'data' => null
                ], 404);
            }

            // Soft delete by setting DelDate
            $deleted = $this->model->update($id, [
                'DelDate' => date('Y-m-d H:i:s'),
                'IsActive' => false
            ]);

            if (!$deleted) {
                return $this->respond([
                    'status' => 'failed',
                    'message' => 'Failed to delete user',
                    'data' => null
                ], 500);
            }

            return $this->respond([
                'status' => 'success',
                'message' => 'User deleted successfully',
                'data' => ['UserID' => $id]
            ], 200);

        } catch (\Exception $e) {
            log_message('error', 'UserController::delete error: ' . $e->getMessage());
            return $this->respond([
                'status' => 'failed',
                'message' => 'Failed to delete user',
                'data' => null
            ], 500);
        }
    }
}
