<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\ProfileModel;
use App\Models\MediaModel;
use App\Models\QRCodeModel;
use App\Models\ActivityLogModel;
use App\Libraries\FileUploadHandler;
use App\Libraries\QRCodeGenerator;

/**
 * UsersController — full CRUD for digital profiles.
 */
class UsersController extends BaseController
{
    private ProfileModel      $profileModel;
    private MediaModel        $mediaModel;
    private QRCodeModel       $qrModel;
    private ActivityLogModel  $logModel;
    private FileUploadHandler $uploader;
    private QRCodeGenerator   $qrGenerator;

    public function __construct()
    {
        $this->profileModel = new ProfileModel();
        $this->mediaModel   = new MediaModel();
        $this->qrModel      = new QRCodeModel();
        $this->logModel     = new ActivityLogModel();
        $this->uploader     = new FileUploadHandler();
        $this->qrGenerator  = new QRCodeGenerator();
    }

    // ----------------------------------------------------------------
    // GET /admin/users
    // ----------------------------------------------------------------
    public function index(): string
    {
        $filters = [
            'search'    => $this->request->getGet('search') ?? '',
            'is_active' => $this->request->getGet('is_active') ?? '',
        ];

        $perPage = (int) ($this->request->getGet('per_page') ?? 15);
        $result  = $this->profileModel->getList($filters, $perPage);

        return $this->render('admin/users/index', [
            'title'    => lang('Admin.users'),
            'profiles' => $result['data'],
            'pager'    => $result['pager'],
            'filters'  => $filters,
            'perPage'  => $perPage,
        ]);
    }

    // ----------------------------------------------------------------
    // GET /admin/users/create
    // ----------------------------------------------------------------
    public function create(): string
    {
        return $this->render('admin/users/create', [
            'title'      => lang('Admin.add_user'),
            'validation' => null,
        ]);
    }

    // ----------------------------------------------------------------
    // POST /admin/users/store
    // ----------------------------------------------------------------
    public function store()
    {
        $rules = $this->getValidationRules();

        if (! $this->validate($rules)) {
            return redirect()->back()
                             ->withInput()
                             ->with('errors', $this->validator->getErrors());
        }

        $data = $this->buildProfileData();

        // Profile photo upload
        $photoFile = $this->request->getFile('profile_photo');
        if ($photoFile && $photoFile->isValid() && ! $photoFile->hasMoved()) {
            $result = $this->uploader->uploadImage($photoFile, 'profiles');
            if ($result['success']) {
                $data['profile_photo'] = $result['path'];
            } else {
                return redirect()->back()->withInput()->with('error', $result['message']);
            }
        }

        // Company logo upload
        $logoFile = $this->request->getFile('company_logo');
        if ($logoFile && $logoFile->isValid() && ! $logoFile->hasMoved()) {
            $result = $this->uploader->uploadImage($logoFile, 'logos');
            if ($result['success']) {
                $data['company_logo'] = $result['path'];
            } else {
                return redirect()->back()->withInput()->with('error', $result['message']);
            }
        }

        $data['created_by'] = $this->adminId();
        $data['slug']       = $this->profileModel->generateSlug($data['name']);

        $profileId = $this->profileModel->insert($data);

        // Handle media uploads
        $this->handleMediaUploads((int) $profileId);

        // Auto-generate QR code using the profile photo (if one was uploaded)
        $this->autoGenerateQr((int) $profileId, $data['profile_photo'] ?? null);

        $this->logModel->log('create', 'profiles', (int) $profileId,
            'Created profile: ' . $data['name']);

        $this->flashSuccess(lang('Admin.user_created'));
        return redirect()->to(site_url('admin/users'));
    }

    // ----------------------------------------------------------------
    // GET /admin/users/edit/:id
    // ----------------------------------------------------------------
    public function edit(int $id): string
    {
        $profile = $this->profileModel->find($id);
        if (! $profile) {
            $this->flashError(lang('Admin.user_not_found'));
            return redirect()->to(site_url('admin/users'))->send() ?: '';
        }

        return $this->render('admin/users/edit', [
            'title'   => lang('Admin.edit_user'),
            'profile' => $profile,
            'videos'  => $this->mediaModel->getByProfile($id, 'video'),
            'docs'    => $this->mediaModel->getByProfile($id, 'document'),
            'gallery' => $this->mediaModel->getByProfile($id, 'gallery'),
        ]);
    }

