<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Traits\InductionTrait;
use App\Models\InductionDocument;
use App\Models\InductionDocumentSignature;
use App\Models\EmpCompanyDetails;
use App\Models\Role;
use App\Jobs\SendInductionDocumentNotificationJob;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\File;

class InductionController extends Controller
{
    use InductionTrait;

    /**
     * View Inductions - List all documents with versions and signature counts
     * 
     * @param Request $request
     * @return JsonResponse
     */
        public function index(Request $request)
        {
            $ids = $this->getCustomerAndWorkspaceIds();
            $customerId = $ids['customer_id'];
            $workspaceId = $ids['workspace_id'];
            $query = InductionDocument::where('customer_id', $customerId)
                ->where('workspace_id', $workspaceId)
                ->where('del', '0');
            // Filter by title/search
            if ($request->filled('search')) {
                $search = $request->search;
                $query->where(function ($q) use ($search) {
                    $q->where('title', 'LIKE', "%{$search}%")
                        ->orWhere('version', 'LIKE', "%{$search}%")
                        ->orWhere('description', 'LIKE', "%{$search}%");
                });
            }
            // Check if document_id filter is provided
            $includeAllVersions = $request->boolean('all_versions', false);
            if ($request->filled('document_id')) {
                $documentId = $request->document_id;
                // Get the document
                $document = InductionDocument::where('id', $documentId)
                    ->where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('del', '0')
                    ->first();
                if (!$document) {
                    return $this->error('Document not found', 404);
                }
                // Find the root document (traverse up using parent_document_id)
                $rootDocumentId = $document->id;
                $currentDoc = $document;
                while ($currentDoc && $currentDoc->parent_document_id) {
                    $rootDocumentId = $currentDoc->parent_document_id;
                    $currentDoc = InductionDocument::where('id', $rootDocumentId)
                        ->where('customer_id', $customerId)
                        ->where('workspace_id', $workspaceId)
                        ->where('del', '0')
                        ->first();
                    if (!$currentDoc) {
                        break;
                    }
                }
                // Get all versions of this document chain
                $allVersions = InductionDocument::where(function ($q) use ($rootDocumentId) {
                    $q->where('id', $rootDocumentId)
                        ->orWhere('parent_document_id', $rootDocumentId);
                })
                    ->where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('del', '0')
                    ->orderBy('version', 'desc')
                    ->get();
                // Get the latest version to mark it as current
                $latestVersion = $this->getLatestVersion(
                    $rootDocumentId,
                    $customerId,
                    $workspaceId
                );
                $latestVersionId = $latestVersion ? $latestVersion->id : null;
                // Build result with all versions
                $result = [];
                foreach ($allVersions as $doc) {
                    $roleTypes = $doc->role_types ?? ['all'];
                    $stats = $this->getSignatureStatistics(
                        $doc->id,
                        $doc->version,
                        $roleTypes,
                        $customerId,
                        $workspaceId
                    );
                    // Check if this is the current (latest) version
                    $isCurrentVersion = ($doc->id === $latestVersionId);
                    $result[] = [
                        'id' => $doc->id,
                        'title' => $doc->title,
                        'document_type' => $doc->document_type,
                        'file_path' => $doc->file_path,
                        'role_types' => $doc->role_types ?? [],
                        'trade_ids' => $doc->trade_ids ?? [],
                        'trades' => $doc->trades->map(function($trade) {
                            return [
                                'id' => $trade->id,
                                'title' => $trade->title,
                            ];
                        })->toArray(),
                        'is_active' => $doc->is_active,
                        'current_version' => $doc->version,
                        'flag_current_version' => $isCurrentVersion,
                        'update_type' => $doc->update_type,
                        'parent_document_id' => $doc->parent_document_id,
                        'total_required' => $stats['total_required'],
                        'signed_count' => $stats['signed_count'],
                        'pending_count' => $stats['not_signed_count'],
                        'created_at' => $doc->created_at,
                    ];
                }
            } elseif ($includeAllVersions) {
                // Return only latest version of each document (regardless of active/inactive)
                $documents = $query->orderBy('title')->orderBy('version', 'desc')->get();
                // Group documents by their root document ID to find latest versions
                $processedRoots = [];
                $latestVersionsByTitle = [];
                foreach ($documents as $doc) {
                    // Find the root document ID for this document chain
                    $rootDocumentId = $doc->id;
                    $currentDoc = $doc;
                    // Traverse up to find the root document
                    while ($currentDoc && $currentDoc->parent_document_id) {
                        $rootDocumentId = $currentDoc->parent_document_id;
                        $currentDoc = $documents->firstWhere('id', $rootDocumentId);
                        if (!$currentDoc) {
                            // If parent not found in current collection, query database
                            $currentDoc = InductionDocument::where('id', $rootDocumentId)
                                ->where('customer_id', $customerId)
                                ->where('workspace_id', $workspaceId)
                                ->where('del', '0')
                                ->first();
                            if (!$currentDoc) {
                                break;
                            }
                        }
                    }
                    // If we haven't processed this root yet, find the latest version
                    if (!isset($processedRoots[$rootDocumentId])) {
                        $latestVersion = $this->getLatestVersion(
                            $rootDocumentId,
                            $customerId,
                            $workspaceId
                        );   
                        if ($latestVersion) {
                            $title = $latestVersion->title;
                            // Only store if we haven't seen this title yet
                            if (!isset($latestVersionsByTitle[$title])) {
                                $latestVersionsByTitle[$title] = $latestVersion;
                            }
                        }
                        $processedRoots[$rootDocumentId] = true;
                    }
                }
                // Calculate signature statistics for each latest version
                $result = [];
                foreach ($latestVersionsByTitle as $title => $latestDoc) {
                    $roleTypes = $latestDoc->role_types ?? ['all'];
                    $stats = $this->getSignatureStatistics(
                        $latestDoc->id,
                        $latestDoc->version,
                        $roleTypes,
                        $customerId,
                        $workspaceId
                    );   
                    $result[] = [
                        'id' => $latestDoc->id,
                        'title' => $title,
                        'document_type' => $latestDoc->document_type,
                        'file_path' => $latestDoc->file_path,
                        'role_types' => $latestDoc->role_types ?? [],
                        'trade_ids' => $latestDoc->trade_ids ?? [],
                        'trades' => $latestDoc->trades->map(function($trade) {
                            return [
                                'id' => $trade->id,
                                'title' => $trade->title,
                            ];
                        })->toArray(),
                        'current_version' => $latestDoc->version,
                        'flag_current_version' => true,
                        'is_active' => $latestDoc->is_active,
                        'update_type' => $latestDoc->update_type,
                        'total_required' => $stats['total_required'],
                        'signed_count' => $stats['signed_count'],
                        'pending_count' => $stats['not_signed_count'],
                        'created_at' => $latestDoc->created_at,
                    ];
                }
            } else {
                // Default behavior: Group by title and get latest version for each (only active documents)
                $documents = $query->orderBy('title')->orderBy('version', 'desc')->get();
                $groupedDocuments = [];
                foreach ($documents as $doc) {
                    // Only process active documents
                    if (!$doc->is_active) {
                        continue;
                    }
                    $title = $doc->title;
                    if (!isset($groupedDocuments[$title])) {
                        $groupedDocuments[$title] = [
                            'title' => $title,
                            'document_type' => $doc->document_type,
                            'role_types' => $doc->role_types ?? [],
                            'trade_ids' => $doc->trade_ids ?? [],
                            'latest_version' => $doc->version,
                            'latest_version_id' => $doc->id,
                            'file_path' => $doc->file_path,
                            'is_active' => $doc->is_active,
                            'update_type' => $doc->update_type,
                            'created_at' => $doc->created_at,
                        ];
                    }
                }
                // Calculate signature statistics for each document
                $result = [];
                foreach ($groupedDocuments as $title => $docData) {
                    $latestDoc = $documents->firstWhere('id', $docData['latest_version_id']);
                    if ($latestDoc) {
                        $roleTypes = $latestDoc->role_types ?? ['all'];
                        $stats = $this->getSignatureStatistics(
                            $latestDoc->id,
                            $latestDoc->version,
                            $roleTypes,
                            $customerId,
                            $workspaceId
                        );
                        $result[] = [
                            'id' => $latestDoc->id,
                            'title' => $title,
                            'document_type' => $docData['document_type'],
                            'file_path' => $docData['file_path'],
                            'role_types' => $docData['role_types'],
                            'trade_ids' => $latestDoc->trade_ids ?? [],
                            'trades' => $latestDoc->trades->map(function($trade) {
                                return [
                                    'id' => $trade->id,
                                    'title' => $trade->title,
                                ];
                            })->toArray(),
                            'current_version' => $docData['latest_version'],
                            'flag_current_version' => true,
                            'is_active' => $docData['is_active'],
                            'update_type' => $docData['update_type'],
                            'total_required' => $stats['total_required'],
                            'signed_count' => $stats['signed_count'],
                            'pending_count' => $stats['not_signed_count'],
                            'created_at' => $docData['created_at'],
                        ];
                    }
                }
            }
            
            // Calculate summary statistics (counts)
            $totalDocuments = count($result);
            $totalRequired = 0;
            $totalCompleted = 0;
            $totalPending = 0;
            
            foreach ($result as $doc) {
                $totalRequired += $doc['total_required'] ?? 0;
                $totalCompleted += $doc['signed_count'] ?? 0;
                $totalPending += $doc['pending_count'] ?? 0;
            }
            
            // Add summary to response
            $summary = [
                'total_documents' => $totalDocuments,
                'total_required' => $totalRequired,
                'completed' => $totalCompleted,
                'pending' => $totalPending,
            ];
            
            // Get the response from withCount and add summary
            $response = $this->withCount($result, 'Induction documents retrieved successfully');
            $responseData = json_decode($response->getContent(), true);
            $responseData['summary'] = $summary;
            
            return response()->json($responseData, $response->getStatusCode());
        }

