<?php

namespace App\Http\Controllers\Traits;

use App\Models\WhsqReport;
use App\Models\WHSQEReportLog;
use App\Models\WHSQETableOfContentMeta;
use App\Models\WHSQECustomerSelectedSettings;
use App\Models\WHSQEContentOption;
use App\Models\WHSQEContentDate;
use App\Models\WhsqSignature;
use App\Models\GeneratedPdfReport;
use App\Models\EmpCompanyDetails;
use App\Models\Role;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Exception;
trait WHSQTrait
{
    /**
     * Store report WHSQ
     */
    protected function storeWHSQReport($request, $ids)
    {
        try {
            DB::beginTransaction();
            $isUpdate = $request->report_id;
            $query = WhsqReport::query();
            $query = $this->applyCustomerWorkspaceFilter($query);
            // If this is an update, check if the report is published
            if ($isUpdate) {
                $report = $query->find($request->report_id);
                if (!$report) {
                    return $this->error('Report not found.', 404);
                }
                if ($report->publish) {
                    $report->createNewVersion();
                    DB::commit();
                    return $this->success('New version created successfully.', 'WHSQE Created successfully.');
                }
            }
            // Regular create/update flow
            $oldWhsqData = null;
            if ($isUpdate) {
                $oldWhsqData = $query->find($request->report_id);
                if (!$oldWhsqData) {
                    return $this->error('Report not found.', 404);
                }
            }
            $whsqData = [
                'document_title' => $request->document_title,
                'authorised_by' => $request->authorised_by,
                'revision_number' => $request->revision_number ?? 'R1',
                'revision_date' => $request->revision_date,
                'next_revision_date' => $request->next_revision_date,
                'document_number' => $request->document_number,
                'is_completed' => 0,
                'site_id' => $request->whsq_site,
                'customer_id' => $ids['customer_id'],
                'workspace_id' => $ids['workspace_id'],
            ];
            if ($isUpdate) {
                $oldWhsqData->update($whsqData);
                $report = $oldWhsqData;
            } else {
                $report = WhsqReport::create($whsqData);
            }
            // Log the WHSQ action
            $this->logWHSQReportAction(
                $report->id,
                $isUpdate ? 'WHSEQ  Edited' : 'WHSEQ Created',
                $isUpdate ? 'Updated WHSEQ  report ' : 'Created new WHSEQ report ',
                null,
                [
                    'document_title' => $request->document_title,
                    'document_number' => $request->document_number,
                    'revision_number' => $request->revision_number,
                    'site_id' => $request->whsq_site,
                    'old_values' => $oldWhsqData ? [
                        'document_title' => $oldWhsqData->document_title,
                        'document_number' => $oldWhsqData->document_number,
                        'revision_number' => $oldWhsqData->revision_number,
                        'site_id' => $oldWhsqData->site_id
                    ] : null,
                    'new_values' => $whsqData,
                    'action_time' => now()->toDateTimeString()
                ]
            );
            DB::commit();
            $message = $isUpdate ? 'Updated Successfully' : 'Saved Successfully';
            return $this->success($report, $message);
        } catch (Exception $e) {
            DB::rollBack();
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }

    /**
     * Determine the level based on the IDs present
     */
    private function determineLevelFromIds($parentId, $childId, $grandchildId)
    {
        if (!empty($grandchildId)) {
            return 'grandchild';
        } elseif (!empty($childId)) {
            return 'child';
        } elseif (!empty($parentId)) {
            return 'parent';
        }
        return null;
    }

    /**
     * Save selected settings for a report
     */
    protected function saveWHSQSelectedSettings($validated, $ids)
    {
        try {
            DB::beginTransaction();
            // Get existing settings for this report
            $existingSettings = WHSQECustomerSelectedSettings::where('whsq_report_id', $validated['report_id'])
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->get()
                ->keyBy(function ($item) {
                    return $item->parent_id . '_' . $item->child_id . '_' . $item->grandchild_id;
                });
            // Create a set of keys from the request to track what should be selected
            $requestedSettingKeys = [];
            $requestedParents = [];
            $requestedChildren = [];
            foreach ($validated['selected_settings'] as $index => $setting) {
                $settingKey = ($setting['parent_id'] ?? '') . '_' . ($setting['child_id'] ?? '') . '_' . ($setting['grandchild_id'] ?? '');
                $requestedSettingKeys[] = $settingKey;
                // Track selected parents and children for hierarchical logic
                if (!empty($setting['parent_id'])) {
                    $requestedParents[] = $setting['parent_id'];
                }
                if (!empty($setting['child_id'])) {
                    $requestedChildren[] = $setting['child_id'];
                }
                if (isset($existingSettings[$settingKey])) {
                    // Update existing setting - mark as selected and update sort order and level
                    $level = $this->determineLevelFromIds(
                        $setting['parent_id'] ?? null,
                        $setting['child_id'] ?? null,
                        $setting['grandchild_id'] ?? null
                    );
                    $existingSettings[$settingKey]->update([
                        'is_selected' => true,
                        'sort_order' => $setting['sort_order'] ?? $index,
                        'level' => $level
                    ]);
                } else {
                    // Create new setting only if it doesn't exist
                    $level = $this->determineLevelFromIds(
                        $setting['parent_id'] ?? null,
                        $setting['child_id'] ?? null,
                        $setting['grandchild_id'] ?? null
                    );
                    $newSetting = WHSQECustomerSelectedSettings::create([
                        'whsq_report_id' => $validated['report_id'],
                        'customer_id' => $ids['customer_id'],
                        'workspace_id' => $ids['workspace_id'],
                        'parent_id' => $setting['parent_id'] ?? null,
                        'child_id' => $setting['child_id'] ?? null,
                        'grandchild_id' => $setting['grandchild_id'] ?? null,
                        'sort_order' => $setting['sort_order'] ?? $index,
                        'is_selected' => true,
                        'level' => $level
                    ]);
                    // Add the new setting to existingSettings collection so it's processed by hierarchical logic
                    $existingSettings[$settingKey] = $newSetting;
                    // Log the creation of new setting for debugging
                    Log::info('New WHSQ setting created', [
                        'id' => $newSetting->id,
                        'setting_key' => $settingKey,
                        'is_selected' => $newSetting->is_selected,
                        'parent_id' => $setting['parent_id'] ?? null,
                        'child_id' => $setting['child_id'] ?? null,
                        'grandchild_id' => $setting['grandchild_id'] ?? null
                    ]);
                }
            }
            // OPTIMIZED HIERARCHICAL LOGIC
            // Convert arrays to hash sets for O(1) lookups instead of O(n) searches
            $requestedSettingKeysSet = array_flip($requestedSettingKeys);
            $requestedParentsSet = array_flip($requestedParents);
            $requestedChildrenSet = array_flip($requestedChildren);
            // Batch updates instead of individual database calls
            $settingsToUpdate = [];
            foreach ($existingSettings as $key => $setting) {
                // Use hash lookup instead of in_array for better performance
                $shouldBeSelected = isset($requestedSettingKeysSet[$key]);
                
                // Only apply hierarchical logic if not explicitly requested
                if (!$shouldBeSelected && !empty($setting->parent_id)) {
                    // Parent must be selected for child/grandchild to be considered
                    if (isset($requestedParentsSet[$setting->parent_id])) {
                        if (!empty($setting->child_id)) {
                            // Grandchild: requires both parent and child to be selected
                            $shouldBeSelected = isset($requestedChildrenSet[$setting->child_id]) && 
                                               isset($requestedSettingKeysSet[$key]);
                        } else {
                            // Child: only needs to be explicitly requested (parent already checked)
                            $shouldBeSelected = isset($requestedSettingKeysSet[$key]);
                        }
                    }
                    // If parent not selected, shouldBeSelected remains false
                } elseif (!$shouldBeSelected && empty($setting->parent_id)) {
                    // Parent setting: should be selected if it's in requested parents
                    $shouldBeSelected = isset($requestedParentsSet[$setting->parent_id ?? '']);
                }
                
                // Only update if status actually changed
                if ($setting->is_selected != $shouldBeSelected) {
                    $settingsToUpdate[$setting->id] = $shouldBeSelected;
                }
            }
            // Batch update all changed settings in one query
            if (!empty($settingsToUpdate)) {
                // Update selected settings
                $selectedIds = array_keys(array_filter($settingsToUpdate));
                if (!empty($selectedIds)) {
                    WHSQECustomerSelectedSettings::whereIn('id', $selectedIds)->update(['is_selected' => true]);
                }   
                // Update unselected settings
                $unselectedIds = array_keys(array_filter($settingsToUpdate, function($selected) { return !$selected; }));
                if (!empty($unselectedIds)) {
                    WHSQECustomerSelectedSettings::whereIn('id', $unselectedIds)->update(['is_selected' => false]);
                }
            }
            // Ensure all newly created settings are marked as selected (double-check)
            foreach ($requestedSettingKeys as $requestedKey) {
                if (isset($existingSettings[$requestedKey])) {
                    $setting = $existingSettings[$requestedKey];
                    if (!$setting->is_selected) {
                        $setting->update(['is_selected' => true]);
                    }
                }
            }
            // Final verification: Force all requested settings to be selected
            WHSQECustomerSelectedSettings::where('whsq_report_id', $validated['report_id'])
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->whereIn('id', collect($existingSettings)->pluck('id'))
                ->whereIn(DB::raw("CONCAT(COALESCE(parent_id, ''), '_', COALESCE(child_id, ''), '_', COALESCE(grandchild_id, ''))"), $requestedSettingKeys)
                ->update(['is_selected' => true]);
            // Also handle any existing settings that are not in the existingSettings collection
            // (these might be settings that were created in previous calls but not in current data)
            WHSQECustomerSelectedSettings::where('whsq_report_id', $validated['report_id'])
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->whereNotIn('id', $existingSettings->pluck('id'))
                ->update(['is_selected' => false]);
            DB::commit();
            // Log the settings action
            $this->logWHSQReportAction(
                $validated['report_id'],
                'Settings Selected',
                'Selected settings for WHSEQ report',
                null,
                [
                    'settings_count' => count($validated['selected_settings']),
                    'action_time' => now()->toDateTimeString()
                ]
            );
            return $this->message('Selected settings saved successfully.');
        } catch (Exception $e) {
            DB::rollBack();
            return $this->error('Error saving selected settings: ' . $e->getMessage(), 500);
        }
    }
    /**
     * Get selected settings for a report
     */
    protected function getWHSQSelectedSettings($reportId, $ids)
    {
        $selectedSettings = WHSQECustomerSelectedSettings::where('whsq_report_id', $reportId)
            ->where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('is_selected', true)
            ->orderBy('id','asc')
            ->with([
                'parentContent' => function ($query) use ($ids) {
                    $query->where('customer_id', $ids['customer_id'])
                        ->where('workspace_id', $ids['workspace_id']);
                },
                'childContent' => function ($query) use ($ids) {
                    $query->where('customer_id', $ids['customer_id'])
                        ->where('workspace_id', $ids['workspace_id']);
                },
                'grandchildContent' => function ($query) use ($ids) {
                    $query->where('customer_id', $ids['customer_id'])
                        ->where('workspace_id', $ids['workspace_id']);
                }
            ])
            ->get();
        if ($selectedSettings->isEmpty()) {
            return $this->error('No selected settings found.', 404);
        }
        return $this->success($selectedSettings, 'Selected settings retrieved successfully.');
    }

    /**
     * Toggle publish/unpublish status of a report
     */
    protected function toggleWHSQReportPublish($id, $ids)
    {
        $report = WhsqReport::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->find($id);
        if (!$report) {
            return $this->error('Report not found.', 404);
        }
        // Toggle the publish status
        $report->publish = !$report->publish;
        $report->save();
        // Log the action
        $this->logWHSQReportAction(
            $report->id,
            'Publish/Unpublish',
            'Publish/Unpublish WHSEQ report',
            $report->step,
            [
                'document_title' => $report->document_title ?? 'Untitled',
                'document_number' => $report->document_number ?? 'No Number',
                'publish_status' => $report->publish
            ]
        );
        return $this->success($report, 'Report status Updated successfully.');
    }

    /**
     * Get all data for a given report for frontend PDF generation
     */
    protected function getWHSQReportData($id, $ids)
    {
        $report = WhsqReport::with(['site', 'authoriseBy',])->where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->find($id);
        if (!$report) {
            return $this->error('Report not found.', 404);
        }
        // Get selected settings for this report
        $selectedSettings = WHSQECustomerSelectedSettings::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('whsq_report_id', $id)
            ->where('is_selected', 1)
            ->orderBy('sort_order')
            ->get();
        // Get all content for this report
        $allContent = WHSQETableOfContentMeta::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('whsq_report_id', $id)
            ->orderBy('sort_order', 'asc')
            ->orderBy('id', 'asc')
            ->get();
        // Get all signatures for this report
        $signatures = WhsqSignature::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('whsq_report_id', $id)
            ->with(['employee'])
            ->orderBy('created_at', 'asc')
            ->get();
        // Organize content hierarchically
        $organizedContent = $this->organizeWHSQContent($selectedSettings, $allContent);
        if($report->report_method == 1){
            $whsq_upload_report=GeneratedPdfReport::where('report_type', 'whsqe_report')->where('report_id', $id)->first();
        }
        else{
            $whsq_upload_report=null;
        }
        $reportData = [
            'report' => [
                'id' => $report->id,
                'step' => $report->step,
                'semi' => $report->semi,
                'publish' => $report->publish,
                'created_at' => $report->created_at,
                'updated_at' => $report->updated_at,
                'document_title' => $report->document_title,
                'authorised_by' => $report->authorised_by,
                'revision_number' => $report->revision_number,
                'document_number' => $report->document_number,
                'revision_date' => $report->revision_date,
                'next_revision_date' => $report->next_revision_date,
                'site_id' => $report->site_id,
                'version' => $report->version,
                'customer_id' => $report->customer_id,
                'workspace_id' => $report->workspace_id,
                'created_by' => $report->created_by,
                'site' => $report->site,
                'authoriseBy' => $report->authoriseBy
            ],
            'content' => $organizedContent,
            'uploaded_report' => $whsq_upload_report,
            'signatures' => $signatures->map(function ($signature) use ($ids) {
                $roleTitle = null;
                if ($signature->employee_id) {
                    // Get role title based on employee's access_role code
                    $employee = EmpCompanyDetails::where('id', $signature->employee_id)
                        ->where('customer_id', $ids['customer_id'])
                        ->where('workspace_id', $ids['workspace_id'])
                        ->first();
                    
                    if ($employee && $employee->access_role) {
                        // Find the role using the role code
                        $role = Role::where('code', $employee->access_role)
                            ->where('del', '0')
                            ->first();
                        
                        $roleTitle = $role ? $role->title : null;
                    }
                }
                
                return [
                    'id' => $signature->id,
                    'employee_id' => $signature->employee_id,
                    'is_site_employee' => $signature->is_site_employee,
                    'signature' => $signature->signature,
                    'job_description' => $signature->job_description,
                    'induction_date' => $signature->induction_date,
                    'created_at' => $signature->created_at,
                    'employee' => $signature->employee ? [
                        'emp_id' => $signature->employee->emp_id,
                        'first_name' => $signature->employee->first_name,
                        'middle_name' => $signature->employee->middle_name,
                        'last_name' => $signature->employee->last_name,
                        'full_name' => trim($signature->employee->first_name . ' ' . $signature->employee->middle_name . ' ' . $signature->employee->last_name),
                        'role_title' => $roleTitle
                    ] : null
                ];
            }),
        ];
        return $this->success($reportData, 'Report data retrieved successfully for PDF generation.');
    }

    /**
     * Remove the specified WHSQ report and related data
     */
    protected function destroyWHSQReport($id, $ids)
    {
        DB::beginTransaction();
        try {
            $report = WhsqReport::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->find($id);
            if (!$report) {
                DB::rollBack();
                return $this->error('Report not found.', 404);
            }
            // Collect all content meta IDs for this report
            $metaIds = WHSQETableOfContentMeta::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('whsq_report_id', $report->id)
                ->pluck('id');
            if ($metaIds->isNotEmpty()) {
                // Delete options and dates linked to those metas
                WHSQEContentOption::whereIn('content_meta_id', $metaIds)->delete();
                WHSQEContentDate::whereIn('content_meta_id', $metaIds)->delete();
                // Delete meta records
                WHSQETableOfContentMeta::whereIn('id', $metaIds)->delete();
            }
            // Delete selected settings for this report
            WHSQECustomerSelectedSettings::where('whsq_report_id', $report->id)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->delete();
            // Delete report logs
            WHSQEReportLog::where('report_id', $report->id)->delete();
            // Finally delete the report
            $report->delete();
            DB::commit();
            return $this->message('WHSQ report and all related data deleted successfully.');
        } catch (Exception $e) {
            DB::rollBack();
            return $this->error('Error deleting report: ' . $e->getMessage(), 500);
        }
    }

    /**
     * Duplicate WHSQ report with new version
     */
    protected function duplicateWHSQReport($reportId, $ids)
    {
        DB::beginTransaction();
        try {
            // Find the original report
            $originalReport = WhsqReport::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->find($reportId);
            if (!$originalReport) {
                DB::rollBack();
                return $this->error('Report not found.', 404);
            }
            // Create new report with incremented version
            $newReportData = $originalReport->toArray();
            unset($newReportData['id'], $newReportData['created_at'], $newReportData['updated_at']);
            // Increment revision number
            $newReportData['revision_number'] = $this->incrementRevisionNumber($originalReport->revision_number, $originalReport->id);
            $newReportData['revision_date'] = now()->toDateString();
            $newReportData['next_revision_date'] = now()->addYear()->toDateString();
            $newReportData['publish'] = false; // New version starts as unpublished
            $newReportData['parent_report_id'] = $originalReport->id;
            $newReportData['customer_id'] = $ids['customer_id'];
            $newReportData['workspace_id'] = $ids['workspace_id'];

            $newReport = WhsqReport::create($newReportData);
            // Duplicate selected settings
            $originalSettings = WHSQECustomerSelectedSettings::where('whsq_report_id', $reportId)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->get();
            foreach ($originalSettings as $setting) {
                $newSettingData = $setting->toArray();
                unset($newSettingData['id'], $newSettingData['created_at'], $newSettingData['updated_at']);
                $newSettingData['whsq_report_id'] = $newReport->id;
                $newSettingData['customer_id'] = $ids['customer_id'];
                $newSettingData['workspace_id'] = $ids['workspace_id'];
                WHSQECustomerSelectedSettings::create($newSettingData);
            }
            // Duplicate table of content meta
            $originalMeta = WHSQETableOfContentMeta::where('whsq_report_id', $reportId)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->get();
            foreach ($originalMeta as $meta) {
                $newMetaData = $meta->toArray();
                unset($newMetaData['id'], $newMetaData['created_at'], $newMetaData['updated_at']);
                $newMetaData['whsq_report_id'] = $newReport->id;
                $newMeta = WHSQETableOfContentMeta::create($newMetaData);
                // Duplicate content options for this meta
                $originalOptions = WHSQEContentOption::where('content_meta_id', $meta->id)->get();
                foreach ($originalOptions as $option) {
                    $newOptionData = $option->toArray();
                    unset($newOptionData['id'], $newOptionData['created_at'], $newOptionData['updated_at']);
                    $newOptionData['content_meta_id'] = $newMeta->id;
                    $newOptionData['customer_id'] = $ids['customer_id'];
                    $newOptionData['workspace_id'] = $ids['workspace_id'];

                    WHSQEContentOption::create($newOptionData);
                }
                // Duplicate content dates for this meta
                $originalDates = WHSQEContentDate::where('content_meta_id', $meta->id)->get();
                foreach ($originalDates as $date) {
                    $newDateData = $date->toArray();
                    unset($newDateData['id'], $newDateData['created_at'], $newDateData['updated_at']);
                    $newDateData['content_meta_id'] = $newMeta->id;
                    $newDateData['customer_id'] = $ids['customer_id'];
                    $newDateData['workspace_id'] = $ids['workspace_id'];
                    WHSQEContentDate::create($newDateData);
                }
            }
            // Duplicate signatures
            $originalSignatures = WhsqSignature::where('whsq_report_id', $reportId)
                ->where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->get();

            foreach ($originalSignatures as $signature) {
                $newSignatureData = $signature->toArray();
                unset($newSignatureData['id'], $newSignatureData['created_at'], $newSignatureData['updated_at']);
                $newSignatureData['whsq_report_id'] = $newReport->id;
                $newSignatureData['customer_id'] = $ids['customer_id'];
                $newSignatureData['workspace_id'] = $ids['workspace_id'];
                WhsqSignature::create($newSignatureData);
            }
            // Log the duplication action
            $this->logWHSQReportAction(
                $newReport->id,
                'WHSEQ Duplicated',
                'Duplicated WHSEQ report from version ' . $originalReport->revision_number . ' to ' . $newReport->revision_number,
                null,
                [
                    'original_report_id' => $originalReport->id,
                    'original_revision' => $originalReport->revision_number,
                    'new_revision' => $newReport->revision_number,
                    'duplication_date' => now()->toDateTimeString()
                ]
            );
            $newReport->approval_status = 0;
            $newReport->save();
            DB::commit();
            return $this->success($newReport, 'WHSQ report duplicated successfully with new version ' . $newReport->revision_number);
        } catch (Exception $e) {
            DB::rollBack();
            return $this->error('Error duplicating report: ' . $e->getMessage(), 500);
        }
    }

    /**
     * Increment revision number
     */
    private function incrementRevisionNumber($currentRevision, $originalReportId = null)
    {
        // If we have the original report ID, find the latest revision across all reports
        if ($originalReportId) {
            $originalReport = WhsqReport::find($originalReportId);
            if ($originalReport) {
                // Find the latest revision number across all reports with the same base
                $latest = WhsqReport::where('customer_id', $originalReport->customer_id)
                    ->where('workspace_id', $originalReport->workspace_id)
                    ->orderByRaw("CAST(SUBSTRING(revision_number, 2) AS UNSIGNED) DESC")
                    ->first();

                if ($latest && $latest->revision_number) {
                    $currentRevision = (int)substr($latest->revision_number, 1); // Remove "R"
                    return 'R' . ($currentRevision + 1);
                }
            }
        }
        // Fallback to simple increment if no original report ID or fallback logic
        if (preg_match('/^R(\d+)$/', $currentRevision, $matches)) {
            $number = intval($matches[1]);
            return 'R' . ($number + 1);
        }
        // Handle numeric formats
        if (is_numeric($currentRevision)) {
            return $currentRevision + 1;
        }
        // Handle string formats like "1.0", "1.1", etc.
        if (strpos($currentRevision, '.') !== false) {
            $parts = explode('.', $currentRevision);
            $lastPart = end($parts);
            if (is_numeric($lastPart)) {
                $parts[count($parts) - 1] = $lastPart + 1;
                return implode('.', $parts);
            }
        }
        // Handle other formats by appending .1
        return $currentRevision . '.1';
    }

    /**
     * Get step content for a specific step
     */
    protected function getWHSQStepContent($stepId, $reportId, $ids)
    {
        // First, get the specific setting record by its ID
        $currentSetting = WHSQECustomerSelectedSettings::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('whsq_report_id', $reportId)
            ->where('id', $stepId)
            ->where('is_selected', 1)
            ->with(['parentContent', 'childContent', 'grandchildContent'])
            ->first();

        if (!$currentSetting) {
            return $this->error('Setting not found or not selected.', 404);
        }

        // Get all selected settings for this report to determine next step
        $allSelectedSettings = WHSQECustomerSelectedSettings::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('whsq_report_id', $reportId)
            ->where('is_selected', 1)
            ->orderBy('sort_order')
            ->get();

        // Get next step ID
        $nextStepId = $this->getWHSQNextStepId($allSelectedSettings, $currentSetting->parent_id);

        // Get all related settings for the same parent to build complete hierarchy
        $relatedSettings = WHSQECustomerSelectedSettings::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('whsq_report_id', $reportId)
            ->where('parent_id', $currentSetting->parent_id) // Get all settings with same parent_id
            ->where('is_selected', 1)
            ->with(['parentContent', 'childContent', 'grandchildContent'])
            ->orderBy('id', 'asc')
            ->get();

        // Get all content records for this step and report with proper sorting
        $contentRecords = WHSQETableOfContentMeta::where('customer_id', $ids['customer_id'])
            ->where('workspace_id', $ids['workspace_id'])
            ->where('whsq_report_id', $reportId)
            ->where('step_id', $stepId)
            ->with(['options', 'dates'])
            ->orderBy('id', 'asc')
            ->get();

        // Organize content hierarchically - use all related settings to build complete hierarchy
        $organizedContent = $this->organizeWHSQContent($relatedSettings, $contentRecords);

        // Get navigation info
        $navigation = $this->getWHSQStepNavigation($currentSetting->parent_id, $reportId, $ids, $allSelectedSettings);

        return $this->success([
            'content' => $organizedContent,
            'step_id' => $stepId,
            'report_id' => $reportId,
            'next_step_id' => $nextStepId ?? null,
            'navigation' => $navigation,
        ], 'Step content retrieved successfully.');
    }

    /**
     * Save step content and settings
     */
    protected function saveWHSQStepContent($validated, $ids)
    {
        DB::beginTransaction();
        try {
            // Delete existing content for this step and report
            WHSQETableOfContentMeta::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('whsq_report_id', $validated['report_id'])
                ->where('step_id', $validated['step_id'])
                ->delete();

            // Store new content
            foreach ($validated['content_data'] as $index => $contentItem) {
                // Store parent content
                if (isset($contentItem['parent_content'])) {
                    $this->storeWHSQLevelContent(
                        $validated['report_id'],
                        $validated['step_id'],
                        $contentItem['parent_id'],
                        null,
                        null,
                        $contentItem['parent_content'],
                        'parent',
                        $contentItem['sort_order'] ?? $index,
                        $ids
                    );
                }

                // Store child content
                if (isset($contentItem['child_content'])) {
                    $this->storeWHSQLevelContent(
                        $validated['report_id'],
                        $validated['step_id'],
                        $contentItem['parent_id'],
                        $contentItem['child_id'],
                        null,
                        $contentItem['child_content'],
                        'child',
                        $contentItem['sort_order'] ?? $index,
                        $ids
                    );
                }

                // Store grandchild content
                if (isset($contentItem['grandchild_content'])) {
                    $this->storeWHSQLevelContent(
                        $validated['report_id'],
                        $validated['step_id'],
                        $contentItem['parent_id'],
                        $contentItem['child_id'],
                        $contentItem['grandchild_id'],
                        $contentItem['grandchild_content'],
                        'grandchild',
                        $contentItem['sort_order'] ?? $index,
                        $ids
                    );
                }
            }

            // Log the step content action
            $this->logWHSQReportAction(
                $validated['report_id'],
                'Step Content Saved',
                'Saved content for step ' . $validated['step_id'],
                $validated['step_id'],
                [
                    'step_id' => $validated['step_id'],
                    'content_count' => count($validated['content_data']),
                    'action_time' => now()->toDateTimeString()
                ]
            );

            DB::commit();

            // Get navigation info for the current step
            $selectedSettings = WHSQECustomerSelectedSettings::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('whsq_report_id', $validated['report_id'])
                ->where('is_selected', 1)
                ->orderBy('sort_order', 'asc')
                ->get();

            $navigation = $this->getWHSQStepNavigation($validated['step_id'], $validated['report_id'], $ids, $selectedSettings);

            return $this->success([
                'navigation' => $navigation,
                'selected_settings' => $selectedSettings->map(function ($setting) {
                    return [
                        'id' => $setting->id,
                        'parent_id' => $setting->parent_id,
                        'child_id' => $setting->child_id,
                        'grandchild_id' => $setting->grandchild_id,
                        'sort_order' => $setting->sort_order,
                        'is_selected' => $setting->is_selected
                    ];
                })
            ], 'Step content saved successfully.');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error('Failed to save step content: ' . $e->getMessage());
        }
    }

    /**
     * Get report progress summary
     */
    protected function getWHSQReportProgress($reportId, $ids)
    {
        try {
            // Get selected settings for this customer and report
            $selectedSettings = WHSQECustomerSelectedSettings::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('whsq_report_id', $reportId)
                ->where('is_selected', 1)
                ->orderBy('sort_order', 'asc')
                ->get();

            // If no selected settings, return empty progress
            if ($selectedSettings->isEmpty()) {
                return $this->success([
                    'total_steps' => 0,
                    'completed_steps' => 0,
                    'progress_percentage' => 0,
                    'remaining_steps' => 0,
                    'selected_steps' => [],
                    'message' => 'No steps selected for this report'
                ], 'Report progress retrieved successfully.');
            }

            // Get unique parent IDs only (each parent represents one step)
            $uniqueParentIds = $selectedSettings->pluck('parent_id')->unique()->filter()->values();
            $totalSteps = $uniqueParentIds->count();

            // Get completed steps (steps that have content)
            $completedSteps = WHSQETableOfContentMeta::where('customer_id', $ids['customer_id'])
                ->where('workspace_id', $ids['workspace_id'])
                ->where('whsq_report_id', $reportId)
                ->whereIn('step_id', $uniqueParentIds)
                ->distinct('step_id')
                ->count('step_id');

            // Calculate progress
            $progressPercentage = $totalSteps > 0 ? round(($completedSteps / $totalSteps) * 100, 2) : 0;
            $remainingSteps = $totalSteps - $completedSteps;

            // Get detailed step information
            $stepDetails = $uniqueParentIds->map(function ($parentId, $index) use ($reportId, $ids) {
                $hasContent = WHSQETableOfContentMeta::where('customer_id', $ids['customer_id'])
                    ->where('workspace_id', $ids['workspace_id'])
                    ->where('whsq_report_id', $reportId)
                    ->where('step_id', $parentId)
                    ->exists();

                return [
                    'step_number' => $index + 1,
                    'step_id' => $parentId,
                    'is_completed' => $hasContent,
                    'has_content' => $hasContent
                ];
            });

            $progress = [
                'total_steps' => $totalSteps,
                'completed_steps' => $completedSteps,
                'progress_percentage' => $progressPercentage,
                'remaining_steps' => $remainingSteps,
                'selected_steps' => $stepDetails,
                'step_summary' => [
                    'total' => $totalSteps,
                    'completed' => $completedSteps,
                    'pending' => $remainingSteps,
                    'percentage' => $progressPercentage
                ]
            ];

            return $this->success($progress, 'Report progress retrieved successfully.');
        } catch (Exception $e) {
            return $this->error('Error retrieving report progress: ' . $e->getMessage(), 500);
        }
    }

    /**
     * Organize WHSQ content hierarchically
     */
    private function organizeWHSQContent($selectedSettings, $contentRecords)
    {
        // Organize content hierarchically by parent using indexed arrays
        $contentByParent = [];

        // First, initialize the structure based on selected settings
        foreach ($selectedSettings as $setting) {
            $parentId = $setting->parent_id;
            $childId = $setting->child_id;
            $grandchildId = $setting->grandchild_id;

            // Initialize parent if not exists
            if (!isset($contentByParent[$parentId])) {
                $contentByParent[$parentId] = [
                    'parent_id' => $parentId,
                    'parent_title' => $setting->parentContent ? $setting->parentContent->title : null,
                    'parent_content' => [
                        'id' => null,
                        'step_id' => null,
                        'content' => null,
                        'start_new' => false,
                        'options' => [],
                        'dates' => [],
                        'children' => [],
                    ],
                ];
            }

            // Initialize child if exists
            if ($childId) {
                $childExists = false;
                foreach ($contentByParent[$parentId]['parent_content']['children'] as $existingChild) {
                    if ($existingChild['child_id'] == $childId) {
                        $childExists = true;
                        break;
                    }
                }

                if (!$childExists) {
                    $contentByParent[$parentId]['parent_content']['children'][] = [
                        'child_id' => $childId,
                        'child_title' => $setting->childContent ? $setting->childContent->title : null,
                        'id' => null,
                        'step_id' => null,
                        'content' => null,
                        'start_new' => false,
                        'options' => [],
                        'dates' => [],
                        'grandchildren' => [],
                    ];
                }
            }

            // Initialize grandchild if exists
            if ($grandchildId && $childId) {
                $childIndex = null;
                foreach ($contentByParent[$parentId]['parent_content']['children'] as $index => $child) {
                    if ($child['child_id'] == $childId) {
                        $childIndex = $index;
                        break;
                    }
                }

                if ($childIndex !== null) {
                    $grandchildExists = false;
                    foreach ($contentByParent[$parentId]['parent_content']['children'][$childIndex]['grandchildren'] as $existingGrandchild) {
                        if ($existingGrandchild['grandchild_id'] == $grandchildId) {
                            $grandchildExists = true;
                            break;
                        }
                    }

                    if (!$grandchildExists) {
                        $contentByParent[$parentId]['parent_content']['children'][$childIndex]['grandchildren'][] = [
                            'id' => null,
                            'step_id' => null,
                            'grandchild_id' => $grandchildId,
                            'grandchild_title' => $setting->grandchildContent ? $setting->grandchildContent->title : null,
                            'content' => null,
                            'start_new' => false,
                            'options' => [],
                            'dates' => [],
                        ];
                    }
                }
            }
        }

        // Now populate with actual content data
        foreach ($contentRecords as $record) {
            $parentId = $record->parent_id;

            // If this is parent level content (only parent_id, no child_id or grandchild_id)
            if ($record->parent_id && !$record->child_id && !$record->grandchild_id) {
                if (isset($contentByParent[$parentId])) {
                    $contentByParent[$parentId]['parent_content']['id'] = $record->id;
                    $contentByParent[$parentId]['parent_content']['step_id'] = $record->step_id;
                    $contentByParent[$parentId]['parent_content']['content'] = $record->processed_content ?? $record->content;
                    $contentByParent[$parentId]['parent_content']['start_new'] = $record->start_new ?? false;
                    $contentByParent[$parentId]['parent_content']['options'] = $this->formatWHSQOptions($record->options);
                    $contentByParent[$parentId]['parent_content']['dates'] = $this->formatWHSQDates($record->dates);
                }
            }
            // If this is child level content (has parent_id and child_id, but no grandchild_id)
            elseif ($record->parent_id && $record->child_id && !$record->grandchild_id) {
                $childId = $record->child_id;

                if (isset($contentByParent[$parentId])) {
                    foreach ($contentByParent[$parentId]['parent_content']['children'] as &$child) {
                        if ($child['child_id'] == $childId) {
                            $child['id'] = $record->id;
                            $child['step_id'] = $record->step_id;
                            $child['content'] = $record->processed_content ?? $record->content;
                            $child['start_new'] = $record->start_new ?? false;
                            $child['options'] = $this->formatWHSQOptions($record->options);
                            $child['dates'] = $this->formatWHSQDates($record->dates);
                            break;
                        }
                    }
                }
            }
            // If this is grandchild level content (has parent_id, child_id, and grandchild_id)
            elseif ($record->parent_id && $record->child_id && $record->grandchild_id) {
                $childId = $record->child_id;
                $grandchildId = $record->grandchild_id;

                if (isset($contentByParent[$parentId])) {
                    foreach ($contentByParent[$parentId]['parent_content']['children'] as &$child) {
                        if ($child['child_id'] == $childId) {
                            foreach ($child['grandchildren'] as &$grandchild) {
                                if ($grandchild['grandchild_id'] == $grandchildId) {
                                    $grandchild['id'] = $record->id;
                                    $grandchild['step_id'] = $record->step_id;
                                    $grandchild['content'] = $record->processed_content ?? $record->content;
                                    $grandchild['start_new'] = $record->start_new ?? false;
                                    $grandchild['options'] = $this->formatWHSQOptions($record->options);
                                    $grandchild['dates'] = $this->formatWHSQDates($record->dates);
                                    break 2;
                                }
                            }
                        }
                    }
                }
            }
        }

        // Convert to indexed arrays and sort by ID
        $organizedContent = [];
        foreach ($contentByParent as $parentId => $parentData) {
            $parentItem = [
                'parent_id' => $parentId,
                'parent_title' => $parentData['parent_title'],
                'parent_content' => $parentData['parent_content'],
            ];

            // Always include children array and ensure titles are preserved
            $children = collect($parentData['parent_content']['children'])->map(function ($child) {
                // Ensure child title is always included even if content is null
                return [
                    'child_id' => $child['child_id'],
                    'child_title' => $child['child_title'], // This should now have the proper title from relationship
                    'id' => $child['id'],
                    'step_id' => $child['step_id'],
                    'content' => $child['content'],
                    'start_new' => $child['start_new'] ?? false,
                    'options' => $child['options'],
                    'dates' => $child['dates'],
                    'grandchildren' => collect($child['grandchildren'])->map(function ($grandchild) {
                        // Ensure grandchild title is always included even if content is null
                        return [
                            'id' => $grandchild['id'],
                            'step_id' => $grandchild['step_id'],
                            'grandchild_id' => $grandchild['grandchild_id'],
                            'grandchild_title' => $grandchild['grandchild_title'], // This should now have the proper title from relationship
                            'content' => $grandchild['content'],
                            'start_new' => $grandchild['start_new'] ?? false,
                            'options' => $grandchild['options'],
                            'dates' => $grandchild['dates'],
                        ];
                    })->sortBy('id')->values()
                ];
            })->sortBy('id')->values();
            
            $parentItem['parent_content']['children'] = $children;

            $organizedContent[] = $parentItem;
        }

        // Sort parents by ID ASC
        return collect($organizedContent)->sortBy('id')->values();
    }

    /**
     * Get WHSQ next step ID
     */
    private function getWHSQNextStepId($selectedSettings, $stepId)
    {
        if ($selectedSettings->isEmpty()) {
            return null;
        }

        // Get unique parent IDs only (each parent represents one step)
        $uniqueParentIds = $selectedSettings->pluck('parent_id')->unique()->filter()->sort()->values();

        // Find current step index in unique parent IDs
        $currentStepIndex = $uniqueParentIds->search($stepId);

        if ($currentStepIndex !== false && $currentStepIndex < $uniqueParentIds->count() - 1) {
            $nextParentId = $uniqueParentIds[$currentStepIndex + 1];

            // Find the WHSQECustomerSelectedSettings record with this parent_id and return its primary key ID
            $nextSetting = $selectedSettings->where('parent_id', $nextParentId)->first();
            return $nextSetting ? $nextSetting->id : null;
        }

        return null;
    }

    /**
     * Get WHSQ step navigation
     */
    private function getWHSQStepNavigation($currentStepId, $reportId, $userTable, $selectedSettings)
    {
        if ($selectedSettings->isEmpty()) {
            return null;
        }

        // Get unique parent IDs only (each parent represents one step)
        $uniqueParentIds = $selectedSettings->pluck('parent_id')->unique()->filter()->sort()->values();

        // Find current step index in unique parent IDs
        $currentStepIndex = $uniqueParentIds->search($currentStepId);

        if ($currentStepIndex === false) {
            return null;
        }

        $currentSetting = $selectedSettings->where('parent_id', $currentStepId)->first();
        $navigation = [
            'current_step' => [
                'id' => $currentSetting ? $currentSetting->id : null, // Return WHSQECustomerSelectedSettings primary key ID
                'parent_id' => $currentStepId, // Keep parent_id for reference
                'step_number' => $currentStepIndex + 1
            ],
            'total_steps' => $uniqueParentIds->count(),
            'current_step_number' => $currentStepIndex + 1
        ];

        // Get next step
        if ($currentStepIndex < $uniqueParentIds->count() - 1) {
            $nextParentId = $uniqueParentIds[$currentStepIndex + 1];
            $nextSetting = $selectedSettings->where('parent_id', $nextParentId)->first();
            $navigation['next_step'] = [
                'id' => $nextSetting ? $nextSetting->id : null, // Return WHSQECustomerSelectedSettings primary key ID
                'parent_id' => $nextParentId, // Keep parent_id for reference
                'step_number' => $currentStepIndex + 2,

            ];
        }

        // Get previous step
        if ($currentStepIndex > 0) {
            $prevParentId = $uniqueParentIds[$currentStepIndex - 1];
            $prevSetting = $selectedSettings->where('parent_id', $prevParentId)->first();
            $navigation['previous_step'] = [
                'id' => $prevSetting ? $prevSetting->id : null, // Return WHSQECustomerSelectedSettings primary key ID
                'parent_id' => $prevParentId, // Keep parent_id for reference
                'step_number' => $currentStepIndex,

            ];
        }

        return $navigation;
    }

    /**
     * Store WHSQ content for a specific level (parent, child, or grandchild)
     */
    private function storeWHSQLevelContent($reportId, $stepId, $parentId, $childId, $grandchildId, $levelContent, $level, $sortOrder, $userTable)
    {
        // Process summernote content (extract and save base64 images)
        $processedContent = null;
        if (isset($levelContent['content']) && $levelContent['content']) {
            $processedContent = WHSQETableOfContentMeta::processSummernoteContent(
                $levelContent['content'],
                $reportId,
                $stepId
            );
        }

        // Create content record for this level
        $contentMeta = WHSQETableOfContentMeta::create([
            'whsq_report_id' => $reportId,
            'step_id' => $stepId,
            'parent_id' => $parentId,
            'child_id' => $childId,
            'grandchild_id' => $grandchildId,
            'content' => $processedContent ?? $levelContent['content'] ?? null,
            'sort_order' => $sortOrder,
            'start_new' => $levelContent['start_new'] ?? false,
            'customer_id' => $userTable['customer_id'],
            'workspace_id' => $userTable['workspace_id']
        ]);

        // Store options for this level (only if they exist and have required data)
        if (isset($levelContent['options']) && is_array($levelContent['options'])) {
            foreach ($levelContent['options'] as $option) {
                // Only create option if it has the minimum required data
                if (isset($option['option_id']) && isset($option['option_value']) && isset($option['option_type']) && isset($option['option_label'])) {
                    WHSQEContentOption::create([
                        'content_meta_id' => $contentMeta->id,
                        'option_id' => $option['option_id'],
                        'option_value' => $option['option_value'],
                        'option_type' => $option['option_type'],
                        'option_label' => $option['option_label'],
                        'main_heading' => $option['main_heading'] ?? null,
                        'group_order' => $option['group_order'] ?? null,
                        'level' => $level,
                        'level_id' => $this->getWHSQLevelId($parentId, $childId, $grandchildId, $level),
                        'customer_id' => $userTable['customer_id'],
                        'workspace_id' => $userTable['workspace_id']
                    ]);
                }
            }
        }

        // Store dates for this level (only if they exist and have required data)
        if (isset($levelContent['dates']) && is_array($levelContent['dates'])) {
            foreach ($levelContent['dates'] as $date) {
                // Only create date if it has the minimum required data
                if (isset($date['date_value'])) {
                    WHSQEContentDate::create([
                        'content_meta_id' => $contentMeta->id,
                        'date_value' => $date['date_value'],
                        'date_label' => $date['date_label'] ?? null,
                        'date_type' => $date['date_type'] ?? null,
                        'level' => $level,
                        'level_id' => $this->getWHSQLevelId($parentId, $childId, $grandchildId, $level),
                        'customer_id' => $userTable['customer_id'],
                        'workspace_id' => $userTable['workspace_id']
                    ]);
                }
            }
        }
    }

    /**
     * Get the appropriate WHSQ level ID based on the level
     */
    private function getWHSQLevelId($parentId, $childId, $grandchildId, $level)
    {
        switch ($level) {
            case 'parent':
                return $parentId;
            case 'child':
                return $childId;
            case 'grandchild':
                return $grandchildId;
            default:
                return null;
        }
    }

    /**
     * Format WHSQ options for consistent structure
     */
    private function formatWHSQOptions($options)
    {
        if (!$options || $options->count() === 0) {
            return [];
        }

        return $options->map(function ($option) {
            return [
                'id' => $option->id,
                'option_id' => $option->option_id,
                'option_value' => $option->option_value,
                'option_type' => $option->option_type,
                'option_label' => $option->option_label,
                'main_heading' => $option->main_heading,
                'group_order' => $option->group_order,
                'is_checked' => $option->option_value === 'checked',
                'display_value' => $option->option_value === 'checked' ? 'Yes' : 'No'
            ];
        })->values();
    }

    /**
     * Format WHSQ dates for consistent structure
     */
    private function formatWHSQDates($dates)
    {
        if (!$dates || $dates->count() === 0) {
            return [];
        }

        return $dates->map(function ($date) {
            return [
                'id' => $date->id,
                'date_value' => $date->date_value,
                'date_label' => $date->date_label,
                'date_type' => $date->date_type,
                'formatted_date' => $date->date_value,
                'display_date' => $date->display_date
            ];
        })->values();
    }

    /**
     * Log WHSQ report action
     */
    private function logWHSQReportAction($reportId, $actionType, $message, $stepNumber = null, $changes = null)
    {
        if (!$reportId) {
            return;
        }
        $userTable = $this->getUserTable();
        $authId = 0;
        $workspaceId = 0;
        if ($userTable === "customer") {
            $customerId = auth()->id();
            $workspaceId = auth()->user()->current_workspace_id;
        }
        if ($userTable === "emp") {
            $authId = auth()->id();
            $customerId = auth()->user()->customer_id;
            $workspaceId = auth()->user()->workspace_id;
        }
        WHSQEReportLog::create([
            'report_id' => $reportId,
            'employee_id' => $authId,
            'action_type' => $actionType,
            'step_number' => $stepNumber ?? 0,
            'message' => $message,
            'changes' => $changes,
            'customer_id' => $customerId,
            'workspace_id' => $workspaceId
        ]);
    }
    
    /**
     * Store WHSQ quick entry - create new report with basic info, signatures, and PDF
     */
    public function whseqQuickEntryStore(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            [
                'document_title' => 'required|string|max:255',
                'document_number' => 'required|string|max:255',
                'authorised_by' => 'required|integer|exists:emp_personal_details,emp_id',
                'site_id' => 'required|integer|exists:sites,id',
                'revision_number' => 'nullable|string',
                'revision_date' => 'nullable|date',
                'next_revision_date' => 'nullable|date|after_or_equal:revision_date',
                'sign_off' => 'nullable|array',
                'sign_off.*.emp_id' => 'required_with:sign_off|integer|exists:emp_personal_details,emp_id',
                'sign_off.*.is_site_employee' => 'nullable|boolean',
                'sign_off.*.job_description' => 'nullable|string',
                'sign_off.*.induction_date' => 'nullable|date',
                'file' => 'required|file|max:20480',
            ],
            [
                'file.required' => 'WHSQ report summary PDF is required.',
            ]
        );

        if ($validator->fails()) {
            $this->logWHSQReportAction(
                0,
                'WHSEQ Quick Entry Validation Error',
                'WHSEQ quick entry validation error: ' . $validator->errors()->first(),
                null,
                [
                    'errors' => $validator->errors()->toArray(),
                    'action_time' => now()->toDateTimeString()
                ]
            );
            return $this->error($validator->errors()->first(), 422);
        }

        try {
            DB::beginTransaction();
            
            $userTable = $this->getUserTable();
            $authUser = auth()->user();
            $customerId = null;
            $workspaceId = null;
            
            if ($userTable === 'customer') {
                $customerId = $authUser->id;
                $workspaceId = $authUser->current_workspace_id;
            } elseif ($userTable === 'emp') {
                $customerId = $authUser->customer_id;
                $workspaceId = $authUser->workspace_id;
            } else {
                return $this->error('You do not have permission to create this record.', 403);
            }

            // Generate revision number if not provided
            $revisionNumber = $request->revision_number ?? 'R1';
            $revisionDate = $request->revision_date ?? now()->toDateString();
            $nextRevisionDate = $request->next_revision_date ?? now()->addYear()->toDateString();

            // Create WHSQ report
            $whsqReport = WhsqReport::create([
                'document_title' => $validator->validated()['document_title'],
                'document_number' => $validator->validated()['document_number'],
                'authorised_by' => $validator->validated()['authorised_by'],
                'site_id' => $validator->validated()['site_id'],
                'revision_number' => $revisionNumber,
                'revision_date' => $revisionDate,
                'next_revision_date' => $nextRevisionDate,
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
                'is_completed' => 1,
                'publish' => false,
                'created_by' => $userTable === 'emp' ? $authUser->id : null,
                'report_method'=>1,
            ]);

            // Handle signatures
            $signatureEntries = collect($request->input('sign_off', []))->filter(function ($entry) {
                return isset($entry['emp_id']) && !empty($entry['emp_id']);
            });

            foreach ($signatureEntries as $entry) {
                WhsqSignature::create([
                    'whsq_report_id' => $whsqReport->id,
                    'employee_id' => $entry['emp_id'],
                    'is_site_employee' => $entry['is_site_employee'] ?? false,
                    'job_description' => $entry['job_description'] ?? null,
                    'induction_date' => $entry['induction_date'] ?? now()->toDateString(),
                    'customer_id' => $customerId,
                    'workspace_id' => $workspaceId,
                ]);
            }

            // Upload PDF file
            $fileUrl = $this->handleFileImageUpload($request, 'whsqe_report')['path'] ?? null;

            GeneratedPdfReport::updateOrCreate(
                [
                    'report_id' => $whsqReport->id,
                    'report_type' => 'whsqe_report',
                ],
                [
                    'path' => $fileUrl,
                    'customer_id' => $customerId,
                    'workspace_id' => $workspaceId,
                ]
            );

            DB::commit();

            // Log the action
            $this->logWHSQReportAction(
                $whsqReport->id,
                'WHSEQ Quick Entry Created',
                'WHSEQ quick entry created successfully',
                null,
                [
                    'document_title' => $whsqReport->document_title,
                    'document_number' => $whsqReport->document_number,
                    'signatures_count' => $signatureEntries->count(),
                    'action_time' => now()->toDateTimeString()
                ]
            );

            return $this->success([
                'whsq_report_id' => $whsqReport->id,
                'pdf_url' => $fileUrl,
            ], 'WHSEQ quick entry saved successfully.');
        } catch (Exception $e) {
            DB::rollBack();
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $this->logWHSQReportAction(
                0,
                'WHSEQ Quick Entry Error',
                'WHSEQ quick entry error: ' . $shortMessage,
                null,
                [
                    'error' => $shortMessage,
                    'action_time' => now()->toDateTimeString()
                ]
            );
            return $this->error('An error occurred: ' . $shortMessage, 500);
        }
    }