    // ----------------------------------------------------------------
    // POST /admin/users/update/:id
    // ----------------------------------------------------------------
    public function update(int $id)
    {
        $profile = $this->profileModel->find($id);
        if (! $profile) {
            $this->flashError(lang('Admin.user_not_found'));
            return redirect()->to(site_url('admin/users'));
        }

        $rules = $this->getValidationRules($id);
        if (! $this->validate($rules)) {
            return redirect()->back()
                             ->withInput()
                             ->with('errors', $this->validator->getErrors());
        }

        $data = $this->buildProfileData();

        // Profile photo upload
        $photoFile = $this->request->getFile('profile_photo');
        if ($photoFile && $photoFile->isValid() && ! $photoFile->hasMoved()) {
            $result = $this->uploader->uploadImage($photoFile, 'profiles');
            if ($result['success']) {
                if (! empty($profile['profile_photo'])) {
                    $this->uploader->deleteFile($profile['profile_photo']);
                }
                $data['profile_photo'] = $result['path'];
            } else {
                return redirect()->back()->withInput()->with('error', $result['message']);
            }
        }

        // Company logo upload
        $logoFile = $this->request->getFile('company_logo');
        if ($logoFile && $logoFile->isValid() && ! $logoFile->hasMoved()) {
            $result = $this->uploader->uploadImage($logoFile, 'logos');
            if ($result['success']) {
                if (! empty($profile['company_logo'])) {
                    $this->uploader->deleteFile($profile['company_logo']);
                }
                $data['company_logo'] = $result['path'];
            } else {
                return redirect()->back()->withInput()->with('error', $result['message']);
            }
        }

        // Handle "remove logo" checkbox
        if ($this->request->getPost('remove_company_logo') && ! ($logoFile && $logoFile->isValid())) {
            if (! empty($profile['company_logo'])) {
                $this->uploader->deleteFile($profile['company_logo']);
            }
            $data['company_logo'] = null;
        }

        $this->profileModel->update($id, $data);

        // Handle media uploads
        $this->handleMediaUploads($id);

        // Auto-regenerate QR code whenever a new profile photo is uploaded
        if (isset($data['profile_photo'])) {
            $this->autoGenerateQr($id, $data['profile_photo']);
        }

        $this->logModel->log('update', 'profiles', $id,
            'Updated profile: ' . ($data['name'] ?? $profile['name']));

        $this->flashSuccess(lang('Admin.user_updated'));
        return redirect()->to(site_url('admin/users'));
    }

    // ----------------------------------------------------------------
    // GET /admin/users/view/:id
    // ----------------------------------------------------------------
    public function view(int $id): string
    {
        $profile = $this->profileModel->find($id);
        if (! $profile) {
            $this->flashError(lang('Admin.user_not_found'));
            return redirect()->to(site_url('admin/users'))->send() ?: '';
        }

        return $this->render('admin/users/view', [
            'title'   => lang('Admin.view_user'),
            'profile' => $profile,
            'videos'  => $this->mediaModel->getByProfile($id, 'video'),
            'docs'    => $this->mediaModel->getByProfile($id, 'document'),
            'gallery' => $this->mediaModel->getByProfile($id, 'gallery'),
            'qr'      => model('App\Models\QRCodeModel')->getByProfile($id),
        ]);
    }

    // ----------------------------------------------------------------
    // POST /admin/users/delete/:id
    // ----------------------------------------------------------------
    public function delete(int $id)
    {
        $profile = $this->profileModel->find($id);
        if ($profile) {
            // Soft delete
            $this->profileModel->delete($id);
            $this->logModel->log('delete', 'profiles', $id,
                'Deleted profile: ' . $profile['name']);
            $this->flashSuccess(lang('Admin.user_deleted'));
        }
        return redirect()->to(site_url('admin/users'));
    }

    // ----------------------------------------------------------------
    // POST /admin/users/toggle/:id
    // ----------------------------------------------------------------
    public function toggle(int $id)
    {
        $profile = $this->profileModel->find($id);
        if ($profile) {
            $newStatus = $profile['is_active'] ? 0 : 1;
            $this->profileModel->update($id, ['is_active' => $newStatus]);
            $this->logModel->log('toggle', 'profiles', $id,
                ($newStatus ? 'Activated' : 'Deactivated') . ' profile: ' . $profile['name']);
        }
        return redirect()->back();
    }