        /**
         * Get existing documents for update dropdown
         * 
         * @param Request $request
         * @return JsonResponse
         */
        public function getDocumentsForUpdate(Request $request)
        {
            $ids = $this->getCustomerAndWorkspaceIds();
            $customerId = $ids['customer_id'];
            $workspaceId = $ids['workspace_id'];
            // Get unique document titles with their latest active version
            $documents = InductionDocument::where('customer_id', $customerId)
                ->where('workspace_id', $workspaceId)
                ->where('del', 0)
                ->where('is_active', true)
                ->select('id', 'title', 'document_type', 'version')
                ->orderBy('title')
                ->get()
                ->groupBy('title')
                ->map(function ($docs) {
                    $latest = $docs->sortByDesc('version')->first();
                    return [
                        'id' => $latest->id,
                        'title' => $latest->title,
                        'document_type' => $latest->document_type,
                        'current_version' => $latest->version,
                        'display_text' => $latest->title . ' (Currently ' . $latest->version . ') - ' . ($latest->document_type ?? 'N/A'),
                    ];
                })
                ->values();
            return $this->success($documents, 'Documents retrieved successfully');
        }

        /**
         * Store a new induction document
         * 
         * @param Request $request
         * @return JsonResponse
         */
        public function store(Request $request)
        {
            $validator = Validator::make($request->all(), [
                'title' => 'required|string|max:255',
                'document_type' => 'nullable|string|max:255',
                'role_types' => 'required|array',
                'role_types.*' => 'in:internal,external,subcontractor,all',
                'trade_ids' => 'nullable|array',
                'trade_ids.*' => 'integer|exists:trades,id',
                'file' => 'required|file|mimes:pdf|max:10240',
                'description' => 'nullable|string',
                'notify_all_employees' => 'nullable|boolean',
            ]);
            if ($validator->fails()) {
                return $this->error($validator->errors()->first(), 422);
            }
            $ids = $this->getCustomerAndWorkspaceIds();
            if ($ids['flag'] != 'customer') {
                return $this->error('Unauthorized', 401);
            }
            // Upload file
            $uploadResult = $this->uploadInductionDocument($request->file('file'));
            if (isset($uploadResult['error'])) {
                return $this->error($uploadResult['error'], 422);
            }
            // Prepare trade_ids - ensure it's a valid array or null
            $tradeIds = null;
            if ($request->filled('trade_ids') && is_array($request->trade_ids)) {
                $tradeIds = array_values(array_filter($request->trade_ids, function($id) {
                    return is_numeric($id) && $id > 0;
                }));
                // If empty after filtering, set to null
                if (empty($tradeIds)) {
                    $tradeIds = null;
                }
            }
            
            // Create document
            $document = InductionDocument::create([
                'title' => $request->title,
                'document_type' => $request->document_type ?? 'onboarding',
                'role_types' => $request->role_types,
                'trade_ids' => $tradeIds,
                'version' => 'v1',
                'file_path' => $uploadResult['path'],
                'is_active' => true,
                'update_type' => null,
                'parent_document_id' => null,
                'customer_id' => $ids['customer_id'],
                'workspace_id' => $ids['workspace_id'],
                'created_by' => Auth::id(),
                'description' => $request->description,
                'del' => '0', // Enum expects string value
            ]);
            // Check if notify_all_employees is requested
            if ($request->boolean('notify_all_employees', false)) {
                $this->notifyEmployeesAboutDocument($document, $ids['customer_id'], $ids['workspace_id'], false, false);
            }
            return $this->success($document, 'Induction document created successfully');
        }