    /**
     * Edit WHSQ quick entry - retrieve report data for editing
     */
    public function whseqQuickEntryEdit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'whsq_report_id' => 'required|integer|exists:whsq_reports,id',
        ]);

        if ($validator->fails()) {
            $this->logWHSQReportAction(
                $request->get('whsq_report_id', 0),
                'WHSEQ Quick Entry Edit Validation Error',
                'WHSEQ quick entry edit validation error: ' . $validator->errors()->first(),
                null,
                [
                    'errors' => $validator->errors()->toArray(),
                    'action_time' => now()->toDateTimeString()
                ]
            );
            return $this->error($validator->errors()->first(), 422);
        }

        try {
            $whsqReport = WhsqReport::with('site')->find($request->whsq_report_id);
            if (!$whsqReport) {
                return $this->error('WHSEQ report not found.', 404);
            }

            $userTable = $this->getUserTable();
            $authUser = auth()->user();
            $customerId = $userTable === 'customer' ? $authUser->id : $authUser->customer_id;
            $workspaceId = $userTable === 'customer' ? $authUser->current_workspace_id : $authUser->workspace_id;

            if ($whsqReport->customer_id !== $customerId || $whsqReport->workspace_id !== $workspaceId) {
                return $this->error('You do not have access to this report.', 403);
            }

            // Get signatures
            $signatureEntries = WhsqSignature::where('whsq_report_id', $whsqReport->id)
                ->get()
                ->map(function ($signature) {
                    return [
                        'emp_id' => $signature->employee_id,
                        'is_site_employee' => $signature->is_site_employee,
                        'job_description' => $signature->job_description,
                        'induction_date' => $signature->induction_date,
                    ];
                })
                ->toArray();

            // Get generated report
            $generatedReport = GeneratedPdfReport::where('report_type', 'whsqe_report')
                ->where('report_id', $whsqReport->id)
                ->first();

            $responseData = [
                'whsq_report_id' => $whsqReport->id,
                'document_title' => $whsqReport->document_title,
                'document_number' => $whsqReport->document_number,
                'authorised_by' => $whsqReport->authorised_by,
                'site_id' => $whsqReport->site_id,
                'revision_number' => $whsqReport->revision_number,
                'revision_date' => $whsqReport->revision_date,
                'next_revision_date' => $whsqReport->next_revision_date,
                'sign_off' => $signatureEntries,
                'pdf_url' => $generatedReport->path ?? null,
            ];

            return $this->success($responseData, 'WHSEQ quick entry fetched successfully.');
        } catch (Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $this->logWHSQReportAction(
                $request->whsq_report_id,
                'WHSEQ Quick Entry Edit Error',
                'WHSEQ quick entry edit error: ' . $shortMessage,
                null,
                [
                    'error' => $shortMessage,
                    'action_time' => now()->toDateTimeString()
                ]
            );
            return $this->error('An error occurred: ' . $shortMessage, 500);
        }
    }

    /**
     * Update WHSQ quick entry - update report with new data
     */
    public function whseqQuickEntryUpdate(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            [
                'whsq_report_id' => 'required|integer|exists:whsq_reports,id',
                'document_title' => 'required|string|max:255',
                'document_number' => 'required|string|max:255',
                'authorised_by' => 'required|integer|exists:emp_personal_details,emp_id',
                'site_id' => 'required|integer|exists:sites,id',
                'revision_number' => 'nullable|string',
                'revision_date' => 'nullable|date',
                'next_revision_date' => 'nullable|date|after_or_equal:revision_date',
                'sign_off' => 'nullable|array',
                'sign_off.*.emp_id' => 'required_with:sign_off|integer|exists:emp_personal_details,emp_id',
                'sign_off.*.is_site_employee' => 'nullable|boolean',
                'sign_off.*.job_description' => 'nullable|string',
                'sign_off.*.induction_date' => 'nullable|date',
                'file' => 'nullable|file|max:20480',
            ]
        );

        if ($validator->fails()) {
            $this->logWHSQReportAction(
                $request->get('whsq_report_id', 0),
                'WHSEQ Quick Entry Update Validation Error',
                'WHSEQ quick entry update validation error: ' . $validator->errors()->first(),
                null,
                [
                    'errors' => $validator->errors()->toArray(),
                    'action_time' => now()->toDateTimeString()
                ]
            );
            return $this->error($validator->errors()->first(), 422);
        }

        try {
            DB::beginTransaction();
            
            $whsqReport = WhsqReport::find($request->whsq_report_id);
            if (!$whsqReport) {
                return $this->error('WHSEQ report not found.', 404);
            }

            $userTable = $this->getUserTable();
            $authUser = auth()->user();
            $customerId = $userTable === 'customer' ? $authUser->id : $authUser->customer_id;
            $workspaceId = $userTable === 'customer' ? $authUser->current_workspace_id : $authUser->workspace_id;

            if ($whsqReport->customer_id !== $customerId || $whsqReport->workspace_id !== $workspaceId) {
                return $this->error('You do not have access to this report.', 403);
            }

            // Check if report is published - if so, create new version and update that instead
            if ($whsqReport->publish) {
                $newReport = $whsqReport->createNewVersion();
                // Update the new version with the provided data
                $newReport->update([
                    'document_title' => $request->document_title,
                    'document_number' => $request->document_number,
                    'authorised_by' => $request->authorised_by,
                    'site_id' => $request->site_id,
                    'revision_date' => $request->revision_date ?? now()->toDateString(),
                    'next_revision_date' => $request->next_revision_date ?? now()->addYear()->toDateString(),
                    'publish' => false, // New version starts as unpublished
                ]);
                $whsqReport = $newReport; // Use the new report for subsequent operations
            }

            // Update report
            $whsqReport->update([
                'document_title' => $request->document_title,
                'document_number' => $request->document_number,
                'authorised_by' => $request->authorised_by,
                'site_id' => $request->site_id,
                'revision_number' => $request->revision_number ?? $whsqReport->revision_number,
                'revision_date' => $request->revision_date ?? $whsqReport->revision_date,
                'next_revision_date' => $request->next_revision_date ?? $whsqReport->next_revision_date,
            ]);

            // Update signatures
            $currentEmployeeIds = collect($request->input('sign_off', []))
                ->pluck('emp_id')
                ->filter(function($empId) {
                    return !empty($empId);
                })
                ->toArray();

            $existingEmployeeIds = WhsqSignature::where('whsq_report_id', $whsqReport->id)
                ->pluck('employee_id')
                ->toArray();

            $employeesToRemove = array_diff($existingEmployeeIds, $currentEmployeeIds);

            if (!empty($employeesToRemove)) {
                WhsqSignature::where('whsq_report_id', $whsqReport->id)
                    ->whereIn('employee_id', $employeesToRemove)
                    ->delete();
            }

            foreach ($request->input('sign_off', []) as $entry) {
                if (empty($entry['emp_id'])) {
                    continue;
                }

                $existingRecord = WhsqSignature::where('whsq_report_id', $whsqReport->id)
                    ->where('employee_id', $entry['emp_id'])
                    ->first();

                if ($existingRecord) {
                    $existingRecord->update([
                        'is_site_employee' => $entry['is_site_employee'] ?? false,
                        'job_description' => $entry['job_description'] ?? null,
                        'induction_date' => $entry['induction_date'] ?? now()->toDateString(),
                    ]);
                } else {
                    WhsqSignature::create([
                        'whsq_report_id' => $whsqReport->id,
                        'employee_id' => $entry['emp_id'] ?? null,
                        'is_site_employee' => $entry['is_site_employee'] ?? false,
                        'job_description' => $entry['job_description'] ?? null,
                        'induction_date' => $entry['induction_date'] ?? now()->toDateString(),
                        'customer_id' => $customerId,
                        'workspace_id' => $workspaceId,
                    ]);
                }
            }

            // Handle file upload
            $existingFilePath = GeneratedPdfReport::where('report_type', 'whsqe_report')
                ->where('report_id', $whsqReport->id)
                ->value('path');
            
            $fileUrl = $existingFilePath;

            if ($request->hasFile('file')) {
                $uploadResult = $this->handleFileImageUpload($request, 'whsqe_report', $existingFilePath);
                $fileUrl = $uploadResult['path'] ?? $fileUrl;
            }

            GeneratedPdfReport::updateOrCreate(
                [
                    'report_id' => $whsqReport->id,
                    'report_type' => 'whsqe_report',
                ],
                [
                    'path' => $fileUrl,
                    'customer_id' => $customerId,
                    'workspace_id' => $workspaceId,
                ]
            );

            DB::commit();

            // Log the action
            $this->logWHSQReportAction(
                $whsqReport->id,
                'WHSEQ Quick Entry Updated',
                'WHSEQ quick entry updated successfully',
                null,
                [
                    'document_title' => $whsqReport->document_title,
                    'document_number' => $whsqReport->document_number,
                    'signatures_count' => count($currentEmployeeIds),
                    'action_time' => now()->toDateTimeString()
                ]
            );

            return $this->success([
                'whsq_report_id' => $whsqReport->id,
                'pdf_url' => $fileUrl,
            ], 'WHSEQ quick entry updated successfully.');
        } catch (Exception $e) {
            DB::rollBack();
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $this->logWHSQReportAction(
                $request->whsq_report_id,
                'WHSEQ Quick Entry Update Error',
                'WHSEQ quick entry update error: ' . $shortMessage,
                null,
                [
                    'error' => $shortMessage,
                    'action_time' => now()->toDateTimeString()
                ]
            );
            return $this->error('An error occurred: ' . $shortMessage, 500);
        }
    }
}