    // ----------------------------------------------------------------
    // POST /admin/users/delete-media/:id
    // ----------------------------------------------------------------
    public function deleteMedia(int $id)
    {
        $media = $this->mediaModel->find($id);
        if ($media) {
            $this->mediaModel->deleteWithFile($id);
            $this->logModel->log('delete', 'profile_media', $id, 'Deleted media file');
        }
        return redirect()->back();
    }

    // ----------------------------------------------------------------
    // GET /admin/users/export  (CSV)
    // ----------------------------------------------------------------
    public function export()
    {
        $profiles = $this->profileModel
                         ->select('name,company_name,designation,email,mobile,address,is_active,created_at')
                         ->findAll();

        $filename = 'profiles_export_' . date('YmdHis') . '.csv';

        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');

        $out = fopen('php://output', 'w');
        // UTF-8 BOM for Excel
        fputs($out, "\xEF\xBB\xBF");

        fputcsv($out, ['Name','Company','Designation','Email','Mobile','Address','Active','Created At']);
        foreach ($profiles as $p) {
            fputcsv($out, [
                $p['name'], $p['company_name'], $p['designation'],
                $p['email'], $p['mobile'], $p['address'],
                $p['is_active'] ? 'Yes' : 'No', $p['created_at'],
            ]);
        }
        fclose($out);
        exit;
    }

    // ----------------------------------------------------------------
    // Private helpers
    // ----------------------------------------------------------------

    private function getValidationRules(?int $id = null): array
    {
        $slugRule = 'permit_empty|alpha_dash|max_length[255]|is_unique[profiles.slug,id,' . ($id ?? 0) . ']';

        return [
            'name'          => 'required|max_length[255]',
            'email'         => 'permit_empty|valid_email|max_length[191]',
            'mobile'        => 'permit_empty|max_length[20]',
            'profile_photo' => 'permit_empty',
            'company_logo'  => 'permit_empty',
        ];
    }

    private function buildProfileData(): array
    {
        $post = $this->request->getPost();

        return [
            'name'                => $post['name']                ?? '',
            'company_name'        => $post['company_name']        ?? null,
            'designation'         => $post['designation']         ?? null,
            'email'               => $post['email']               ?? null,
            'mobile'              => $post['mobile']              ?? null,
            'mobile_country_code' => $post['mobile_country_code'] ?? '+91',
            'about_us'            => $post['about_us']            ?? null,
            'address'             => $post['address']             ?? null,
            'latitude'            => ! empty($post['latitude'])   ? (float)$post['latitude']  : null,
            'longitude'           => ! empty($post['longitude'])  ? (float)$post['longitude'] : null,
            'linkedin'            => $post['linkedin']            ?? null,
            'instagram'           => $post['instagram']           ?? null,
            'facebook'            => $post['facebook']            ?? null,
            'twitter'             => $post['twitter']             ?? null,
            'youtube'             => $post['youtube']             ?? null,
            'is_active'           => isset($post['is_active']) ? 1 : 0,
        ];
    }