        /**
         * Update existing document - Create new version
         * 
         * @param Request $request
         * @return JsonResponse
         */
        public function updateDocument(Request $request)
        {
            $validator = Validator::make($request->all(), [
                'document_id' => 'required|integer|exists:induction_documents,id',
                'update_type' => 'required|in:major,minor',
                'file' => 'required|file|mimes:pdf|max:10240',
                'title' => 'nullable|string|max:255',
                'trade_ids' => 'nullable|array',
                'trade_ids.*' => 'integer|exists:trades,id',
                'notify_all_employees' => 'nullable|boolean',
            ]);
            if ($validator->fails()) {
                return $this->error($validator->errors()->first(), 422);
            }
            $ids = $this->getCustomerAndWorkspaceIds();
            if ($ids['flag'] != 'customer') {
                return $this->error('Unauthorized', 401);
            }
            // Get parent document
            $parentDocument = InductionDocument::where('id', $request->document_id)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->first();
            if (!$parentDocument) {
                return $this->error('Document not found', 404);
            }
            // Upload new file
            $uploadResult = $this->uploadInductionDocument($request->file('file'));
            if (isset($uploadResult['error'])) {
                return $this->error($uploadResult['error'], 422);
            }
            // Deactivate old version
            $parentDocument->update(['is_active' => false]);
            // Find the root document (the one with parent_document_id = null)
            $rootDocumentId = $parentDocument->id;
            $currentDoc = $parentDocument;
            // Traverse up to find the root document
            while ($currentDoc && $currentDoc->parent_document_id) {
                $rootDocumentId = $currentDoc->parent_document_id;
                $currentDoc = InductionDocument::where('id', $rootDocumentId)
                    ->where('customer_id', $ids['customer_id'])
                    ->where('workspace_id', $ids['workspace_id'])
                    ->where('del', '0')
                    ->first();
            }
            // Get next version using parent_document_id chain
            $nextVersion = $this->getNextVersion(
                $parentDocument->id,
                $ids['customer_id'],
                $ids['workspace_id']
            );
            // Use title from request if provided, otherwise use parent document's title
            $newTitle = $request->filled('title') ? $request->title : $parentDocument->title;
            
            // Prepare trade_ids - use from request if provided, otherwise inherit from parent
            $tradeIds = $parentDocument->trade_ids;
            if ($request->filled('trade_ids')) {
                if (is_array($request->trade_ids)) {
                    $tradeIds = array_values(array_filter($request->trade_ids, function($id) {
                        return is_numeric($id) && $id > 0;
                    }));
                    // If empty after filtering, set to null
                    if (empty($tradeIds)) {
                        $tradeIds = null;
                    }
                } else {
                    $tradeIds = null;
                }
            }
            
            // Create new version - always use root document ID as parent_document_id
            $newDocument = InductionDocument::create([
                'title' => $newTitle,
                'document_type' => $parentDocument->document_type ?? 'onboarding',
                'role_types' => $parentDocument->role_types,
                'trade_ids' => $tradeIds,
                'version' => $nextVersion,
                'file_path' => $uploadResult['path'],
                'is_active' => true,
                'update_type' => $request->update_type,
                'parent_document_id' => $rootDocumentId, // Always use root document ID
                'customer_id' => $ids['customer_id'],
                'workspace_id' => $ids['workspace_id'],
                'created_by' => Auth::id(),
                'description' => $parentDocument->description,
                'del' => '0', // Enum expects string value
            ]);
            $isMajorUpdate = $request->update_type === 'major';
            if ($isMajorUpdate) {
                $this->invalidateDocumentSignatures($parentDocument->id);
            }
            $newDocument->refresh();
            $notifyAllEmployees = false;
            $notifyInput = $request->input('notify_all_employees');
            if ($notifyInput !== null) {
                if (is_bool($notifyInput)) {
                    $notifyAllEmployees = $notifyInput;
                } elseif (is_string($notifyInput)) {
                    $notifyAllEmployees = in_array(strtolower($notifyInput), ['true', '1', 'yes', 'on']);
                } elseif (is_numeric($notifyInput)) {
                    $notifyAllEmployees = (bool) $notifyInput;
                } else {
                    $notifyAllEmployees = $request->boolean('notify_all_employees', false);
                }
            }
            if ($notifyAllEmployees) {
                $this->notifyEmployeesAboutDocument($newDocument, $ids['customer_id'], $ids['workspace_id'], true, $isMajorUpdate);
            }
            return $this->success($newDocument, 'Document updated successfully. New version ' . $nextVersion . ' created.');
        }

        /**
         * Show a specific document with versions and signatures
         * 
         * @param Request $request
         * @param int $id
         * @return JsonResponse
         */
        public function show(Request $request, $id)
        {
            $ids = $this->getCustomerAndWorkspaceIds();
            $document = InductionDocument::where('id', $id)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->with(['parentDocument', 'childDocuments', 'creator'])
                ->first();
            if (!$document) {
                return $this->error('Document not found', 404);
            }
            $versionFilter = $request->filled('version') ? $request->version : null;
            $rootDocumentId = $document->id;
            $currentDoc = $document;
            // Traverse up to find the root document
            while ($currentDoc && $currentDoc->parent_document_id) {
                $rootDocumentId = $currentDoc->parent_document_id;
                $currentDoc = InductionDocument::where('id', $rootDocumentId)
                    ->where('customer_id', $ids['customer_id'])
                    ->where('workspace_id', $ids['workspace_id'])
                    ->where('del', '0')
                    ->first();
            }
            // Get all versions of this document chain (by parent_document_id, not by title)
            $allVersions = InductionDocument::where(function ($q) use ($rootDocumentId, $ids) {
                $q->where('id', $rootDocumentId)
                    ->orWhere('parent_document_id', $rootDocumentId);
            })
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->orderBy('version', 'desc')
                ->get();
            // If version filter is provided, find and use that specific version's document
            if ($versionFilter) {
                $versionDocument = $allVersions->firstWhere('version', $versionFilter);
                if (!$versionDocument) {
                    return $this->error('Version not found', 404);
                }
                // Use the filtered version document instead of the original document
                $document = $versionDocument;
            }
            // Get all document IDs to load signatures in bulk (for all versions)
            $documentIds = $allVersions->pluck('id')->toArray();
            // Load all signatures for all versions in one query
            $allSignatures = [];
            if (!empty($documentIds)) {
                $signaturesData = InductionDocumentSignature::whereIn('induction_document_id', $documentIds)
                    ->where('is_valid', true)
                    ->where('del', '0')
                    ->get();
                // Group signatures by document_id and version
                foreach ($signaturesData as $sig) {
                    $key = $sig->induction_document_id . '_' . $sig->document_version;
                    if (!isset($allSignatures[$key])) {
                        $allSignatures[$key] = [];
                    }
                    $allSignatures[$key][] = $sig;
                }
            }
            // Collect all employee IDs and user IDs from signatures
            $employeeIds = [];
            $userIds = [];
            foreach ($allSignatures as $sigList) {
                foreach ($sigList as $sig) {
                    if ($sig->employee_id) {
                        $employeeIds[] = $sig->employee_id;
                    }
                    if ($sig->user_id) {
                        $userIds[] = $sig->user_id;
                    }
                }
            }
            // Load all employees and users in one query
            $employees = [];
            if (!empty($employeeIds)) {
                $employeeData = \App\Models\EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)
                    ->whereIn('id', array_unique($employeeIds))
                    ->with('empPersonalDetails')
                    ->get();
                foreach ($employeeData as $emp) {
                    $employees[$emp->id] = $emp;
                }
            }
            $users = [];
            if (!empty($userIds)) {
                $userData = \App\Models\User::whereIn('id', array_unique($userIds))->get();
                foreach ($userData as $user) {
                    $users[$user->id] = $user;
                }
            }
            // Get signature statistics for the selected version (or current if no filter)
            $roleTypes = $document->role_types ?? ['all'];
            $stats = $this->getSignatureStatistics(
                $document->id,
                $document->version,
                $roleTypes,
                $ids['customer_id'],
                $ids['workspace_id']
            );
            // Collect all access_role codes from signed employees to fetch roles in bulk
            $accessRoleCodes = [];
            foreach ($stats['signed_users'] as $sig) {
                if (isset($sig['access_role']) && $sig['access_role']) {
                    $accessRoleCodes[] = $sig['access_role'];
                }
            }
            $accessRoleCodes = array_unique($accessRoleCodes);
            // Fetch all roles in one query
            $roles = [];
            if (!empty($accessRoleCodes)) {
                try {
                    // Try querying with customer_id and workspace_id first
                    $roleData = Role::whereIn('code', $accessRoleCodes)
                        ->where('del', '0')
                        ->get();
                } catch (\Exception $e) {
                    // If columns don't exist, query without them
                    $roleData = Role::whereIn('code', $accessRoleCodes)
                        ->where('del', '0')
                        ->get();
                }
                foreach ($roleData as $role) {
                    $roles[$role->code] = $role->title;
                }
            }
            // Format signed users with more details for current version
            $signedUsers = [];
            foreach ($stats['signed_users'] as $sig) {
                $roleTitle = null;
                // Get role title for employees
                if ($sig['type'] === 'employee' && isset($sig['access_role']) && $sig['access_role']) {
                    $roleTitle = $roles[$sig['access_role']] ?? null;
                }
                $signedUsers[] = [
                    'id' => $sig['id'],
                    'name' => $sig['name'] ?? 'Unknown',
                    'type' => $roleTitle ?? ($sig['type'] ?? 'unknown'),
                    'role_type' => $sig['role_type'] ?? 'unknown',
                    'email' => $sig['email'] ?? '',
                    'signed_at' => $sig['signed_at'],
                    'signature_path' => $sig['signature_path'],
                ];
            }
            // Collect access_role codes from not signed employees
            $notSignedAccessRoleCodes = [];
            foreach ($stats['not_signed_users'] as $user) {
                if (isset($user['access_role']) && $user['access_role']) {
                    $notSignedAccessRoleCodes[] = $user['access_role'];
                }
            }
            $notSignedAccessRoleCodes = array_unique($notSignedAccessRoleCodes);
            // Fetch roles for not signed users
            $notSignedRoles = [];
            if (!empty($notSignedAccessRoleCodes)) {
                try {
                    // Try querying with customer_id and workspace_id first
                    $notSignedRoleData = Role::whereIn('code', $notSignedAccessRoleCodes)
                        ->where('del', '0')
                        ->get();
                } catch (\Exception $e) {
                    // If columns don't exist, query without them
                    $notSignedRoleData = Role::whereIn('code', $notSignedAccessRoleCodes)
                        ->where('del', '0')
                        ->get();
                }
                foreach ($notSignedRoleData as $role) {
                    $notSignedRoles[$role->code] = $role->title;
                }
            }
            // Format not signed users for current version
            $notSignedUsers = [];
            foreach ($stats['not_signed_users'] as $user) {
                $roleTitle = null;
                // Get role title for employees
                if ($user['type'] === 'employee' && isset($user['access_role']) && $user['access_role']) {
                    $roleTitle = $notSignedRoles[$user['access_role']] ?? null;
                }
                $notSignedUsers[] = [
                    'id' => $user['id'],
                    'name' => $user['name'],
                    'type' => $roleTitle ?? ($user['type'] ?? 'unknown'),
                    'role_type' => $user['role_type'],
                    'email' => $user['email'],
                ];
            }
            // Get available versions (simplified list)
            $availableVersions = $allVersions->map(function ($v) {
                return [
                    'version' => $v->version,
                    'is_active' => $v->is_active,
                    'created_at' => $v->created_at,
                ];
            });
            $result = [
                'id' => $document->id,
                'title' => $document->title,
                'document_type' => $document->document_type,
                'role_types' => $document->role_types ?? [],
                'version' => $document->version, // The version being viewed (filtered or current)
                'is_active' => $document->is_active,
                'update_type' => $document->update_type,
                'parent_document_id' => $document->parent_document_id, // Shows parent relationship
                'description' => $document->description,
                'total_required' => $stats['total_required'],
                'file_path' => $document->file_path,
                'signed_count' => $stats['signed_count'],
                'pending_count' => $stats['not_signed_count'],
                'created_at' => $document->created_at,
                'available_versions' => $availableVersions, // All available versions for this document title
                'signed_users' => $signedUsers,
                'not_signed_users' => $notSignedUsers,
                'statistics' => [
                    'total_required' => $stats['total_required'],
                    'signed_count' => $stats['signed_count'],
                    'not_signed_count' => $stats['not_signed_count'],
                ],
            ];
            return $this->success($result, 'Document retrieved successfully');
        }

        /**
         * Delete a document (soft delete)
         * If deleting the latest version, automatically activate the previous version
         * 
         * @param int $id
         * @return JsonResponse
         */
        public function destroy($id)
        {
            $ids = $this->getCustomerAndWorkspaceIds();
            if ($ids['flag'] != 'customer') {
                return $this->error('Unauthorized', 401);
            }
            $document = InductionDocument::where('id', $id)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->first();
            if (!$document) {
                return $this->error('Document not found', 404);
            }
            DB::beginTransaction();
            try {
                $previousVersion = null;
                // Get the latest version of this document chain
                $latestVersion = $this->getLatestVersion(
                    $document->id,
                    $ids['customer_id'],
                    $ids['workspace_id']
                );
                // Check if the document being deleted is the latest version
                if ($latestVersion && $latestVersion->id == $document->id) {
                    // Get the previous version
                    $previousVersion = $this->getPreviousVersion(
                        $document->id,
                        $ids['customer_id'],
                        $ids['workspace_id']
                    );
                    if ($previousVersion) {
                        // Activate the previous version
                        $previousVersion->update(['is_active' => true]);
                    }
                }
                // Soft delete the document
                $document->update(['del' => '1']); // Enum expects string value
                DB::commit();
                $message = 'Document deleted successfully';
                if ($latestVersion && $latestVersion->id == $document->id && $previousVersion) {
                    $message .= '. Previous version ' . $previousVersion->version . ' has been activated.';
                }
                return $this->message($message);
            } catch (\Exception $e) {
                DB::rollBack();
                return $this->error('An error occurred while deleting document: ' . $e->getMessage(), 500);
            }
        }

        /**
         * Toggle active status of a document (only works on current/latest version)
         * 
         * @param Request $request
         * @param int $id
         * @return JsonResponse
         */
        public function toggleActive($id)
        {
            $ids = $this->getCustomerAndWorkspaceIds();
            if ($ids['flag'] != 'customer') {
                return $this->error('Unauthorized', 401);
            }
            $document = InductionDocument::where('id', $id)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->first();
            if (!$document) {
                return $this->error('Document not found', 404);
            }
            // Get the latest version of this document chain
            $latestVersion = $this->getLatestVersion(
                $document->id,
                $ids['customer_id'],
                $ids['workspace_id']
            );
            if (!$latestVersion) {
                return $this->error('Could not determine latest version', 500);
            }
            // Check if the document is the latest version
            if ($latestVersion->id != $document->id) {
                return $this->error('You can only activate/inactivate the current version (latest version). Current version is ' . $latestVersion->version, 422);
            }
            // Toggle the active status
            $newStatus = !$document->is_active;
            $document->update(['is_active' => $newStatus]);
            $statusText = $newStatus ? 'activated' : 'inactivated';
            return $this->success([
                'id' => $document->id,
                'version' => $document->version,
                'is_active' => $newStatus,
            ], 'Document version ' . $document->version . ' has been ' . $statusText . ' successfully');
        }

        /**
         * Upload signature for induction document (Employee/User signs document)
         * 
         * @param Request $request
         * @return JsonResponse
         */
        public function uploadSignature(Request $request)
        {
            $validator = Validator::make($request->all(), [
                'document_id' => 'required|integer|exists:induction_documents,id',
                'version' => 'nullable|string',
                'signature' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
                'notes' => 'nullable|string',
            ]);
            if ($validator->fails()) {
                return $this->error($validator->errors()->first(), 422);
            }
            $ids = $this->getCustomerAndWorkspaceIds();
            if ($ids['flag'] != 'emp') {
                return $this->error('Only employees can sign documents', 401);
            }
            // Get document
            $document = InductionDocument::where('id', $request->document_id)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->where('is_active', true)
                ->first();
            if (!$document) {
                return $this->error('Document not found or not active', 404);
            }
            // Use provided version or default to document's current version
            $version = $request->version ?? $document->version;
            // Verify version exists
            $versionDocument = InductionDocument::where('title', $document->title)
                ->where('version', $version)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->first();
            if (!$versionDocument) {
                return $this->error('Version not found', 404);
            }
            // Get user type (employee or customer)
            $userTable = $this->getUserTable();
            $employeeId = null;
            $userId = null;
            $signatureType = null;
            if ($userTable === 'emp') {
                $employeeId = Auth::id();
                $signatureType = 'employee';
                // Verify employee is in the required role types
                $employee = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)
                    ->where('id', $employeeId)
                    ->where('customer_id', $ids['customer_id'])
                    ->where('workspace_id', $ids['workspace_id'])
                    ->first();
                if (!$employee) {
                    return $this->error('Employee not found', 404);
                }
                // Check if employee matches role types
                $roleTypes = $document->role_types ?? ['all'];
                if (!in_array('all', $roleTypes)) {
                    $employeeRoleType = $employee->user_type == 0 ? 'internal' : 'external';
                    if (!in_array($employeeRoleType, $roleTypes)) {
                        return $this->error('You are not authorized to sign this document', 403);
                    }
                }
            } elseif ($userTable === 'customer') {
                $userId = Auth::id();
                $signatureType = 'customer';
            } else {
                return $this->error('Invalid user type', 403);
            }
            // Check if already signed this version
            $existingSignature = InductionDocumentSignature::where('induction_document_id', $versionDocument->id)
                ->where('document_version', $version)
                ->where('is_valid', true)
                ->where('del', '0');
            if ($employeeId) {
                $existingSignature->where('employee_id', $employeeId);
            } else {
                $existingSignature->where('user_id', $userId);
            }
            $existingSignature = $existingSignature->first();
            if ($existingSignature) {
                return $this->error('You have already signed this document version', 422);
            }
            DB::beginTransaction();
            try {
                // Upload signature image
                $signaturePath = null;
                if ($request->hasFile('signature')) {
                    $signatureFile = $request->file('signature');
                    $directory = 'InductionSignatures';
                    $uploadPath = public_path($directory);
                    if (!File::exists($uploadPath)) {
                        File::makeDirectory($uploadPath, 0755, true);
                    }
                    $extension = $signatureFile->getClientOriginalExtension();
                    $imageName = ($employeeId ?? $userId) . '_' . $versionDocument->id . '_' . time() . '.' . $extension;
                    $signatureFile->move($uploadPath, $imageName);
                    $signaturePath = "$directory/$imageName";
                }
                // Create signature record
                $signature = InductionDocumentSignature::create([
                    'induction_document_id' => $versionDocument->id,
                    'document_version' => $version,
                    'employee_id' => $employeeId,
                    'user_id' => $userId,
                    'signature_type' => $signatureType,
                    'signature_path' => $signaturePath,
                    'signed_at' => now(),
                    'is_valid' => true,
                    'notes' => $request->notes,
                    'customer_id' => $ids['customer_id'],
                    'workspace_id' => $ids['workspace_id'],
                    'del' => '0',
                ]);
                DB::commit();
                return $this->success($signature, 'Document signed successfully');
            } catch (\Exception $e) {
                DB::rollBack();
                return $this->error('An error occurred while uploading signature: ' . $e->getMessage(), 500);
            }
        }

        /**
         * Get documents that need to be signed by current user/employee
         * 
         * @param Request $request
         * @return JsonResponse
         */
        public function getMyDocumentsToSign(Request $request)
        {
            $ids = $this->getCustomerAndWorkspaceIds();
            $userTable = $this->getUserTable();
            $employeeId = null;
            $userId = null;
            if ($userTable === 'emp') {
                $employeeId = Auth::id();
                $employee = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)
                    ->where('id', $employeeId)
                    ->first();
                if (!$employee) {
                    return $this->error('Employee not found', 404);
                }
            } elseif ($userTable === 'customer') {
                $userId = Auth::id();
            }
            // Get all active documents
            $documents = InductionDocument::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('del', '0')
                ->where('is_active', true)
                ->get();
            $documentsToSign = [];
            foreach ($documents as $doc) {
                $roleTypes = $doc->role_types ?? ['all'];
                // Check if user matches role types
                if ($userTable === 'emp' && isset($employee)) {
                    $employeeRoleType = $employee->user_type == 0 ? 'internal' : 'external';
                    if (!in_array('all', $roleTypes) && !in_array($employeeRoleType, $roleTypes)) {
                        continue; // Skip if employee doesn't match role types
                    }
                }
                // Check if already signed
                $hasSigned = InductionDocumentSignature::where('induction_document_id', $doc->id)
                    ->where('document_version', $doc->version)
                    ->where('is_valid', true)
                    ->where('del', '0')
                    ->where(function ($query) use ($employeeId, $userId) {
                        if ($employeeId) {
                            $query->where('employee_id', $employeeId);
                        }
                        if ($userId) {
                            $query->where('user_id', $userId);
                        }
                    })
                    ->exists();
                if($hasSigned == false) {
                    $hasSigned = 0;
                } else {
                    $hasSigned = 1;
                }
                // Return all documents with signed flag
                $documentsToSign[] = [
                    'id' => $doc->id,
                    'title' => $doc->title,
                    'document_type' => $doc->document_type,
                    'version' => $doc->version,
                    'file_path' => $doc->file_path,
                    'description' => $doc->description,
                    'created_at' => $doc->created_at,
                    'signed' => $hasSigned, // true if signed, false if not signed
                ];
        }
        return $this->success($documentsToSign, 'Documents to sign retrieved successfully');
    }

    /**
     * Notify all employees about document creation/update
     * 
     * @param InductionDocument $document
     * @param int $customerId
     * @param int $workspaceId
     * @param bool $isUpdate
     * @param bool $isMajorUpdate
     * @return void
     */
    protected function notifyEmployeesAboutDocument($document, $customerId, $workspaceId, $isUpdate = false, $isMajorUpdate = false)
    {
        $roleTypes = $document->role_types ?? ['all'];
        
        Log::info('notifyEmployeesAboutDocument: Starting notification', [
            'document_id' => $document->id,
            'document_version' => $document->version,
            'document_title' => $document->title,
            'role_types' => $roleTypes,
            'customer_id' => $customerId,
            'workspace_id' => $workspaceId,
            'is_update' => $isUpdate,
            'is_major_update' => $isMajorUpdate
        ]);
        
        // Get all employees based on role types - NO FILTERING BY SIGNATURE STATUS
        // All employees matching role types will receive emails regardless of whether they've signed or not
        $employees = collect([]);
        if (in_array('all', $roleTypes)) {
            // Get all employees (internal and external) - including those who have already signed
            $employees = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)
                ->where('customer_id', $customerId)
                ->where('workspace_id', $workspaceId)
                ->where('del', '0')
                ->whereNotNull('employee_email')
                ->with('empPersonalDetails')
                ->get();
                
            Log::info('notifyEmployeesAboutDocument: Found employees for "all" role type', [
                'total_employees' => $employees->count(),
                'employee_ids' => $employees->pluck('id')->toArray()
            ]);
        } else {
            // Get employees based on specific role types - including those who have already signed
            if (in_array('internal', $roleTypes)) {
                $internalEmployees = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)
                    ->where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('user_type', 0)
                    ->where('del', '0')
                    ->whereNotNull('employee_email')
                    ->with('empPersonalDetails')
                    ->get();
                $employees = $employees->merge($internalEmployees);
                
                Log::info('notifyEmployeesAboutDocument: Found internal employees', [
                    'count' => $internalEmployees->count(),
                    'employee_ids' => $internalEmployees->pluck('id')->toArray()
                ]);
            }
            if (in_array('external', $roleTypes)) {
                $externalEmployees = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)
                    ->where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('user_type', 1)
                    ->where('del', '0')
                    ->whereNotNull('employee_email')
                    ->with('empPersonalDetails')
                    ->get();
                $employees = $employees->merge($externalEmployees);
                
                Log::info('notifyEmployeesAboutDocument: Found external employees', [
                    'count' => $externalEmployees->count(),
                    'employee_ids' => $externalEmployees->pluck('id')->toArray()
                ]);
            }
        }
        
        // Remove duplicates (in case an employee matches multiple role types)
        $employees = $employees->unique('id');
        
        Log::info('notifyEmployeesAboutDocument: Total unique employees to notify', [
            'total_count' => $employees->count(),
            'employee_ids' => $employees->pluck('id')->toArray(),
            'employee_emails' => $employees->pluck('employee_email')->toArray()
        ]);
        
        // Dispatch job for each employee - ALL employees will receive emails regardless of signature status
        $dispatchedCount = 0;
        foreach ($employees as $employee) {
            Log::info('InductionController: Dispatching notification job', [
                'employee_id' => $employee->id,
                'employee_email' => $employee->employee_email,
                'document_id' => $document->id,
                'document_version' => $document->version,
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
                'is_update' => $isUpdate,
                'is_major_update' => $isMajorUpdate,
                'note' => 'Email will be sent regardless of whether employee has signed previous version'
            ]);
            
            SendInductionDocumentNotificationJob::dispatch(
                $employee->id,
                $document->id,
                $isUpdate,
                $isMajorUpdate,
                $customerId
            );
            $dispatchedCount++;
        }
        
        Log::info('notifyEmployeesAboutDocument: Notification jobs dispatched', [
            'total_dispatched' => $dispatchedCount,
            'document_id' => $document->id
        ]);
    }
}