    private function handleMediaUploads(int $profileId): void
    {
        // Videos
        $videoFiles = $this->request->getFileMultiple('videos');
        if ($videoFiles) {
            foreach ($videoFiles as $file) {
                if ($file && $file->isValid() && ! $file->hasMoved()) {
                    $result = $this->uploader->uploadMedia($file, 'videos');
                    if ($result['success']) {
                        $this->mediaModel->insert([
                            'profile_id'    => $profileId,
                            'media_type'    => 'video',
                            'file_path'     => $result['path'],
                            'original_name' => $file->getClientName(),
                            'file_size'     => $file->getSize(),
                            'mime_type'     => $file->getClientMimeType(),
                        ]);
                    }
                }
            }
        }

        // Video URLs
        $videoUrls = $this->request->getPost('video_urls') ?? [];
        foreach ((array)$videoUrls as $url) {
            $url = trim($url);
            if ($url) {
                $this->mediaModel->insert([
                    'profile_id' => $profileId,
                    'media_type' => 'video',
                    'url'        => $url,
                ]);
            }
        }

        // Documents
        $docFiles = $this->request->getFileMultiple('documents');
        if ($docFiles) {
            foreach ($docFiles as $file) {
                if ($file && $file->isValid() && ! $file->hasMoved()) {
                    $result = $this->uploader->uploadMedia($file, 'documents');
                    if ($result['success']) {
                        $this->mediaModel->insert([
                            'profile_id'    => $profileId,
                            'media_type'    => 'document',
                            'file_path'     => $result['path'],
                            'original_name' => $file->getClientName(),
                            'file_size'     => $file->getSize(),
                            'mime_type'     => $file->getClientMimeType(),
                        ]);
                    }
                }
            }
        }

        // Gallery Images
        $galleryFiles = $this->request->getFileMultiple('gallery_images');
        if ($galleryFiles) {
            foreach ($galleryFiles as $file) {
                if ($file && $file->isValid() && ! $file->hasMoved()) {
                    $result = $this->uploader->uploadImage($file, 'gallery');
                    if ($result['success']) {
                        $this->mediaModel->insert([
                            'profile_id'    => $profileId,
                            'media_type'    => 'gallery',
                            'file_path'     => $result['path'],
                            'original_name' => $file->getClientName(),
                            'file_size'     => $file->getSize(),
                            'mime_type'     => $file->getClientMimeType(),
                        ]);
                    }
                }
            }
        }
    }

    /**
     * Auto-generate (or regenerate) the QR code for a profile.
     * Called automatically when a profile photo is uploaded via the
     * admin panel.  Mirrors the logic in MemberProfileController::regenerateQr().
     *
     * @param int         $profileId
     * @param string|null $photoRelPath  e.g. 'profiles/abc123.jpg'
     */
    private function autoGenerateQr(int $profileId, ?string $photoRelPath): void
    {
        try {
            $profile = $this->profileModel->find($profileId);
            if (! $profile) {
                return;
            }

            // Resolve the public QR URL (same priority order as QRCodeController)
            $envBase     = env('qr.baseURL');
            $settingBase = model('App\Models\SettingsModel')->getSetting('qr_base_url');

            if (! empty($envBase)) {
                $qrUrl = rtrim($envBase, '/') . '/' . $profile['slug'];
            } elseif (! empty($settingBase)) {
                $qrUrl = rtrim($settingBase, '/') . '/' . $profile['slug'];
            } else {
                $req      = service('request');
                $scheme   = $req->isSecure() ? 'https' : 'http';
                $host     = $req->getServer('HTTP_HOST');
                $basePath = rtrim(dirname($req->getServer('SCRIPT_NAME'), 2), '/\\');
                $qrUrl    = $scheme . '://' . $host . $basePath . '/profile/' . $profile['slug'];
            }

            // Resolve absolute path to the profile photo for the QR background
            $photoAbsPath = null;
            $photoRel     = $photoRelPath ?? $profile['profile_photo'] ?? null;
            if ($photoRel) {
                $candidate = FCPATH . 'uploads/' . ltrim($photoRel, '/');
                if (file_exists($candidate)) {
                    $photoAbsPath = $candidate;
                }
            }

            // Ensure QR output directory exists
            $qrDir = FCPATH . 'uploads/qrcodes/';
            if (! is_dir($qrDir)) {
                mkdir($qrDir, 0775, true);
            }

            $savePath = $qrDir . 'qr_profile_' . $profileId . '.png';

            $this->qrGenerator->generate([
                'data'       => $qrUrl,
                'save_path'  => $savePath,
                'photo_path' => $photoAbsPath,
                'foreground' => '#000000',
                'background' => '#FFFFFF',
                'size'       => 1200,
                'margin'     => 0,
            ]);

            $this->qrModel->upsert($profileId, [
                'file_path'  => 'qrcodes/qr_profile_' . $profileId . '.png',
                'qr_url'     => $qrUrl,
                'has_logo'   => 0,
                'logo_path'  => null,
                'foreground' => '#000000',
                'background' => '#FFFFFF',
            ]);

        } catch (\Throwable $e) {
            // Non-fatal — log but don't block the profile save
            log_message('error', '[UsersController] QR auto-generation failed for profile #'
                . $profileId . ': ' . $e->getMessage());
        }
    }
}
