<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf;
use Exception;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\IncidentImage;
use App\Models\IncidentReport;
use App\Models\InspectionPlan;
use App\Models\EmpCompanyDetails;
use App\Models\EmpPersonalDetails;
use App\Models\GeneratedPdfReport;
use App\Models\IncidentClassificationReport;
use App\Models\IncidentDocument;
use App\Models\IncidentEmployeeInjuryType;
use App\Models\IncidentEmployerDetail;
use App\Models\IncidentFinalClassification;
use App\Models\IncidentReportQuestion;
use Illuminate\Support\Facades\Validator;
use App\Models\IncidentInjuryManagement;
use App\Models\IncidentInvolvedPersonDetail;
use App\Models\IncidentInvolvedPersonTraining;
use App\Models\IncidentNotifiableClassification;
use App\Models\IncidentNotifiedTo;
use App\Models\IncidentReportedBy;
use App\Models\IncidentReportedTo;
use App\Models\IncidentReportMeta;
use App\Models\IncidentReportNotifiableClassification;
use App\Models\IncidentReportQuestionAnswer;
use App\Models\IncidentRiskCategoryDetail;
use App\Models\IncidentSignoff;
use App\Models\IncidentWitnes;
use App\Models\EmpType;
use App\Models\InspectionPlanSignature;
use App\Models\MeetingNoteSignature;
use App\Models\Role;
use App\Models\Swms;
use App\Models\SwmsApprovedBy;
use App\Models\swmsDevelopedBy;
use App\Models\SwmsSignature;
use App\Models\WhsReport;
use App\Models\WhsSignature;
use App\Models\WhsqReport;
use App\Models\WhsqSignature;
use App\Models\Sites;

class IncidentReportController extends Controller
{
    /**
     * Format report type display name with proper capitalization
     */
    private function formatReportTypeDisplay($reportType)
    {
        // Convert underscores to spaces and handle special cases
        $formatted = str_replace('_', ' ', $reportType);
        
        // Special cases that should be fully capitalized
        $specialCases = [
            'whsqe report' => 'WHSQE Report',
            'whs report' => 'WHS Report', 
            'swms report' => 'SWMS Report'
        ];
        
        // Check if it's a special case
        if (isset($specialCases[strtolower($formatted)])) {
            return $specialCases[strtolower($formatted)];
        }
        
        // For other reports, use title case (first letter of each word capitalized)
        return ucwords(strtolower($formatted));
    }

    public function index(Request $request)
    {
        // $auth_id = auth()->user()->id;
        $userTable = $this->getUserTable(); // Get whether user is a customer or employee
        $query = IncidentReport::query()
            ->orderBy('id', 'DESC')
            ->where('del', '0')
            ->with('authorisedBy');
        // Filter based on user type
        if ($userTable === 'customer') {
            $query->where('customer_id', auth()->id())
                ->where('workspace_id', auth()->user()->current_workspace_id);
        } elseif ($userTable === 'emp') {
            $sites = Sites::where('customer_id', auth()->user()->customer_id)
            ->where('workspace_id', auth()->user()->workspace_id)
            ->where('sso_id', auth()->user()->id)
            ->where('active',1)
            ->where('del',0)
            ->pluck('id');
            $query->where('customer_id', auth()->user()->customer_id)
                ->where('workspace_id', auth()->user()->workspace_id)
                ->whereIn('site_id', $sites);
           
        }
        // Apply single search filter
        if ($request->filled('search')) {
            $searchTerm = $request->search;
        
            $query->where(function ($q) use ($searchTerm) {
                // Search in title or document number
                $q->where('title', 'like', '%' . $searchTerm . '%')
                  ->orWhere('document_number', 'like', '%' . $searchTerm . '%')
                  ->orWhereHas('authorisedBy', function ($subquery) use ($searchTerm) {
                      $subquery->where(function ($nameQuery) use ($searchTerm) {
                          $nameQuery->where('first_name', 'like', '%' . $searchTerm . '%')
                                    ->orWhere('middle_name', 'like', '%' . $searchTerm . '%')
                                    ->orWhere('last_name', 'like', '%' . $searchTerm . '%');
                      });
                  });
            });
        }        
        $query_result = $query->get();
        foreach ($query_result as $report) {
            $generatedReport = GeneratedPdfReport::where([
                ['report_type', 'incident_report'],
                ['report_id', $report->id]
            ])->first();
            $report->generated_report_url = $generatedReport ? $generatedReport->path : null;
        }
        return $this->withCount($query_result, 'Get Incident Reports List Successfully');
    }



    private function generateRevisionNumber($parentIncidentReportId = null)
    {
        if (!$parentIncidentReportId) {
            return 1; // Return integer 1 for first revision
        }
        $highestRevision = IncidentReport::where(function ($query) use ($parentIncidentReportId) {
            $query->where('id', $parentIncidentReportId) // The parent report
                ->orWhere('parent_number', $parentIncidentReportId); // All child reports
        })
            ->where('del', 0) // Assuming you have a soft delete field
            ->max('revision_number');
        return $highestRevision ? (int)$highestRevision + 1 : 1; // Ensure integer return
    }
    public function storeStep1(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required',
            'title' => 'required',
            'document_number' => 'required',
            'authorised_by' => 'required',
            'issue_date' => 'nullable|date',
            'revision_date' => 'nullable|date|after_or_equal:issue_date',
            'site_id' => 'required',
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $userTable = $this->getUserTable(); // Get the user type (customer or emp)
            if ($userTable == "customer") {
                $customer_id = auth()->id();
                $workspace_id = auth()->user()->current_workspace_id;
            } elseif ($userTable == "emp") {
                $customer_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            }
            $msg = '';
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            if (!$incidentReport) {
                // Creating new report
                $uniqueRevisionNumber = $this->generateRevisionNumber(); // This should return integer 1
                // Validate issue & revision date only when creating a new report
                $validator = Validator::make($request->all(), [
                    'issue_date' => 'nullable|date',
                    'revision_date' => 'nullable|date|after_or_equal:issue_date',
                ]);
                if ($validator->fails()) {
                    storeReportsLogs([
                        'employee_id' => auth()->user()->id,
                        'message' => $validator->errors()->first(),
                        'report_id' => $request->incident_report_id,
                        'report_type' => 'incident_report',
                        'error_type' => 'validation error'
                    ]);
                    return $this->message($validator->errors()->first(), 422);
                }
                // Prepare data for new incident report with unique revision number
                $incidentReportData = [
                    'title' => $validatedData['title'],
                    'document_number' => $validatedData['document_number'],
                    'authorised_by' => $validatedData['authorised_by'] ?? 0,
                    'revision_number' => $uniqueRevisionNumber, // This is now an integer
                    'issue_date' => $validatedData['issue_date'] ?? null,
                    'revision_date' => $validatedData['revision_date'] ?? null,
                    'site_id' => $validatedData['site_id'] ?? null,
                    'customer_id' => $customer_id,
                    'workspace_id' => $workspace_id,
                ];
                // Create new incident report
                $incidentReport = IncidentReport::create($incidentReportData);
                $validatedData['incident_report_id'] = $incidentReport->id;
                $msg = 'Report Created Successfully with revision number: ' . $uniqueRevisionNumber;
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => $msg . " with id " . $incidentReport->id,
                    'report_id' => $incidentReport->id,
                    'report_type' => 'incident_report'
                ]);
            } else {
                // For updates, only modify document_number if a new one is provided
                $document_number = $validatedData['document_number']; // Keep existing
                $incidentReportData = [
                    'title' => $validatedData['title'],
                    'document_number' => $document_number,
                    'authorised_by' => $validatedData['authorised_by'] ?? 0,
                    // Keep existing revision number - don't change it
                    'revision_number' => $incidentReport->revision_number,
                    'issue_date' => $validatedData['issue_date'] ?? $incidentReport->issue_date,
                    'revision_date' => $validatedData['revision_date'] ?? $incidentReport->revision_date,
                    'site_id' => $validatedData['site_id'] ?? $incidentReport->site_id,
                    'customer_id' => $customer_id,
                    'workspace_id' => $workspace_id,
                ];
                $incidentReport->update($incidentReportData);
                $msg = 'Report Updated Successfully (Revision: ' . $incidentReport->revision_number . ')';
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Report updated for ID: ' . $incidentReport->id,
                    'report_id' => $incidentReport->id,
                    'report_type' => 'incident_report'
                ]);
            }
            // Final logging for step completion
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 1 ' . $msg,
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report'
            ]);
            // Fetch employee access role (only if authorised_by is provided)
            // if (!empty($validatedData['authorised_by'])) {
            //     $userAuthorizedBy = EmpCompanyDetails::with(['EmpPersonalDetails', 'accessRole', 'accessTier'])
            //         ->find($validatedData['authorised_by']);
            //     $accessRole = $userAuthorizedBy->accessRole->code ?? null;
            //     // Create or update incident signoff
            //     IncidentSignoff::updateOrCreate(
            //         [
            //             'incident_report_id' => $validatedData['incident_report_id'],
            //             'emp_id' => $validatedData['authorised_by'],
            //         ],
            //         [
            //             'role_code' => $accessRole,
            //             'emp_id' => $validatedData['authorised_by'],
            //         ]
            //     );
            // }
            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], $msg);
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 1 encountered an error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'] ?? null,
                'report_type' => 'incident_report',
                'error_type' => 'exception error'
            ]);
            return $this->error('An error occurred: ' . $e->getMessage());
        }
    }

    public function editStep1(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required'
        ]);
        if ($validator->fails()) {
            return response()->json([
                'message' => $validator->errors()->first()
            ], 422);
        }
        try {
            $validatedData =  $validator->validated();
            if ($validatedData['incident_report_id'] != 0) {
                $incident_report = IncidentReport::with('sitesData')
                    ->where('id', $validatedData['incident_report_id'])->first();
            } else {
                $incident_report = IncidentReport::with('sitesData')->where('id', $validatedData['incident_report_id'])
                    ->first();
            }
            if ($incident_report) {
                $userTable = $this->getUserTable();
                if ($userTable === 'customer' && ($incident_report->customer_id !== auth()->id() || $incident_report->workspace_id !== auth()->user()->current_workspace_id)) {
                    return $this->message('You do not have access to this report.', 403);
                } else {
                    $customerId = auth()->user()->id;
                    $workspaceId = auth()->user()->current_workspace_id;
                }
                if ($userTable === 'emp' && ($incident_report->customer_id !== auth()->user()->customer_id || $incident_report->workspace_id !== auth()->user()->workspace_id)) {
                    return $this->message('You do not have access to this report.', 403);
                } else {
                    $customerId = auth()->user()->customer_id;
                    $workspaceId = auth()->user()->workspace_id;
                }
            }

            $emp_list = EmpCompanyDetails::where('compeleted', '1')
                ->where('approved', '1')
                ->where('status', '1')
                ->where('del', '0')
                ->with([
                    'empPersonalDetails' => function ($query) {
                        $query->select('emp_id', 'first_name', 'middle_name', 'last_name');
                    },
                    'accessRole' => function ($query) {
                        $query->select('id', 'title', 'code');
                    },
                    'empTier' => function ($query) {
                        $query->select('id', 'title');
                    },
                    'accessTier' => function ($query) {
                        $query->select('id', 'title', 'tier_key');
                    },
                ])
                ->select('id', 'access_role', 'tier_id')
                ->whereIn('tier_id', function ($query) {
                    $query->select('id')
                        ->from('tiers')
                        ->whereIn('tier_key', ['B-1', 'B-2']);
                })
                ->get();
            $authorised_by_list = $emp_list;
            $userSite = DB::table('sites')
                ->where('del', '0')
                ->where('active', '1')
                ->where('sso_id', auth()->user()->id)
                ->get(['id', 'title']);
            if (count($userSite) > 0) {
                $data['sites'] = $userSite;
                $data['is_sso'] = 1;
            } else {
                $data['sites'] = DB::table('sites')
                    ->where('del', '0')
                    ->where('active', '1')
                    ->get(['id', 'title']);
                $data['is_sso'] = 0;
            }
            // if ($validatedData['incident_report_id'] == 0) {
            //     // Fetch sites where `del = 0` and `active = 1`
            //     $data['sites'] = DB::table('sites')
            //         ->where('del', '0')
            //         ->where('active', '1')
            //         ->where('sso_id', auth()->user()->id)
            //         ->get(['id', 'title']);
            // } else {
            //     $incident_report = IncidentReport::with('sitesData')
            //     ->where('id', $validatedData['incident_report_id'])
            //     ->first();
            //     $data['sites'] = DB::table('sites')
            //         ->where(function ($query) use ($incident_report) {
            //             $query->where('active', '1')
            //                   ->orWhere(function ($subQuery) use ($incident_report) {
            //                       // Exceptional condition for the specific `site_id` from incident report
            //                       if ($incident_report && isset($incident_report->site_id)) {
            //                           $subQuery->where('id', $incident_report->site_id)
            //                                    ->where('del', '0'); 
            //                       }
            //                   });
            //         })
            //         ->get(['id', 'title']);
            // }
            $data['incident_report'] = $incident_report;
            $data['authorised_by_list'] = $authorised_by_list;
            return $this->success($data, 'Get Successfully');
        } catch (Exception $e) {
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'Step 1  edit:' .   $e->getMessage(),
                'report_id' =>  $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'exception error'
            ];
            storeReportsLogs($log);
            return $this->error($e->getMessage(), 500);
        }
    }

    public function storeStep2(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|integer|exists:incident_reports,id',
            'investigation_number' => 'nullable|string',
            'office_number' => 'nullable|string',
            'project_id' => 'nullable|integer',
            'project_number' => 'nullable|integer',
            'report_compiled_by' => 'nullable|integer',
            'position_id' => 'nullable|integer',
            'date' => 'nullable|date',
            'incident_date' => 'nullable|date',
            'incident_time' => 'nullable|date_format:H:i',
            'date_incident_reported' => 'nullable|date|after_or_equal:incident_date',
            'time_incident_reported' => 'nullable',
            'reported_by' => 'nullable|integer',
            'company_name_by' => 'nullable|string',
            'position_by' => 'nullable|integer',
            'contact_number_by' => 'nullable',
            'reported_to' => 'nullable|integer',
            'company_name_to' => 'nullable|string',
            'position_to' => 'nullable|integer',
            'contact_number_to' => 'nullable',
            'injury_classification_id' => 'nullable|array',
            'injury_classification_id.*' => 'nullable|integer',
            'details' => 'nullable|string'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 2 validation error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // Fetch the incident report
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            if (!$incidentReport) {
                return $this->message('Incident report not found', 404);
            }
            // Check user permissions
            $userTable = $this->getUserTable();
            if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            // Check if updating existing data or creating new data
            $existingClassifications = IncidentClassificationReport::where([
                'incident_report_id' => $validatedData['incident_report_id'],
                'type' => '0'
            ])->exists();
            $existingReportedTo = IncidentReportedTo::where('incident_report_id', $validatedData['incident_report_id'])->exists();
            $existingReportedBy = IncidentReportedBy::where('incident_report_id', $validatedData['incident_report_id'])->exists();
            // Update Injury Classification
            if (!empty($validatedData['injury_classification_id'])) {
                if (in_array(1, $validatedData['injury_classification_id']) && empty($validatedData['details'])) {
                    storeReportsLogs([
                        'employee_id' => auth()->user()->id,
                        'message' => 'Step 2 validation error: Details field is required when injury classification is Other',
                        'report_id' => $validatedData['incident_report_id'],
                        'report_type' => 'incident_report',
                        'error_type' => 'validation error'
                    ]);
                    return $this->message('The Details field is required when injury classification is Other', 422);
                }
                // Delete existing classifications for this report (this is necessary for updating selections)
                IncidentClassificationReport::where([
                    'incident_report_id' => $validatedData['incident_report_id'],
                    'type' => '0'
                ])->delete();
                // Insert new classifications
                $incidentClassifications = array_map(function ($c_id) use ($validatedData) {
                    return [
                        "incident_report_id" => $validatedData['incident_report_id'],
                        "injury_classification_id" => $c_id,
                        "details" => $c_id == 1 ? ($validatedData['details'] ?? '') : "", // if selected option is Other
                        "type" => "0",
                        "created_at" => now(),
                        "updated_at" => now()
                    ];
                }, $validatedData['injury_classification_id']);
                IncidentClassificationReport::insert($incidentClassifications);
            }
            // Update main Incident Report Data (this updates existing record, doesn't create new)
            $updateData = array_filter([
                'investigation_number' => $validatedData['investigation_number'] ?? null,
                'office_number' => $validatedData['office_number'] ?? null,
                'project_id' => $validatedData['project_id'] ?? null,
                'project_number' => $validatedData['project_number'] == 'undefined' ? 0 : ($validatedData['project_number'] ?? null),
                'report_compiled_by' => $validatedData['report_compiled_by'] ?? null,
                'position_id' => $validatedData['position_id'] ?? null,
                'date' => $validatedData['date'] ?? null,
                'incident_date' => $validatedData['incident_date'] ?? null,
                'incident_time' => $validatedData['incident_time'] ?? null,
                'date_incident_reported' => $validatedData['date_incident_reported'] ?? null,
                'time_incident_reported' => $validatedData['time_incident_reported'] ?? null
            ], function ($value) {
                return $value !== null && $value !== '';
            });
            if (!empty($updateData)) {
                $incidentReport->update($updateData);
            }
            // Handle Reported To Data
            $reportedToData = array_filter([
                'reported_to' => $validatedData['reported_to'] ?? null,
                'company_name' => $validatedData['company_name_to'] ?? null,
                'position' => $validatedData['position_to'] ?? null,
                'contact_number' => $validatedData['contact_number_to'] ?? null
            ], function ($value) {
                return $value !== null && $value !== '';
            });
            if (!empty($reportedToData)) {
                $reportedToData['incident_report_id'] = $validatedData['incident_report_id'];
                // Use updateOrCreate to avoid creating duplicates
                IncidentReportedTo::updateOrCreate(
                    ['incident_report_id' => $validatedData['incident_report_id']],
                    $reportedToData
                );
            }
            // Handle Reported By Data
            $reportedByData = array_filter([
                'reported_by' => $validatedData['reported_by'] ?? null,
                'company_name' => $validatedData['company_name_by'] ?? null,
                'position' => $validatedData['position_by'] ?? null,
                'contact_number' => $validatedData['contact_number_by'] ?? null
            ], function ($value) {
                return $value !== null && $value !== '';
            });
            if (!empty($reportedByData)) {
                $reportedByData['incident_report_id'] = $validatedData['incident_report_id'];
                // Use updateOrCreate to avoid creating duplicates
                IncidentReportedBy::updateOrCreate(
                    ['incident_report_id' => $validatedData['incident_report_id']],
                    $reportedByData
                );
            }
            // Determine appropriate success message
            $hasExistingData = $existingClassifications || $existingReportedTo || $existingReportedBy;
            $hasNewData = !empty($validatedData['injury_classification_id']) || !empty($reportedToData) || !empty($reportedByData);
            if ($hasExistingData && $hasNewData) {
                $msg = 'Step 2 Updated Successfully';
            } elseif ($hasNewData) {
                $msg = 'Step 2 Saved Successfully';
            } else {
                $msg = 'Step 2 Updated Successfully';
            }
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => $msg,
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report'
            ]);
            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], $msg);
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 2 error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'] ?? null,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred: ' . $e->getMessage());
        }
    }

    public function editStep2(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|integer|exists:incident_reports,id'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 2 Error occurred: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // Fetch Incident Report with related data
            $incident_report = IncidentReport::with(['incidentClassificationReports' => function ($query) {
                $query->where('type', '0');
            }])->find($validatedData['incident_report_id']);
            $userTable = $this->getUserTable();
            if ($userTable === 'customer' && ($incident_report->customer_id !== auth()->id() || $incident_report->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            if ($userTable === 'emp' && ($incident_report->customer_id !== auth()->user()->customer_id || $incident_report->workspace_id !== auth()->user()->workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            // Fetch Related Incident Injury Classifications
            // $incident_injury_classification_list = IncidentInjuryClassification::where('status', '1')
            //     ->where('del', '0')
            //     ->orderBy('id', 'DESC')
            //     ->get();
            // Fetch Active Projects
            // $project_list = Project::where('active', '1')
            //     ->where('is_deleted', '0')
            //     ->get();
            // Fetch Employee List for various roles
            // $emp_list = EmpCompanyDetails::where([
            //         ['compeleted', '1'],
            //         ['approved', '1'],
            //         ['status', '1'],
            //         ['del', '0']
            //     ])
            //     ->with([
            //         'empPersonalDetails:emp_id,first_name,middle_name,last_name',
            //         'accessRole:id,title,code',
            //         'empTier:id,title',
            //         'accessTier:id,title,tier_key'
            //     ])
            //     ->whereIn('tier_id', function ($query) {
            //         $query->select('id')->from('tiers')
            //             ->whereIn('tier_key', ['T-1', 'T-2']);
            //     })
            //     ->select('id', 'access_role', 'tier_id')
            //     ->get();
            // Fetch Employees for `compiled_list`
            // $compiled_list = EmpCompanyDetails::where([
            //         ['compeleted', '1'],
            //         ['approved', '1'],
            //         ['status', '1'],
            //         ['del', '0']
            //     ])
            //     ->with([
            //         'empPersonalDetails:emp_id,first_name,middle_name,last_name',
            //         'accessRole:id,title,code',
            //         'empTier:id,title',
            //         'accessTier:id,title,tier_key'
            //     ])
            //     ->whereIn('tier_id', function ($query) {
            //         $query->select('id')->from('tiers')
            //             ->whereIn('tier_key', ['T-1', 'T-2', 'T-3', 'T-4', 'T-5']);
            //     })
            //     ->select('id', 'access_role', 'tier_id')
            //     ->get();
            // Fetch Employees for `incident_reported_by_list`
            // $incident_reported_by_list = EmpCompanyDetails::where([
            //         ['compeleted', '1'],
            //         ['approved', '1'],
            //         ['status', '1'],
            //         ['del', '0']
            //     ])
            //     ->with([
            //         'empPersonalDetails:emp_id,first_name,middle_name,last_name',
            //         'accessRole:id,title,code',
            //         'empTier:id,title',
            //         'accessTier:id,title,tier_key'
            //     ])
            //     ->whereIn('tier_id', function ($query) {
            //         $query->select('id')->from('tiers')
            //             ->whereIn('tier_key', ['T-1', 'T-2', 'T-3', 'T-4', 'T-5', 'T-6']);
            //     })
            //     ->select('id', 'access_role', 'tier_id')
            //     ->get();

            // Fetch Reported By & Reported To Data
            $incident_reported_by = IncidentReportedBy::where('incident_report_id', $validatedData['incident_report_id'])->first();
            $incident_reported_to = IncidentReportedTo::where('incident_report_id', $validatedData['incident_report_id'])->first();
            // Assign additional data to incident report object
            $incident_report->incident_reported_by = $incident_reported_by;
            $incident_report->incident_reported_to = $incident_reported_to;
            // Prepare Response Data
            $data = [
                'incident_report' => $incident_report,
                // 'incident_injury_classification_list' => $incident_injury_classification_list,
                // 'report_compiled_list' => $compiled_list,
                // 'incident_reported_by_list' => $incident_reported_by_list,
                // 'incident_reported_to_list' => $emp_list,
                // 'project_list' => $project_list
            ];
            return $this->success($data, 'Data retrieved successfully.');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 2 Edit Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'exception error'
            ]);
            return $this->error($e->getMessage());
        }
    }

    public function storeStep3(Request $request)
    {
        $dateValidation = ['required_if:is_notified_to,0', 'nullable'];
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
            'is_notified' => 'integer',
            'notifiable_classification_id' => 'required_if:is_notified,0',
            'is_notified_to' => 'required',
            'is_victim' => 'nullable',
            'notified_to' => ['required_if:is_notified_to,1', 'integer'],
            'ohs_regulator' => 'required_if:is_notified_to,0',
            'reference_number' => ['nullable', 'integer', 'digits_between:1,10'], // Ensure it's a 10-digit integer
            'date' => $dateValidation,
            'time' => 'required_if:is_notified_to,0',
            'contact_name' => 'required_if:is_notified_to,0',
            'involved_persons' => 'required_if:is_victim,0'
        ], [
            'incident_report_id.required' => 'Incident Report ID is required.',
            'is_notified.required_unless' => 'Please specify if the incident was notified.',
            'is_notified_to.required' => 'Please specify if the incident was notified to someone.',
            'notified_to.required_if' => 'The field "Notified To" is required when "Is Notified To" is checked.',
            'notified_to.integer' => 'The "Notified To" field must be an integer.',
            'ohs_regulator.required_if' => 'OHS Regulator is required when applicable indication is not checked.',
            'reference_number.integer' => 'Reference Number must be an integer.',
            'reference_number.digits_between' => 'The Maximum Reference Number is 10 digits.', // Custom error for 10 digits validation
            'date.required_if' => 'Date is required when applicable indication is not checked.',
            'time.required_if' => 'Time is required when applicable indication is not checked.',
            'notifiable_classification_id.required_if' => 'The Classification of Incident must be selected when applicable indication is not checked.',
            'contact_name.required_if' => 'Contact Name is required when applicable indication is not checked.',
            'involved_persons.required_if' => 'Involved persons are required.'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 3 Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            if (!$incidentReport) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Step 3 Incident Report Record Not Found',
                    'report_id' => $request->incident_report_id,
                    'report_type' => 'incident_report',
                    'error_type' => 'Not found error'
                ]);
                return $this->message('Incident Report Record Not Found', 404);
            }
            $userTable = $this->getUserTable();
            if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            // Check if this is a new entry for step progression
            $isNewEntry = !IncidentReportNotifiableClassification::where('incident_report_id', $validatedData['incident_report_id'])->exists();
            // Update Incident Report
            $incidentReport->update([
                'is_notified' => $validatedData['is_notified'],
                'is_notified_to' => $validatedData['is_notified_to'],
                'is_victim' => $validatedData['is_victim'] ?? null,
                'involved_persons' => $validatedData['involved_persons'] ?? null
            ]);
            // Update or Insert Notifiable Classification
            if (isset($validatedData['notifiable_classification_id'])) {
                IncidentReportNotifiableClassification::updateOrCreate(
                    ['incident_report_id' => $validatedData['incident_report_id']],
                    ['notifiable_classification_id' => $validatedData['notifiable_classification_id']]
                );
            }
            // Update or Insert Incident Notified To
            IncidentNotifiedTo::updateOrCreate(
                ['incident_report_id' => $validatedData['incident_report_id']],
                [
                    'notified_to' => $validatedData['notified_to'] ?? null,
                    'ohs_regulator' => $validatedData['ohs_regulator'] ?? null,
                    'reference_number' => $validatedData['reference_number'] ?? 0,
                    'date' => $validatedData['date'] ?? null,
                    'time' => $validatedData['time'] ?? null,
                    'contact_name' => $validatedData['contact_name'] ?? null
                ]
            );
            // Update step number if this is a new entry
            if ($isNewEntry) {
                $incidentReport->update(['step_no' => 4]);
                $msg = 'Saved Successfully';
            } else {
                $msg = 'Updated Successfully';
            }
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 3 ' . $msg,
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report'
            ]);
            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], $msg);
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 3 Store Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage());
        }
    }

    public function editStep3(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id'
        ]);
        if ($validator->fails()) {
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // Fetch Incident Report with related data
            $incidentReport = IncidentReport::with(['notifiableClassifications', 'notifiedTos'])
                ->where('id', $validatedData['incident_report_id'])
                ->firstOrFail();
            if (!$incidentReport) {
                return $this->message('Incident Report Record Not Found', 404);
            }
            $userTable = $this->getUserTable();
            $customerId = null;
            if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
                $customerId = auth()->user()->id;
                return $this->message('You do not have access to this report.', 403);
            }
            if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
                $customerId = auth()->user()->customer_id;
                return $this->message('You do not have access to this report.', 403);
            }
            // Fetch Notifiable Classification List
            $incidentNotifiableClassificationList = IncidentNotifiableClassification::where('status', '1')
                // ->where('customer_id',$customerId)   feture check if needed
                ->where('del', '0')
                ->get();
            // Construct response data
            $incidentReport->incident_notifiable_classification_list = $incidentNotifiableClassificationList;

            return $this->success($incidentReport, 'Data Retrieved Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 3 edit Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error($e->getMessage());
        }
    }

    public function storeStep4(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
            'id' => 'nullable|exists:incident_involved_person_details,id',
            'employee_id' => 'nullable|exists:emp_personal_details,emp_id',
            'surname' => 'nullable|string|max:255',
            'contact_number' => 'nullable|string',
            'gender' => 'required|integer',
            'dob' => [
                'nullable',
                'date',
                function ($attribute, $value, $fail) {
                    if ($value && Carbon::parse($value)->isAfter(Carbon::now()->subYears(10))) {
                        $fail("The {$attribute} must be at least 10 years old.");
                    }
                },
            ],
            'occupation' => 'nullable|string|max:255',
            'language' => 'nullable|string|max:255',
            'supervisor' => 'nullable|string',
            'experience_years' => 'nullable|integer|min:0',
            'experience_months' => 'nullable|integer|min:0|max:11',
            'is_employer_worker' => 'nullable|string',
            'is_employer_worker_details' => 'nullable|string',
            'employment_type' => 'required|integer',
            'employee_type' => 'nullable|string',
            'training_id' => 'nullable|exists:trainings,id',
            'nature_of_injury' => 'nullable',
            'bodily_location' => 'nullable',
            'nature_of_disease' => 'nullable',
            'breakdown_of_injury' => 'nullable',
            'mechanism_of_injury' => 'nullable',
            'is_type_emp' => 'nullable', // Add validation for these fields
            'is_inj_detail' => 'nullable', // Add validation for these fields
        ]);

        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }

        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);

            if (!$incidentReport) {
                return $this->message('Incident Report Record Not Found', 404);
            }

            $userTable = $this->getUserTable();
            if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }

            // Check if the employee is already involved
            $existingPerson = IncidentInvolvedPersonDetail::where([
                'incident_report_id' => $validatedData['incident_report_id'],
                'employee_id' => $validatedData['employee_id']
            ])->first();

            if (!$validatedData['id'] && $existingPerson) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Step 4 This person is already involved',
                    'report_id' => $validatedData['incident_report_id'],
                    'report_type' => 'incident_report'
                ]);
                return $this->message('This person is already involved', 400);
            }

            // Check if this is a new entry
            $isNewEntry = !$validatedData['id'];

            // Store or Update Involved Person Details
            $involvedPerson = IncidentInvolvedPersonDetail::updateOrCreate(
                ['id' => $validatedData['id'] ?? null],
                [
                    'incident_report_id' => $validatedData['incident_report_id'],
                    'employee_id' => $validatedData['employee_id'] ?? 0,
                    'surname' => $validatedData['surname'],
                    'contact_number' => $validatedData['contact_number'],
                    'gender' => $validatedData['gender'],
                    'dob' => $validatedData['dob'],
                    // Calculate age using Carbon if dob is provided
                    'age' => isset($validatedData['dob']) ? Carbon::parse($validatedData['dob'])->age : 0,
                    'occupation' => $validatedData['occupation'],
                    'language' => $validatedData['language'],
                    'experience_years' => $validatedData['experience_years'] ?? 0,
                    'experience_months' => $validatedData['experience_months'] ?? 0,
                    'employment_type' => $validatedData['employment_type'],
                    'employee_type' => $validatedData['employee_type'],
                    'is_type_emp' => $validatedData['is_type_emp'] ?? null,  // Added these fields to store
                    'is_inj_detail' => $validatedData['is_inj_detail'] // Added these fields to store
                ]
            );
            // Store Training Details
            if ($validatedData['training_id']) {
                IncidentInvolvedPersonTraining::updateOrCreate(
                    [
                        'incident_involved_person_id' => $involvedPerson->employee_id,
                        'incident_report_id' => $validatedData['incident_report_id']
                    ],
                    ['training_id' => $validatedData['training_id']]
                );
            }
            // Store Injury Types
            $injuryOptions = ['nature_of_injury', 'bodily_location', 'nature_of_disease', 'breakdown_of_injury', 'mechanism_of_injury'];
            foreach ($injuryOptions as $option) {
                if (!empty($validatedData[$option])) {
                    IncidentEmployeeInjuryType::updateOrCreate(
                        [
                            'incident_report_id' => $validatedData['incident_report_id'],
                            'employer_id' => $validatedData['employee_id'] ?? 0,
                            'option' => $option
                        ],
                        ['value' => $validatedData[$option]]
                    );
                }
            }
            // Store Employer Details
            IncidentEmployerDetail::updateOrCreate(
                [
                    'incident_report_id' => $validatedData['incident_report_id'],
                    'employer_id' => $validatedData['employee_id'] ?? 0
                ],
                [
                    'supervisor' => $validatedData['supervisor'],
                    'is_employer_worker' => $validatedData['is_employer_worker'],
                    'is_employer_worker_details' => $validatedData['is_employer_worker_details']
                ]
            );
            // Update step number if it's a new entry
            if ($isNewEntry) {
                $incidentReport->update(['step_no' => 5]);
                $msg = 'Saved Successfully';
            } else {
                $msg = 'Updated Successfully';
            }
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 ' . $msg,
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report'
            ]);

            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], $msg);
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Store Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage());
        }
    }


    public function editStep4(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id'  => 'required|exists:incident_reports,id',
            'employee_id' => 'required|exists:emp_personal_details,emp_id'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // Fetch Incident Report and apply access control check
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            if (!$incidentReport) {
                return $this->message('Incident Report Record Not Found', 404);
            }
            // Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->message('You do not have access to this report.', 403);
            }
            // Fetch Incident Report with all related data using ORM
            $incidentReport->load([
                'involvedPersons' => function ($query) use ($validatedData) {
                    $query->where('employee_id', $validatedData['employee_id']);
                },
                'involvedTrainings' => function ($query) use ($validatedData) {
                    $query->where('incident_involved_person_id', $validatedData['employee_id']);
                },
                'injuryTypes' => function ($query) use ($validatedData) {
                    $query->where('employer_id', $validatedData['employee_id']);
                },
                'employerDetails' => function ($query) use ($validatedData) {
                    $query->where('employer_id', $validatedData['employee_id']);
                }
            ]);
            return $this->success($incidentReport, 'Get Successfully');
        } catch (\Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Retrieval Error: ' . $shortMessage,
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error($shortMessage);
        }
    }

    public function listingStep4(Request $request, $id)
    {
        $validator = Validator::make($request->all(), [
            'listing' => 'nullable|boolean',
            'fields_list' => 'nullable|boolean'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($id);
            if (!$incidentReport) {
                return $this->message('Incident Report Record Not Found', 404);
            }
            // Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->message('You do not have access to this report.', 403);
            }
            $data = [];
            // **Fetching Involved Persons Listing**
            $incidentInvolvedPersons = IncidentInvolvedPersonDetail::where('incident_report_id', $id)
                ->with([
                    'empCompanyDetails:id,tier_id',
                    'empCompanyDetails.empTier:id,title',
                    'employee:emp_id,first_name,middle_name,last_name' // Changed 'empPersonalDetails' to 'employee'
                ])
                ->get(['id', 'incident_report_id', 'employee_id']);
            // }
            // need to improve this query according to customer id 
            // if ($validatedData['fields_list']) {
            //     $employeesList = EmpCompanyDetails::where([
            //         ['compeleted', '1'],
            //         ['approved', '1'],
            //         ['status', '1'],
            //         ['del', '0']
            //     ])
            //         ->with([
            //             'empPersonalDetails:emp_id,first_name,middle_name,last_name',
            //             'empTier:id,title'
            //         ])
            //         ->select('id', 'tier_id')
            //         ->get();

            //     $supervisorList = EmpCompanyDetails::where([
            //         ['compeleted', '1'],
            //         ['approved', '1'],
            //         ['status', '1'],
            //         ['del', '0'],
            //         ['access_role', 'SPV']
            //     ])
            //         ->with([
            //             'empPersonalDetails:emp_id,first_name,middle_name,last_name',
            //             'accessRole:id,title,code',
            //             'empTier:id,title'
            //         ])
            //         ->select('id', 'access_role', 'tier_id')
            //         ->get();
            //     $data['employees_list'] = $employeesList;
            //     $data['supervisor_list'] = $supervisorList;
            //     $data['type_of_employment_list'] = EmpType::where('del', '0')->get();
            //     $data['training_list'] = Training::where([['status', '1'], ['del', '0']])->orderByDesc('id')->get();
            //     $data['languages_list'] = [
            //         "English",
            //         "Spanish",
            //         "French",
            //         "German",
            //         "Chinese",
            //         "Hindi",
            //         "Arabic",
            //         "Portuguese",
            //         "Bengali",
            //         "Russian",
            //         "Japanese",
            //         "Punjabi",
            //         "Korean",
            //         "Turkish"
            //     ];
            //     $data['months_list'] = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
            //     $data['type_of_employee_list'] = ['Trainee', 'Apprentice', 'Carpenter', 'Off-sider', 'Labourer', 'Other'];
            //     $data['employer_of_worker_list'] = ['Subcontractor', 'Supplier', 'Other', 'N/A'];
            //     $data['mechanism_of_injury_list'] = ['Fall', 'Trip', 'Hit by object', 'Overexertion'];
            //     $data['breakdown_of_injury_list'] = ['Fracture', 'Sprain', 'Burn', 'Concussion'];
            //     $data['nature_of_disease_list'] = ['Respiratory', 'Cardiovascular', 'Musculoskeletal'];
            //     $data['bodily_location_list'] = ['Head', 'Arm', 'Leg', 'Torso'];
            //     $data['nature_of_injury_list'] = ['Bruise', 'Cut', 'Dislocation', 'Laceration'];
            // }
            return $this->success($incidentInvolvedPersons, 'Get Successfully');
        } catch (\Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Retrieval Error: ' . $shortMessage,
                'report_id' => $validatedData['id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error($shortMessage);
        }
    }


    public function deleteStep4(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
            'employee_id' => 'required|exists:incident_involved_person_details,employee_id'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Delete Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            if (!$incidentReport) {
                return $this->message('Incident Report Not Found', 404);
            }
            // 🔹 Check user permissions to delete
            $userTable = $this->getUserTable();
            if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->message('You do not have access to delete this record.', 403);
            }
            if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
                return $this->message('You do not have access to delete this record.', 403);
            }
            // 🔹 Find & Delete the related records
            $incidentPerson = IncidentInvolvedPersonDetail::where([
                'incident_report_id' => $validatedData['incident_report_id'],
                'employee_id' => $validatedData['employee_id']
            ])->first();
            if (!$incidentPerson) {
                return $this->message('Person not found in the report', 404);
            }
            // ❌ Delete related records (Trainings, Injury Types)
            IncidentInvolvedPersonTraining::where([
                'incident_involved_person_id' => $validatedData['employee_id'],
                'incident_report_id' => $validatedData['incident_report_id']
            ])->delete();
            IncidentEmployeeInjuryType::where([
                'incident_report_id' => $validatedData['incident_report_id'],
                'employer_id' => $validatedData['employee_id']
            ])->delete();
            // ❌ Delete Person Details
            $incidentPerson->delete();
            // 🔹 Log deletion
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Deleted Successfully',
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report'
            ]);
            return $this->message('Deleted Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 4 Delete Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage());
        }
    }

    public function storeStep5(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
            'shift_type' => 'nullable|string',
            'shift_time' => 'nullable|string',
            'is_questions' => 'nullable', // Added is_questions validation
            'answer' => 'nullable',
            'answer.*.question_id' => 'nullable|exists:incident_report_questions,id',
            'answer.*.text' => 'nullable|string',
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 5 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->error($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // 🔹 Fetch Incident Report with security check
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Update is_questions field in incident_reports table
            $incidentReport->update(['is_questions' => $validatedData['is_questions']]);
            // 🔹 Check if this is a new entry
            $isNewEntry = !IncidentReportMeta::where('incident_report_id', $validatedData['incident_report_id'])->exists();
            // 🔹 Save or Update Report Meta Data
            IncidentReportMeta::updateOrCreate(
                ['incident_report_id' => $validatedData['incident_report_id']], // Condition to find the existing record
                [
                    'shift_type' => $validatedData['shift_type'],  // Data to update/create
                    'shift_time' => $validatedData['shift_time']
                ]
            );
            // 🔹 Update Step Number if it's a new entry
            if ($isNewEntry) {
                $incidentReport->update(['step_no' => 6]);
                $msg = 'Saved Successfully';
            } else {
                $msg = 'Updated Successfully';
            }
            // 🔹 Store Report Question Answers
            if (!empty($validatedData['answer'])) {
                IncidentReportQuestionAnswer::where('incident_report_id', $validatedData['incident_report_id'])->delete();
                $reportAnswers = collect($validatedData['answer'])->map(function ($item) use ($validatedData) {
                    return [
                        'incident_report_id' => $validatedData['incident_report_id'],
                        'question_id' => $item['question_id'],
                        'answer' => $item['text'],
                        'created_at' => now(),
                        'updated_at' => now()
                    ];
                })->toArray();
                IncidentReportQuestionAnswer::insert($reportAnswers);
            }
            // 🔹 Log the operation
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 5 ' . $msg,
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report'
            ]);
            return $this->success([
                'incident_report_id' => $validatedData['incident_report_id']
            ], 'Step 5 ' . $msg);
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 5 Store Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }

    public function editStep5(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 5 Edit Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Fetch related data using Eloquent ORM
            $incidentReport->load([
                'incidentReportMetas',  // Relationship for incident_report_metas
                'questionAnswers', // Relationship for incident_report_question_answers
            ]);
            // 🔹 Fetch additional required data
            $reportQuestions = IncidentReportQuestion::where('del', '0')->where('status', '1')->get();
            // $employerList = EmpCompanyDetails::where('compeleted', '1')
            //     ->where('approved', '1')
            //     ->where('status', '1')
            //     ->where('del', '0')
            //     ->with([
            //         'empPersonalDetails:id,first_name,middle_name,last_name',
            //         'accessRole:id,title,code',
            //         'empTier:id,title',
            //     ])
            //     ->select('id', 'access_role', 'tier_id')
            //     ->get();
            // 🔹 Shift types and worker categories
            $shiftTypeAndTimeList = [
                'Day' => ['06:00 AM - 11:59 PM', '07:00 AM - 11:59 PM'],
                'Evening' => ['12:00 AM - 15:59 PM'],
                'Night' => ['16:00 AM - 05:59 PM']
            ];
            $employerOfWorkerList = ['N/A', 'Other', 'Supplier', 'Subcontractor'];
            // 🔹 Construct response data
            $data = [
                'incident_report' => array_merge($incidentReport->toArray(), ['report_questions_list' => $reportQuestions]),
                'shift_type_and_time_list' => $shiftTypeAndTimeList,
                'employer_of_worker_list' => $employerOfWorkerList,
                // 'employer_list' => $employerList,

            ];
            return $this->success($data, 'Step 5 Data Retrieved Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 5 Edit Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }


    public function storeStep6(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
            'is_plant_involved' => 'nullable|boolean',
            'plant_name' => 'nullable|integer',
            'equipment_type' => 'nullable|string',
            'registration_number' => 'nullable|string',
            'damage' => 'nullable|string',
            'cost' => 'nullable|string',
            'is_correct_action_required' => 'nullable|boolean'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 6 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // 🔹 Fetch Incident Report with security check
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Check if this is a new entry for meta table
            $isNewEntry = !IncidentReportMeta::where('incident_report_id', $validatedData['incident_report_id'])->exists();
            // 🔹 Update Incident Report fields
            $incidentReport->update([
                'is_plant_involved' => $validatedData['is_plant_involved'] ?? null,
                'plant_name' => $validatedData['plant_name'] ?? 0,
                'is_correct_action_required' => $validatedData['is_correct_action_required'] ?? null
            ]);
            // 🔹 Update or Create Incident Report Meta
            $incidentReportMeta = IncidentReportMeta::updateOrCreate(
                ['incident_report_id' => $validatedData['incident_report_id']],
                [
                    'equipment_type' => $validatedData['equipment_type'] ?? null,
                    'registration_number' => $validatedData['registration_number'] ?? 0,
                    'damage' => $validatedData['damage'] ?? 0,
                    'cost' => $validatedData['cost'] ?? 0
                ]
            );
            // 🔹 Update step number and set message
            if ($isNewEntry) {
                $incidentReport->update(['step_no' => 7]);
                $msg = 'Saved Successfully';
            } else {
                $msg = 'Updated Successfully';
            }
            // 🔹 Log the action
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 6 ' . $msg,
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report'
            ]);
            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], $msg);
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 6 Store Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }


    public function editStep6(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 6 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::with('incidentReportMetas')->find($validatedData['incident_report_id']);
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Plant Equipment List
            $plantList = [
                '0' => 'Plant / Equipment',
                '1' => 'Contractor Plant / Equipment',
                '2' => 'Third Party / Client'
            ];
            $data = [
                'incident_report' => $incidentReport,
                'plant_list' => $plantList
            ];
            return $this->success($data, 'Get Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 6 Retrieval Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }

    public function storeStep7(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "incident_report_id" => "required|exists:incident_reports,id",
            "incident_response"  => "nullable|string",
            "is_injury_management" => "nullable|integer",
            "date" => "nullable|date",
            "time" => "nullable|date_format:H:i",
            "representative_name" => "nullable|string",
            "injured_names" => "nullable|string",
            "is_first_aid" => "nullable|integer",
            "is_referred" => "nullable|integer",
            "is_doctor" => "nullable|integer",
            "is_clinic" => "nullable|integer",
            "is_admit" => "nullable|integer",
            "return_to_work" => "nullable|integer",
            "is_hospital_details" => "nullable|integer",
            "is_doctor_details" => "nullable|integer",
            "doctor_name" => "nullable|string",
            "doctor_number" => "nullable|string",
            "doctor_address" => "nullable|string",
            "hospital_name" => "nullable|string",
            "hospital_number" => "nullable|string",
            "hospital_address" => "nullable|string",
            "is_recurrence_injury" => "nullable|integer",
            "previous_injury_date" => "nullable|date",
            "previous_report_number" => "nullable|integer"
        ]);

        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 7 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }

        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            if (!$incidentReport) {
                return $this->message('report not found', 404);
            }

            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }

            // 🔹 Update Incident Report (incident_response belongs here)
            $incidentReport->update([
                'is_injury_management' => $validatedData['is_injury_management'] ?? 0,
                'incident_response' => $validatedData['incident_response'] ?? '',
            ]);

            // 🔹 Update or Create Injury Management Details
            // Exclude fields that belong to incident_reports table, not incident_injury_managements
            $injuryManagementData = array_merge(
                $request->except(['is_injury_management', 'incident_report_id', 'incident_response']), // ← Fixed: exclude incident_response
                ['incident_report_id' => $validatedData['incident_report_id']]
            );

            $injuryManagement = IncidentInjuryManagement::updateOrCreate(
                ['incident_report_id' => $validatedData['incident_report_id']],
                $injuryManagementData
            );

            // 🔹 Update Step Number if First Time
            if (!$injuryManagement->wasRecentlyCreated) {
                $msg = 'Updated Successfully';
            } else {
                $incidentReport->update(['step_no' => 8]);
                $msg = 'Saved Successfully';
            }

            // 🔹 Log Action
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 7 ' . $msg,
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report'
            ]);

            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], $msg);
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 7 Store Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'] ?? $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }


    public function editStep7(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 7 Edit Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->error($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // 🔹 Fetch Incident Report with Security Check
            $incidentReport = IncidentReport::with('injuryManagements')
                ->where('id', $validatedData['incident_report_id'])
                ->firstOrFail();
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            return $this->success($incidentReport, 'Get Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 7 Edit Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }

    public function storeStep8(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "incident_report_id" => 'required|exists:incident_reports,id',
            "is_final_injury_classification" => 'nullable|boolean',
            "injury_classification_id" => 'nullable|array',
            'details' => 'nullable|string',
            "is_final_incident_classification" => 'nullable|boolean',
            "final_incident_name" => 'nullable|integer',
            "final_incident_details" => 'nullable|string',
            "lti_or_rwi" => 'nullable|integer',
            "is_rehabilitation" => 'nullable|integer',
            "return_to_duty_date" => 'nullable|date',
            "rtw_date" => 'nullable|date',
            "total_lost_days" => 'nullable|integer',
            "is_worker_notified" => 'nullable|integer',
            "notified_by_whom" => 'required|integer',
            "notified_by_whom_date" => 'nullable|date',
            "notified_by_whom_time" => 'nullable|string',
            "notified_by_whom_details" => 'nullable|string',
            "sign_off" => 'nullable|array',
            "sign_off.*.role_code" => 'required_with:sign_off|string',
            "sign_off.*.emp_id" => 'nullable|integer',
            "sign_off.*.date" => 'nullable|string',
            "sign_off.*.time" => 'nullable|string'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 8 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Update Incident Report
            $incidentReport->update([
                "is_final_incident_classification" => $validatedData['is_final_incident_classification'],
                "is_final_injury_classification" => $validatedData['is_final_injury_classification'] ?? 0,
                "lti_or_rwi" => $validatedData['lti_or_rwi'],
            ]);
            // 🔹 Update or Create Final Classification
            $incidentFinalClassification = IncidentFinalClassification::updateOrCreate(
                ['incident_report_id' => $validatedData['incident_report_id']],
                [
                    "final_incident_name" => $validatedData['final_incident_name'],
                    "final_incident_details" => $validatedData['final_incident_details'],
                    "is_rehabilitation" => $validatedData['is_rehabilitation'],
                    "return_to_duty_date" => $validatedData['return_to_duty_date'],
                    "rtw_date" => $validatedData['rtw_date'],
                    "total_lost_days" => $validatedData['total_lost_days'],
                    "is_worker_notified" => $validatedData['is_worker_notified'],
                    "notified_by_whom" => $validatedData['notified_by_whom'] ?? null,
                    "date" => $validatedData['notified_by_whom_date'] ?? null,
                    "time" => $validatedData['notified_by_whom_time'] ?? null,
                    "details" => $validatedData['notified_by_whom_details'] ?? null
                ]
            );

            // 🔹 Update Injury Classification
            if (isset($validatedData['injury_classification_id'])) {
                IncidentClassificationReport::where('incident_report_id', $validatedData['incident_report_id'])
                    ->where("type", 1)
                    ->delete();
                foreach ($validatedData['injury_classification_id'] as $c_id) {
                    IncidentClassificationReport::create([
                        "incident_report_id" => $validatedData['incident_report_id'],
                        "injury_classification_id" => $c_id,
                        "details" => $c_id == 1 ? $validatedData['details'] : "",
                        "type" => "1"
                    ]);
                }
            }

            // 🔹 Sign-Off Handling (Fixed)
            if (isset($validatedData['sign_off'])) {
                foreach ($validatedData['sign_off'] as $incident_signoff) {
                    // Check if required fields are present before processing
                    if (empty($incident_signoff['emp_id']) || empty($validatedData['incident_report_id'])) {
                        // Skip this record if emp_id or incident_report_id is missing
                        continue;
                    }

                    $incident_signoff['incident_report_id'] = $validatedData['incident_report_id'];
                    $incident_signoff['emp_id'] = $incident_signoff['emp_id'] ?? 0;
                    $incident_signoff['role_code']  = EmpCompanyDetails::where('id', $incident_signoff['emp_id'])->first()->access_role ?? null;
                    
                    // Initialize variables
                    $signOffDate = null;
                    $signOffTime = null;

                    // Parse date if provided and not empty
                    if (!empty($incident_signoff['date'])) {
                        try {
                            // First try Y-m-d format (YYYY-MM-DD)
                            $signOffDate = \Carbon\Carbon::createFromFormat('Y-m-d', $incident_signoff['date'])->format('Y-m-d');
                        } catch (\Exception $e) {
                            try {
                                // Try d-m-Y format (DD-MM-YYYY)
                                $signOffDate = \Carbon\Carbon::createFromFormat('d-m-Y', $incident_signoff['date'])->format('Y-m-d');
                            } catch (\Exception $e2) {
                                try {
                                    // Try m-d-Y format (MM-DD-YYYY)
                                    $signOffDate = \Carbon\Carbon::createFromFormat('m-d-Y', $incident_signoff['date'])->format('Y-m-d');
                                } catch (\Exception $e3) {
                                    try {
                                        // Try Carbon's parse method as fallback
                                        $signOffDate = \Carbon\Carbon::parse($incident_signoff['date'])->format('Y-m-d');
                                    } catch (\Exception $e4) {
                                        // Log the error and skip this date
                                        Log::error('Invalid date format in sign_off: ' . $incident_signoff['date']);
                                        $signOffDate = null;
                                    }
                                }
                            }
                        }
                    }

                    // Parse time if provided and not empty
                    if (!empty($incident_signoff['time'])) {
                        try {
                            // First try H:i format (24-hour format)
                            $signOffTime = \Carbon\Carbon::createFromFormat('H:i', $incident_signoff['time'])->format('H:i');
                        } catch (\Exception $e) {
                            try {
                                // Try h:i A format (12-hour format with AM/PM)
                                $signOffTime = \Carbon\Carbon::createFromFormat('h:i A', $incident_signoff['time'])->format('H:i');
                            } catch (\Exception $e2) {
                                try {
                                    // Try h:i a format (12-hour format with am/pm)
                                    $signOffTime = \Carbon\Carbon::createFromFormat('h:i a', $incident_signoff['time'])->format('H:i');
                                } catch (\Exception $e3) {
                                    try {
                                        // Try Carbon's parse method as fallback
                                        $signOffTime = \Carbon\Carbon::parse($incident_signoff['time'])->format('H:i');
                                    } catch (\Exception $e4) {
                                        // Log the error and skip this time
                                        Log::error('Invalid time format in sign_off: ' . $incident_signoff['time']);
                                        $signOffTime = null;
                                    }
                                }
                            }
                        }
                    }

                    IncidentSignoff::updateOrCreate(
                        [
                            'incident_report_id' => $validatedData['incident_report_id'],
                            'role_code' => $incident_signoff['role_code'],
                            'emp_id' => $incident_signoff['emp_id'],
                        ],
                        [
                            'date' => $signOffDate,  // Store the parsed date or null
                            'time' => $signOffTime,  // Store the parsed time or null
                        ]
                    );
                }
            }

            // 🔹 Update Step No if needed
            if (!$incidentFinalClassification->wasRecentlyCreated) {
                $incidentReport->update(['step_no' => 9]);
            }

            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 8 Updated Successfully',
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report'
            ]);

            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], 'Updated Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 8 Store Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'] ?? $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }

    public function editStep8(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 8 Edit Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->error($validator->errors()->first(), 422);
        }

        try {
            $validatedData = $validator->validated();
            // 🔹 Fetch Incident Report with Security Check
            $incidentReport = IncidentReport::with([
                'incidentClassificationReports' => function ($query) {
                    $query->where('type', 1);
                },
                'finalClassifications',
                'signoffs'
            ])->find($validatedData['incident_report_id']);

            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }

            // 🔹 Fetch Employee Details
            $empList = EmpCompanyDetails::where('compeleted', '1')
                ->where('approved', '1')
                ->where('status', '1')
                ->where('del', '0')
                ->with([
                    'empPersonalDetails:emp_id,first_name,middle_name,last_name',
                    'accessRole:id,title,code',
                    'empTier:id,title',
                    'accessTier:id,title,tier_key'
                ])
                ->select('id', 'access_role', 'tier_id')
                ->get();



            // 🔹 Fetch Additional Data
            $byWhom = EmpCompanyDetails::where('compeleted', '1')
                ->where('approved', '1')
                ->where('status', '1')
                ->where('del', '0')
                ->with([
                    'empPersonalDetails:emp_id,first_name,middle_name,last_name',
                    'accessRole:id,title,code',
                    'empTier:id,title',
                    'accessTier:id,title,tier_key'
                ])
                ->select('id', 'access_role', 'tier_id')
                ->whereHas('empTier', function ($query) {
                    $query->whereIn('tier_key', ['B-1', 'B-2']);
                })
                ->get();
            $incidentReport->setAttribute('by_whom', $byWhom);
            return $this->success($incidentReport, 'Get Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 8 Edit Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }


    public function storeStep9(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "incident_report_id" => 'required|exists:incident_reports,id',
            "incident_risk_category_id" => 'nullable',
            "details" => 'nullable|string',
            "name" => 'nullable|array',
            "time" => 'nullable|array',
            "date" => 'nullable|array',
            "statement_number" => 'nullable|array',
            "title" => 'nullable|array',
            "number" => 'nullable|array'
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 9 Validation Error: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error'
            ]);
            return $this->error($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Update or Create Risk Category Details
            IncidentRiskCategoryDetail::updateOrCreate(
                ['incident_report_id' => $validatedData['incident_report_id']],
                [
                    "incident_risk_category_id" => $validatedData['incident_risk_category_id'] ?? null,
                    "details" => $validatedData['details'] ?? null
                ]
            );
            // 🔹 Process Witness Data
            if (!empty($validatedData['name'])) {
                IncidentWitnes::where('incident_report_id', $validatedData['incident_report_id'])->delete();
                foreach ($validatedData['name'] as $index => $witnessName) {
                    IncidentWitnes::create([
                        "incident_report_id" => $validatedData['incident_report_id'],
                        "name" => $witnessName,
                        "date" => $validatedData['date'][$index] ?? null,
                        "time" => $validatedData['time'][$index] ?? null,
                        "statement_number" => $validatedData['statement_number'][$index] ?? null
                    ]);
                }
            }
            // 🔹 Process Document Data
            if (!empty($validatedData['title'])) {
                IncidentDocument::where('incident_report_id', $validatedData['incident_report_id'])->delete();
                foreach ($validatedData['title'] as $index => $docTitle) {
                    IncidentDocument::create([
                        "incident_report_id" => $validatedData['incident_report_id'],
                        "title" => $docTitle,
                        "number" => $validatedData['number'][$index] ?? null
                    ]);
                }
            }
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 9 Successfully Processed',
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report'
            ]);
            return $this->success(['incident_report_id' => $validatedData['incident_report_id']], 'Saved Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 9 Store Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }

    public function editStep9(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id'
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first(), 422);
        }
        try {
            $validatedData = $validator->validated();
            // 🔹 Fetch Incident Report with Security Check
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            // 🔹 Access Control Check
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Load Related Data
            $incidentReport->load([
                'incidentRiskCategoryDetails',
                'incidentWitnesses',
                'incidentDocuments'
            ]);
            return $this->success(['incident_report' => $incidentReport], 'Get Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 9 Retrieval Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'],
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Error: ' . $e->getMessage(), 500);
        }
    }


    public function storeStep10(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
        ]);

        if ($validator->fails()) {
            return $this->message($validator->errors()->first(), 422);
        }
        $isUpdate = $request->incident_report_id;
        $message = $isUpdate ? 'Updated Successfully' : 'Saved Successfully';
        try {
            $incidentReport = IncidentReport::find($request->incident_report_id);
            if (!$incidentReport) {
                return $this->message('Record not found.', 404);
            }
            $userTable = $this->getUserTable();
            if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }
            if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
                return $this->message('You do not have access to this report.', 403);
            }

            $incidentReport->process = 1;
            $incidentReport->step_no = 10;
            $incidentReport->save();
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'WHS  Step 5 :' . $message,
                'report_id' =>   $request->incident_report_id,
                'report_type' => 'incident_report'
            ];
            storeReportsLogs($log);
            return $this->message($message);
        } catch (\Exception $e) {
            // Handle exceptions and return an error response
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Step 5 error:' . $shortMessage,
                'report_id' =>  $request->incident_report_id,
                'report_type' => 'incident_report'
            ];
            storeReportsLogs($log);
            return $this->error('An error occurred while saving  data: ' . $e->getMessage());
        }
    }


    public function  incidentReportPublishReport(Request $request, $id)
    {
        $incidentReport = IncidentReport::find($id);
        if (!$incidentReport) {
            return $this->message('Report Not Found please try again.', 404);
        }
        $userTable = $this->getUserTable();
        if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
            return $this->message('You do not have access to this report.', 403);
        }
        if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
            return $this->message('You do not have access to this report.', 403);
        }
        $incidentReport->is_published = $incidentReport->is_published == '1' ? '0' : '1';
        $incidentReport->save();
        if (!$incidentReport) {
            return $this->error('Failed to update report status');
        }
        $log = [
            'employee_id' => auth()->user()->id,
            'message' => 'Report status updated successfully',
            'report_id' =>  $id,
            'report_type' => 'incident_report'
        ];
        storeReportsLogs($log);
        return $this->message('Report status updated successfully');
    }
    public function destroy($id)
    {
        try {
            // 🔹 Find the Incident Report
            $incidentReport = IncidentReport::find($id);
            if (!$incidentReport) {
                return $this->message('Record not found', 404);
            }
            if ($incidentReport->del == 1) {
                return $this->message('Record already deleted', 403);
            }
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to delete this report.', 403);
            }
            // 🔹 Soft Delete by Updating `del` Field
            $incidentReport->update(['del' => 1]);
            // 🔹 Log Action
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident Report Deleted Successfully',
                'report_id' => $id,
                'report_type' => 'incident_report'
            ]);
            return $this->message('Incident Report Deleted Successfully');
        } catch (\Exception $e) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident Report Delete Failed: ' . $e->getMessage(),
                'report_id' => $id,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('Incident Report Deletion Failed. Please retry.', 500);
        }
    }

    public function checkSignOffApi(Request $request)
    {
        try {
            // 🔹 Validate Request
            $validator = Validator::make($request->all(), [
                'employee_id' => 'required|exists:emp_personal_details,emp_id',
                'incident_report_id' => 'required|exists:incident_reports,id'
            ]);
            if ($validator->fails()) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Step 9 Validation Error: ' . $validator->errors()->first(),
                    'report_id' => $request->incident_report_id,
                    'report_type' => 'incident_report',
                    'error_type' => 'Validation error'
                ]);
                return $this->error($validator->errors()->first(), 422);
            }
            $validatedData = $validator->validated();
            $incidentReport = IncidentReport::find($validatedData['incident_report_id']);
            if (!$incidentReport) {
                return $this->error('Incident Report Record Not Found', 404);
            }
            // 🔹 Check User Permissions
            $userTable = $this->getUserTable();
            if (
                ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) ||
                ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id))
            ) {
                return $this->error('You do not have access to this report.', 403);
            }
            // 🔹 Fetch Sign-Off Records Using ORM
            $incidentSignoffs = IncidentSignoff::where([
                'emp_id' => $validatedData['employee_id'],
                'incident_report_id' => $validatedData['incident_report_id']
            ])->get();
            return $this->success($incidentSignoffs, 'Data retrieved successfully.');
        } catch (\Exception $e) {
            // 🔹 Log the error
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Step 9 Check Sign-Off Error: ' . $e->getMessage(),
                'report_id' => $validatedData['incident_report_id'] ?? null,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while retrieving data.', 500);
        }
    }

    public function signOffApi(Request $request)
    {
        // try {
            $validator = Validator::make($request->all(), [
                'report_id' => 'required',
                'employee_id' => 'required|integer|exists:emp_personal_details,emp_id',
                'report_type' => 'required|string|in:incident_report,swms_report,inspection_report,whs_report,whsqe_report,meeting_note_report',
                'signature' => 'required|file|mimes:png,jpg,jpeg,pdf|max:10240',
                'key' => 'required|string'
            ]);
            if ($validator->fails()) {
                storeReportsLogs([
                    'employee_id' => $request->employee_id ?? null,
                    'message' => 'Sign-Off API Validation Error: ' . $validator->errors()->first(),
                    'report_id' => $request->report_id,
                    'report_type' => $request->report_type,
                    'error_type' => 'Validation error'
                ]);
                return $this->error($validator->errors()->first(), 422);
            }
            $userTable = $this->getUserTable();
            $validatedData = $validator->validated();
            $employeeId = $validatedData['employee_id'];
            $reportType = $validatedData['report_type'];
            $key = $validatedData['key'];
            // 🔹 Use Global File Upload Function
            if ($request->hasFile('signature')) {
                $validatedData['signature'] = $this->handleFileImageUpload($request, 'SignoffSignature')['path'] ?? null;
            } else {
                return $this->error('No signature file uploaded.', 433);
            }
            $employee = EmpCompanyDetails::where('id', $employeeId)->first();
            $employee_personal = EmpPersonalDetails::where('emp_id', $employeeId)->first();
            if ($employee && $employee->employment_type) {
                $employee_type = EmpType::where('id', $employee->employment_type)->first();
            } else {
                $employee_type = null;
            }
            // 🔹 Process Signature Based on Report Type
            switch ($reportType) {
                case 'incident_report':
                    $incidentReport = IncidentReport::find($validatedData['report_id']);
                    if (!$incidentReport) {
                        return $this->error('Incident Report Record Not Found', 404);
                    }
                    if ($userTable === 'customer' && ($incidentReport->customer_id !== auth()->id() || $incidentReport->workspace_id !== auth()->user()->current_workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    if ($userTable === 'emp' && ($incidentReport->customer_id !== auth()->user()->customer_id || $incidentReport->workspace_id !== auth()->user()->workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    
                    // Determine if employee is a site employee or pre-signed employee
                    $existingSignoff = IncidentSignoff::where('incident_report_id', $validatedData['report_id'])
                        ->where('emp_id', $employeeId)
                        ->whereNull('signature')
                        ->first();
                    $isAuthorizedEmployee = $incidentReport->authorised_by == $employeeId;
                    $isSiteEmployee = !$existingSignoff && !$isAuthorizedEmployee;
                    
                    IncidentSignoff::updateOrCreate(
                        [
                            'incident_report_id' => $validatedData['report_id'],
                            'emp_id' => $employeeId
                        ],
                        [
                            'signature' => $validatedData['signature'],
                            'role_code' => $employee->access_role ?? null,
                            'is_site_employee' => $isSiteEmployee ? 1 : 0,
                            'date' => now()->format('Y-m-d'),
                            'time' => now()->format('H:i:s'),
                            'name' => ($employee_personal->first_name ?? '') . ' ' . ($employee_personal->middle_name ?? '') . ' ' . ($employee_personal->last_name ?? '')
                        ]
                    );

                    // Send notification to customer about signature
                    $this->sendSignatureNotification(
                        $validatedData['report_id'],
                        'incident_report',
                        $employeeId,
                        $incidentReport->customer_id,
                        $incidentReport->workspace_id
                    );
                    // Check if the signing employee is the authorised_by person
                    if ($incidentReport->authorised_by == $employeeId) {
                        $incidentReport->approval_status = 3;
                        $incidentReport->is_published = '1';
                        $incidentReport->save();
                        
                        // Send notification to customer about report approval
                        $this->sendReportApprovalNotification(
                            $validatedData['report_id'],
                            'incident_report',
                            $employeeId,
                            $incidentReport->customer_id,
                            $incidentReport->workspace_id
                        );
                        
                        storeReportsLogs([
                            'employee_id' => $employeeId,
                            'message' => 'Incident report approved and published by authorised person (approval_status: 3, is_published: 1)',
                            'report_id' => $validatedData['report_id'],
                            'report_type' => 'incident_report'
                        ]);
                    }
                    break;

                case 'swms_report':
                    // before adding need to confirm logic from TL
                    $swmsReport = Swms::find($validatedData['report_id']);
                    if (!$swmsReport) {
                        return $this->error('SWMS Report Record Not Found', 404);
                    }
                    if ($userTable === 'customer' && ($swmsReport->customer_id !== auth()->id() || $swmsReport->workspace_id !== auth()->user()->current_workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    if ($userTable === 'emp' && ($swmsReport->customer_id !== auth()->user()->customer_id || $swmsReport->workspace_id !== auth()->user()->workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    
                    // Determine if employee is a site employee or pre-signed employee
                    $existingSwmsSignature = SwmsSignature::where('swms_id', $validatedData['report_id'])
                        ->where('emp_id', $employeeId)
                        ->whereNull('signatures')
                        ->first();
                    $isSiteManagerOrForeman = $swmsReport->site_manager_or_forman == $employeeId;
                    $isSiteEmployee = !$existingSwmsSignature && !$isSiteManagerOrForeman;
                    
                    SwmsSignature::updateOrCreate(
                        ['swms_id' => $validatedData['report_id'], 'emp_id' => $employeeId],
                        [
                            'signatures' => $validatedData['signature'],
                            'is_site_employee' => $isSiteEmployee ? 1 : 0,
                            'inductance_date' => now()->format('Y-m-d')
                        ]
                    );

                    // Send notification to customer about signature
                    $this->sendSignatureNotification(
                        $validatedData['report_id'],
                        'swms_report',
                        $employeeId,
                        $swmsReport->customer_id,
                        $swmsReport->workspace_id
                    );
                    // Check if the signing employee is the authorised_by person
                    $authorisedPersonsIds = explode(',', $swmsReport->site_manager_or_forman);
                    if (in_array($employeeId, $authorisedPersonsIds)) {
                        // Check if this is the last authorized person to sign
                        if ($this->isLastAuthorizedPersonToSign($swmsReport, $employeeId)) {
                            $swmsReport->approval_status = 3;
                            $swmsReport->published = '1';
                            $swmsReport->save();

                            // Send notification to customer about report approval
                            $this->sendReportApprovalNotification(
                                $validatedData['report_id'],
                                'swms_report',
                                $employeeId,
                                $swmsReport->customer_id,
                                $swmsReport->workspace_id
                            );
                        }
                    }
                    break;
                case 'inspection_report':
                    $inspectionReport = InspectionPlan::find($validatedData['report_id']);
                    if (!$inspectionReport) {
                        return $this->error('Inspection Report Record Not Found', 404);
                    }
                    if ($userTable === 'customer' && ($inspectionReport->customer_id !== auth()->id() || $inspectionReport->workspace_id !== auth()->user()->current_workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    if ($userTable === 'emp' && ($inspectionReport->customer_id !== auth()->user()->customer_id || $inspectionReport->workspace_id !== auth()->user()->workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    
                    // Determine if employee is a site employee or pre-signed employee
                    $existingInspectionSignature = InspectionPlanSignature::where('inspection_plan_id', $validatedData['report_id'])
                        ->where('employee_id', $employeeId)
                        ->whereNull('signature')
                        ->first();
                    $isAuthorizedEmployee = $inspectionReport->authorised_by == $employeeId;
                    $isSiteEmployee = !$existingInspectionSignature && !$isAuthorizedEmployee;
                    $empCompanyDetails = EmpCompanyDetails::find($employeeId);
                    if ($empCompanyDetails && $empCompanyDetails->access_role) {
                        $employee_type = $empCompanyDetails->access_role;
                    } else {
                        $employee_type = null;
                    }
                    
                    // Get employee personal details with null check
                    $empPersonalDetails = EmpPersonalDetails::where('emp_id', $employeeId)->first();
                    if ($empPersonalDetails) {
                        $firstName = $empPersonalDetails->first_name ?? '';
                        $middleName = $empPersonalDetails->middle_name ? ' ' . $empPersonalDetails->middle_name : '';
                        $lastName = $empPersonalDetails->last_name ?? '';
                        $employee_name = trim($firstName . $middleName . ' ' . $lastName);
                    } else {
                        // If employee not found, skip this record or set default name
                        $employee_name = 'Unknown Employee (ID: ' . $employeeId . ')';
                    }
                    InspectionPlanSignature::updateOrCreate([
                        'inspection_plan_id' => $validatedData['report_id'],
                        'employee_id' => $employeeId
                    ],[
                        'signature' => $validatedData['signature'],
                        'is_site_employee' => $isSiteEmployee ? 1 : 0,
                        'employee_name' => $employee_name,
                        'date' => now()->format('Y-m-d'),
                        'time' => now()->format('H:i:s'),
                        'employee_type' => $employee_type
                    ]);

                    // Send notification to customer about signature
                    $this->sendSignatureNotification(
                        $validatedData['report_id'],
                        'inspection_report',
                        $employeeId,
                        $inspectionReport->customer_id,
                        $inspectionReport->workspace_id
                    );
                    // Check if the signing employee is the authorised_by person
                    if ($inspectionReport->authorised_by == $employeeId) {
                        $inspectionReport->approval_status = 3;
                        $inspectionReport->is_published = '1';
                        $inspectionReport->save();
                        
                        // Send notification to customer about report approval
                        $this->sendReportApprovalNotification(
                            $validatedData['report_id'],
                            'inspection_report',
                            $employeeId,
                            $inspectionReport->customer_id,
                            $inspectionReport->workspace_id
                        );
                        
                        storeReportsLogs([
                            'employee_id' => $employeeId,
                            'message' => 'Inspection report approved and published by authorised person (approval_status: 3, is_published: 1)',
                            'report_id' => $validatedData['report_id'],
                            'report_type' => 'inspection_report'
                        ]);
                    }
                    break;
                case 'whs_report':
                    $whsReport = WhsReport::find($validatedData['report_id']);
                    if (!$whsReport) {
                        return $this->error('Warehouse Report Record Not Found', 404);
                    }
                    if ($userTable === 'customer' && ($whsReport->customer_id !== auth()->id() || $whsReport->workspace_id !== auth()->user()->current_workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    if ($userTable === 'emp' && ($whsReport->customer_id !== auth()->user()->customer_id || $whsReport->workspace_id !== auth()->user()->workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    
                    // Determine if employee is a site employee or pre-signed employee
                    $existingWhsSignature = WhsSignature::where('whs_id', $validatedData['report_id'])
                        ->where('employee_id', $employeeId)
                        ->whereNull('signatures')
                        ->first();
                    $isAuthorizedEmployee = $whsReport->authorised_by == $employeeId;
                    $isSiteEmployee = !$existingWhsSignature && !$isAuthorizedEmployee;
                    
                    DB::table('whs_signatures')->updateOrInsert(
                        [
                            'whs_id' => $validatedData['report_id'],
                            'employee_id' => $employeeId
                        ],
                        [
                            'signatures' => $validatedData['signature'],
                            'is_site_employee' => $isSiteEmployee ? 1 : 0,
                            'inductance_date' => now()->format('Y-m-d'),
                            'created_at' => now(),
                            'updated_at' => now()
                        ]
                    );

                    // Send notification to customer about signature
                    $this->sendSignatureNotification(
                        $validatedData['report_id'],
                        'whs_report',
                        $employeeId,
                        $whsReport->customer_id,
                        $whsReport->workspace_id
                    );
                    
                    // Check if the signing employee is the authorised_by person
                    if ($whsReport->authorised_by == $employeeId) {
                        $whsReport->approval_status = 3;
                        $whsReport->is_published = 1;
                        $whsReport->save();
                        
                        // Send notification to customer about report approval
                        $this->sendReportApprovalNotification(
                            $validatedData['report_id'],
                            'whs_report',
                            $employeeId,
                            $whsReport->customer_id,
                            $whsReport->workspace_id
                        );
                        
                        storeReportsLogs([
                            'employee_id' => $employeeId,
                            'message' => 'WHS report approved and published by authorised person (approval_status: 3, is_published: 1)',
                            'report_id' => $validatedData['report_id'],
                            'report_type' => 'whs_report'
                        ]);
                    }
                    
                    break;

                case 'whsqe_report':
                    $whsqeReport = WhsqReport::find($validatedData['report_id']);
                    if (!$whsqeReport) {
                        return $this->error('WHSQ&E Report Record Not Found', 404);
                    }
                    if ($userTable === 'customer' && ($whsqeReport->customer_id !== auth()->id() || $whsqeReport->workspace_id !== auth()->user()->current_workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    if ($userTable === 'emp' && ($whsqeReport->customer_id !== auth()->user()->customer_id || $whsqeReport->workspace_id !== auth()->user()->workspace_id)) {
                        return $this->message('You do not have access to this report.', 403);
                    }
                    
                    // Determine if employee is a site employee or pre-signed employee
                    $existingWhsqeSignature = WhsqSignature::where('whsq_report_id', $validatedData['report_id'])
                        ->where('employee_id', $employeeId)
                        ->whereNull('signature')
                        ->first();
                    $isAuthorizedEmployee = $whsqeReport->authorised_by == $employeeId;
                    $isSiteEmployee = !$existingWhsqeSignature && !$isAuthorizedEmployee;
                    
                    WhsqSignature::updateOrCreate(
                        [
                            'whsq_report_id' => $validatedData['report_id'],
                            'employee_id' => $employeeId
                        ],
                        [
                            'signature' => $validatedData['signature'],
                            'customer_id' => $whsqeReport->customer_id,
                            'workspace_id' => $whsqeReport->workspace_id,
                            'is_site_employee' => $isSiteEmployee ? 1 : 0,
                            'induction_date' => now()->format('Y-m-d'),
                            'created_at' => now(),
                            'updated_at' => now()
                        ]
                    );
                    
                    // Check if the signing employee is the authorised_by person
                    if ($whsqeReport->authorised_by == $employeeId) {
                        $whsqeReport->approval_status = 3;
                        $whsqeReport->publish = 1;
                        $whsqeReport->save();
                        
                        storeReportsLogs([
                            'employee_id' => $employeeId,
                            'message' => 'WHSQ&E report approved and published by authorised person (approval_status: 3, is_published: 1)',
                            'report_id' => $validatedData['report_id'],
                            'report_type' => 'whsqe_report'
                        ]);
                    }
                    
                    break;
                default:
                    return $this->error('Invalid report type.', 400);
            }
            storeReportsLogs([
                'employee_id' => $employeeId,
                'message' => 'Sign-Off API Success for ' . strtoupper($reportType),
                'report_id' => $validatedData['report_id'],
                'report_type' => $reportType
            ]);
            return $this->message('Saved Successfully');
        // } catch (\Exception $e) {
        //     storeReportsLogs([
        //         'employee_id' => $request->employee_id ?? null,
        //         'message' => 'Sign-Off API Error: ' . $e->getMessage(),
        //         'report_id' => $request->report_id,
        //         'report_type' => $request->report_type,
        //         'error_type' => 'Exception error'
        //     ]);
        //     return $this->error('An error occurred while saving the signature.', 500);
        // }
    }

    // 
    public function SignOffAllFiles(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'employe_id' => 'required',
        ]);
        $authUser = auth()->user();
        if ($validator->fails()) {
            $log = [
                'employee_id' => $authUser->id,
                'message' => 'API Signoff files ' . $validator->errors()->first(),
                'report_id' => 0,
                'report_type' => 'incident_report'
            ];
            storeReportsLogs($log);
            return $this->message($validator->errors()->first(), 422);
        }
        $userLogin = EmpCompanyDetails::with(['EmpPersonalDetails', 'accessRole', 'accessTier'])
            ->where('id', $request->employe_id)
            ->first();
        if (!$userLogin) {
            return $this->message('Employee not found.', 404);
        }
        $userTable = $this->getUserTable();
        if ($userTable === 'customer' && ($userLogin->customer_id !== $authUser->id || $userLogin->workspace_id !== $authUser->current_workspace_id)) {
            return $this->message('You do not have access to this report.', 403);
        }
        if ($userTable === 'emp' && ($userLogin->customer_id !== $authUser->customer_id || $userLogin->workspace_id !== $authUser->workspace_id)) {
            return $this->message('You do not have access to this report.', 403);
        }

        if($request->without_checkin == 1){
            $latestAttendance = new \stdClass();
            $latestAttendance->site_id = null;
        }else{
        $latestAttendance = \App\Models\EmployeeAttendance::where('employee_id', $request->employe_id)
            ->where('customer_id', $userLogin->customer_id)
            ->where('workspace_id', $userLogin->workspace_id)
            ->where('date', date('Y-m-d')) // Filter for today's records only
            ->orderBy('date', 'desc')
            ->orderBy('created_at', 'desc') // In case of multiple records on same date
            ->first();
            if (!$latestAttendance) {
                return $this->message('No attendance record found for this employee.', 404);
            }
        }
        
        $incidentFile_urls = [];
        $inspectionFile_urls = [];
        $swmsFile_urls = [];
        $whsFile_urls = [];
        $whsqeFile_urls = [];
        if ($userLogin && isset($userLogin->accessRole) && is_object($userLogin->accessRole)) {
            $access_role_code = $userLogin->accessRole->code;
            if ($access_role_code) {
                // Get employee ID for authorization checks
                $employeeId = $request->employe_id;
                
                // Implement new sign-off flow logic
                $incident_records = IncidentReport::where('customer_id', $userLogin->customer_id)
                    ->where('workspace_id', $userLogin->workspace_id)
                    ->where('del', 0)
                    ->where(function($approvalQuery) {
                        // Check approval_status = 1 when not published, approval_status = 3 when published
                        $approvalQuery->where(function($notPublishedQuery) {
                            $notPublishedQuery->where(function($nullOrZero) {
                                $nullOrZero->whereNull('is_published')
                                    ->orWhere('is_published', '0');
                            })
                            ->where('approval_status', 1);
                        })
                        ->orWhere(function($publishedQuery) {
                            $publishedQuery->where('is_published', '1')
                                ->where('approval_status', 3);
                        });
                    })
                    ->where(function($query) use ($employeeId) {
                        // Condition 1: Employee is assigned to sign off (in incident_signoffs table)
                        $query->whereExists(function($subquery) use ($employeeId) {
                            $subquery->select(DB::raw(1))
                                ->from('incident_signoffs')
                                ->whereColumn('incident_signoffs.incident_report_id', 'incident_reports.id')
                                ->where('incident_signoffs.emp_id', $employeeId);
                        })
                        // Condition 2: Employee is authorized_by AND all sign-off employees have signed
                        ->orWhere(function($authQuery) use ($employeeId) {
                            $authQuery->where('authorised_by', $employeeId)
                                ->whereNotExists(function($pendingSignoffs) {
                                    $pendingSignoffs->select(DB::raw(1))
                                        ->from('incident_signoffs')
                                        ->whereColumn('incident_signoffs.incident_report_id', 'incident_reports.id')
                                        ->whereNull('incident_signoffs.signature');
                                });
                        });
                    })
                    ->get();
                
                if ($incident_records->isNotEmpty()) {
                    $incident_report_ids = $incident_records->pluck('id');

                    $incident_files = DB::table('generated_pdf_reports')
                        ->whereIn('report_id', $incident_report_ids)
                        ->where('report_type', 'incident_report')
                        ->get(['id', 'report_id', 'path']);
                    $file_mapping = [];
                    $doc_id_mapping = [];
                    foreach ($incident_files as $file) {
                        if (!empty($file->path)) {
                            $file_mapping[$file->report_id] = url($file->path);
                            $doc_id_mapping[$file->report_id] = $file->id;
                        }
                    }
                    foreach ($incident_records as $record) {
                        $incident_signoff = IncidentSignoff::where('incident_report_id', $record->id)
                            ->where('emp_id', $request->employe_id)->first();
                        $incident_report_file_url = $file_mapping[$record->id] ?? '';
                        if ($incident_report_file_url !== '') {
                            $incidentFile_urls[] = [
                                'report_id' => $record->id,
                                'doc_id' => $doc_id_mapping[$record->id] ?? null,
                                'title' => $record->title ?? '',
                                'document_number' => $record->document_number ?? '',
                                'revision_number' => $record->revision_number ?? '',
                                'url' => $file_mapping[$record->id] ?? '',
                                'is_signed' => $incident_signoff && $incident_signoff->signature !== null ? '0' : '1',
                                'type' => 'incident_report',
                                'key' => 'incident_signoffs'
                            ];
                        }
                    }
                }
            }
        }
        $inspection_records = InspectionPlan::where('customer_id', $userLogin->customer_id)
        ->where('workspace_id', $userLogin->workspace_id)
        ->where('del', '0')
        ->where(function($approvalQuery) {
            // Check approval_status = 1 when not published, approval_status = 3 when published
            $approvalQuery->where(function($notPublishedQuery) {
                $notPublishedQuery->where(function($nullOrZero) {
                    $nullOrZero->whereNull('is_published')
                        ->orWhere('is_published', '0');
                })
                ->where('approval_status', 1);
            })
            ->orWhere(function($publishedQuery) {
                $publishedQuery->where('is_published', '1')
                    ->where('approval_status', 3);
            });
        })
        ->where(function($query) use ($employeeId, $latestAttendance) {
            // Step 1: Pre-sign-off employees (always visible to assigned signers) - NO is_published check
            $query->whereExists(function($subquery) use ($employeeId) {
                $subquery->select(DB::raw(1))
                    ->from('inspection_plan_signatures')
                    ->whereColumn('inspection_plan_signatures.inspection_plan_id', 'inspection_plans.id')
                    ->where('inspection_plan_signatures.employee_id', $employeeId)
                    ->where(function($signatureQuery) {
                        // Include if: (1) pre-signed employee (is_site_employee = 0) OR (2) hasn't signed yet
                        $signatureQuery->where('inspection_plan_signatures.is_site_employee', 0)
                            ->orWhereNull('inspection_plan_signatures.signature');
                    });
            })
            // Step 2: Authorized employee (after all pre-signers complete) - NO is_published check
            ->orWhere(function($authQuery) use ($employeeId) {
                $authQuery->where('authorised_by', $employeeId)
                    ->whereNotExists(function($pendingPreSignoffs) {
                        $pendingPreSignoffs->select(DB::raw(1))
                            ->from('inspection_plan_signatures')
                            ->whereColumn('inspection_plan_signatures.inspection_plan_id', 'inspection_plans.id')
                            ->whereNull('inspection_plan_signatures.signature');
                    });
            })
            // Step 3: Site employees (after all pre-signers AND authorized have signed) - WITH is_published check
            ->orWhere(function($siteQuery) use ($employeeId, $latestAttendance) {
                $siteQuery->where('is_published', '1') // Only check is_published for site employees
                ->where('site_id', $latestAttendance->site_id)
                ->where('approval_status', 3)
                // Ensure all pre-signers have signed
                ->whereNotExists(function($pendingPreSignoffs) {
                    $pendingPreSignoffs->select(DB::raw(1))
                        ->from('inspection_plan_signatures')
                        ->whereColumn('inspection_plan_signatures.inspection_plan_id', 'inspection_plans.id')
                        ->whereNull('inspection_plan_signatures.signature');
                })
                // Ensure authorized user has signed (check if there's a record with signature for authorized user)
                ->whereExists(function($authorizedSigned) {
                    $authorizedSigned->select(DB::raw(1))
                        ->from('inspection_plan_signatures')
                        ->whereColumn('inspection_plan_signatures.inspection_plan_id', 'inspection_plans.id')
                        ->whereColumn('inspection_plan_signatures.employee_id', 'inspection_plans.authorised_by')
                        ->whereNotNull('inspection_plan_signatures.signature');
                })
                // Exclude reports that the current employee has already signed as a site employee
                ->whereNotExists(function($alreadySigned) use ($employeeId) {
                    $alreadySigned->select(DB::raw(1))
                        ->from('inspection_plan_signatures')
                        ->whereColumn('inspection_plan_signatures.inspection_plan_id', 'inspection_plans.id')
                        ->where('inspection_plan_signatures.employee_id', $employeeId)
                        ->where('inspection_plan_signatures.is_site_employee', 1)
                        ->whereNotNull('inspection_plan_signatures.signature');
                });
            });
        })
        ->get();
        if ($inspection_records->isNotEmpty()) {
            $inspection_report_ids = $inspection_records->pluck('id');

            $inspection_files = DB::table('generated_pdf_reports')
                ->whereIn('report_id', $inspection_report_ids)
                ->where('report_type', 'inspection_report')
                ->get(['id', 'report_id', 'path']);
            $file_mapping = [];
            $doc_id_mapping = [];
            foreach ($inspection_files as $file) {
                if (!empty($file->path)) {
                    $file_mapping[$file->report_id] = url($file->path);
                    $doc_id_mapping[$file->report_id] = $file->id;
                }
            }
            foreach ($inspection_records as $record) {
                $inspection_signature = InspectionPlanSignature::where('inspection_plan_id', $record->id)
                    ->where('employee_id', $request->employe_id)->first();
                $inspection_report_file_url = $file_mapping[$record->id] ?? '';
                if ($inspection_report_file_url !== '') {
                    $inspectionFile_urls[] = [
                        'report_id' => $record->id,
                        'doc_id' => $doc_id_mapping[$record->id] ?? null,
                        'title' => $record->title ?? '',
                        'document_number' => $record->document_number ?? '',
                        'revision_number' => $record->revision_number ?? '',
                        'url' => $file_mapping[$record->id] ?? '',
                        'is_signed' => $inspection_signature && $inspection_signature->signature !== null ? '0' : '1',
                        'type' => 'inspection_report',
                        'key' => 'inspection_signatures'
                    ];
                }
            }
        }
        $swms_records = Swms::where('customer_id', $userLogin->customer_id)
        ->where('workspace_id', $userLogin->workspace_id)
        ->where('del', '0')
        ->where(function($approvalQuery) {
            // Check approval_status = 1 when not published, approval_status = 3 when published
            $approvalQuery->where(function($notPublishedQuery) {
                $notPublishedQuery->where(function($nullOrZero) {
                    $nullOrZero->whereNull('published')
                        ->orWhere('published', '0');
                })
                ->where('approval_status', 1);
            })
            ->orWhere(function($publishedQuery) {
                $publishedQuery->where('published', '1')
                    ->where('approval_status', 3);
            });
        })
        ->where(function($query) use ($employeeId, $latestAttendance) {
            // Step 1: Pre-sign-off employees (always visible to assigned signers) - NO published check
            $query->whereExists(function($subquery) use ($employeeId) {
                $subquery->select(DB::raw(1))
                    ->from('swms_signatures')
                    ->whereColumn('swms_signatures.swms_id', 'swms.id')
                    ->where('swms_signatures.emp_id', $employeeId)
                    ->where(function($signatureQuery) {
                        // Include if: (1) pre-signed employee (is_site_employee = 0) OR (2) hasn't signed yet
                        $signatureQuery->where('swms_signatures.is_site_employee', 0)
                            ->orWhereNull('swms_signatures.signatures');
                    });
            })
            // Step 2: Site Manager/Foreman (after all pre-signers complete) - NO published check
            ->orWhere(function($authQuery) use ($employeeId) {
                $authQuery->whereRaw("FIND_IN_SET(?, site_manager_or_forman) > 0", [$employeeId])
                    ->whereNotExists(function($pendingPreSignoffs) {
                        $pendingPreSignoffs->select(DB::raw(1))
                            ->from('swms_signatures')
                            ->whereColumn('swms_signatures.swms_id', 'swms.id')
                            ->whereNull('swms_signatures.signatures');
                    });
            })
            // Step 3: Site employees (after all pre-signers AND site manager/foreman have signed) - WITH published check
            ->orWhere(function($siteQuery) use ($employeeId, $latestAttendance) {
                $siteQuery->where('published', '1') // Only check published for site employees
                ->where('site_id', $latestAttendance->site_id)
                ->where('approval_status', 3)
                // Ensure all pre-signers have signed
                ->whereNotExists(function($pendingPreSignoffs) {
                    $pendingPreSignoffs->select(DB::raw(1))
                        ->from('swms_signatures')
                        ->whereColumn('swms_signatures.swms_id', 'swms.id')
                        ->whereNull('swms_signatures.signatures');
                })
                // Ensure site manager/foreman has signed (check if there's a record with signature for site manager/foreman)
                ->whereExists(function($managerSigned) {
                    $managerSigned->select(DB::raw(1))
                        ->from('swms_signatures')
                        ->whereColumn('swms_signatures.swms_id', 'swms.id')
                        ->whereRaw("FIND_IN_SET(swms_signatures.emp_id, swms.site_manager_or_forman) > 0")
                        ->whereNotNull('swms_signatures.signatures');
                })
                // Exclude reports that the current employee has already signed as a site employee
                ->whereNotExists(function($alreadySigned) use ($employeeId) {
                    $alreadySigned->select(DB::raw(1))
                        ->from('swms_signatures')
                        ->whereColumn('swms_signatures.swms_id', 'swms.id')
                        ->where('swms_signatures.emp_id', $employeeId)
                        ->where('swms_signatures.is_site_employee', 1)
                        ->whereNotNull('swms_signatures.signatures');
                });
            });
        })
        ->get();
        if ($swms_records->isNotEmpty()) {
            $swms_report_ids = $swms_records->pluck('id');

                $swms_files = DB::table('generated_pdf_reports')
                ->whereIn('report_id', $swms_report_ids)
                    ->where('report_type', 'swms_report')
                    ->get(['id', 'report_id', 'path']);
            $file_mapping = [];
            $doc_id_mapping = [];
            foreach ($swms_files as $file) {
                if (!empty($file->path)) {
                    $file_mapping[$file->report_id] = url($file->path);
                    $doc_id_mapping[$file->report_id] = $file->id;
                }
            }
            foreach ($swms_records as $record) {
                $swms_signature = SwmsSignature::where('swms_id', $record->id)
                    ->where('emp_id', $request->employe_id)->first();
                $swms_report_file_url = $file_mapping[$record->id] ?? '';
                if ($swms_report_file_url !== '') {
                        $swmsFile_urls[] = [
                        'report_id' => $record->id,
                        'doc_id' => $doc_id_mapping[$record->id] ?? null,
                        'title' => $record->title ?? '',
                        'document_number' => $record->swms_number ?? '',
                        'revision_number' => $record->revision_number ?? '',
                        'url' => $file_mapping[$record->id] ?? '',
                        'is_signed' => $swms_signature && $swms_signature->signatures !== null ? '0' : '1',
                            'type' => 'swms_report',
                        'key' => 'signatures'
                        ];
                    }
                }
            }
        $whs_records = WhsReport::where('customer_id', $userLogin->customer_id)
        ->where('workspace_id', $userLogin->workspace_id)
        ->where('del', '0')
        ->where(function($approvalQuery) {
            // Check approval_status = 1 when not published, approval_status = 3 when published
            $approvalQuery->where(function($notPublishedQuery) {
                $notPublishedQuery->where(function($nullOrZero) {
                    $nullOrZero->whereNull('is_published')
                        ->orWhere('is_published', '0');
                })
                ->where('approval_status', 1);
            })
            ->orWhere(function($publishedQuery) {
                $publishedQuery->where('is_published', '1')
                    ->where('approval_status', 3);
            });
        })
        ->where(function($query) use ($employeeId, $latestAttendance) {
            // Step 1: Pre-sign-off employees (always visible to assigned signers) - NO is_published check
            $query->whereExists(function($subquery) use ($employeeId) {
                $subquery->select(DB::raw(1))
                    ->from('whs_signatures')
                    ->whereColumn('whs_signatures.whs_id', 'whs_reports.id')
                    ->where('whs_signatures.employee_id', $employeeId)
                    ->where(function($signatureQuery) {
                        // Include if: (1) pre-signed employee (is_site_employee = 0) OR (2) hasn't signed yet
                        $signatureQuery->where('whs_signatures.is_site_employee', 0)
                            ->orWhereNull('whs_signatures.signatures');
                    });
            })
            // Step 2: Authorized employee (after all pre-signers complete) - NO is_published check
            ->orWhere(function($authQuery) use ($employeeId) {
                $authQuery->where('authorised_by', $employeeId)
                    ->whereNotExists(function($pendingPreSignoffs) {
                        $pendingPreSignoffs->select(DB::raw(1))
                            ->from('whs_signatures')
                            ->whereColumn('whs_signatures.whs_id', 'whs_reports.id')
                            ->whereNull('whs_signatures.signatures');
                    });
            })
            // Step 3: Site employees (after all pre-signers AND authorized have signed) - WITH is_published check
            ->orWhere(function($siteQuery) use ($employeeId, $latestAttendance) {
                $siteQuery->where('is_published', '1') // Only check is_published for site employees
                ->where('site_id', $latestAttendance->site_id)
                ->where('approval_status', 3)
                // Ensure all pre-signers have signed
                ->whereNotExists(function($pendingPreSignoffs) {
                    $pendingPreSignoffs->select(DB::raw(1))
                        ->from('whs_signatures')
                        ->whereColumn('whs_signatures.whs_id', 'whs_reports.id')
                        ->whereNull('whs_signatures.signatures');
                })
                // Ensure authorized user has signed (check if there's a record with signature for authorized user)
                ->whereExists(function($authorizedSigned) {
                    $authorizedSigned->select(DB::raw(1))
                        ->from('whs_signatures')
                        ->whereColumn('whs_signatures.whs_id', 'whs_reports.id')
                        ->whereColumn('whs_signatures.employee_id', 'whs_reports.authorised_by')
                        ->whereNotNull('whs_signatures.signatures');
                })
                // Exclude reports that the current employee has already signed as a site employee
                ->whereNotExists(function($alreadySigned) use ($employeeId) {
                    $alreadySigned->select(DB::raw(1))
                        ->from('whs_signatures')
                        ->whereColumn('whs_signatures.whs_id', 'whs_reports.id')
                        ->where('whs_signatures.employee_id', $employeeId)
                        ->where('whs_signatures.is_site_employee', 1)
                        ->whereNotNull('whs_signatures.signatures');
                });
            });
        })
        ->get();
        if ($whs_records->isNotEmpty()) {
            $whs_report_ids = $whs_records->pluck('id');

                $whs_files = DB::table('generated_pdf_reports')
                ->whereIn('report_id', $whs_report_ids)
                ->where('report_type', 'whs_report')
                    ->get(['id', 'report_id', 'path']);
            $file_mapping = [];
            $doc_id_mapping = [];
                    foreach ($whs_files as $file) {
                if (!empty($file->path)) {
                    $file_mapping[$file->report_id] = url($file->path);
                    $doc_id_mapping[$file->report_id] = $file->id;
                }
            }
                        foreach ($whs_records as $record) {
                $whs_signature = WhsSignature::where('whs_id', $record->id)
                    ->where('employee_id', $request->employe_id)->first();
                $whs_report_file_url = $file_mapping[$record->id] ?? '';
                if ($whs_report_file_url !== '') {
                        $whsFile_urls[] = [
                        'report_id' => $record->id,
                        'doc_id' => $doc_id_mapping[$record->id] ?? null,
                        'title' => $record->title ?? '',
                        'document_number' => $record->number ?? '',
                        'revision_number' => $record->revision_number ?? '',
                        'url' => $file_mapping[$record->id] ?? '',
                        'is_signed' => $whs_signature && $whs_signature->signatures !== null ? '0' : '1',
                        'type' => 'whs_report',
                        'key' => 'whs_signatures'
                        ];
                }
            }
        }
        $whsqe_records = WhsqReport::where('customer_id', $userLogin->customer_id)
        ->where('workspace_id', $userLogin->workspace_id)
        ->where(function($approvalQuery) {
            // Check approval_status = 1 when not published, approval_status = 3 when published
            $approvalQuery->where(function($notPublishedQuery) {
                $notPublishedQuery->where(function($nullOrZero) {
                    $nullOrZero->whereNull('publish')
                        ->orWhere('publish', '0');
                })
                ->where('approval_status', 1);
            })
            ->orWhere(function($publishedQuery) {
                $publishedQuery->where('publish', '1')
                    ->where('approval_status', 3);
            });
        })
        ->where(function($query) use ($employeeId) {
            // Condition 1: Employee is assigned to sign off (in incident_signoffs table)
            $query->whereExists(function($subquery) use ($employeeId) {
                $subquery->select(DB::raw(1))
                    ->from('whsq_signature')
                    ->whereColumn('whsq_signature.whsq_report_id', 'whsq_reports.id')
                    ->where('whsq_signature.employee_id', $employeeId);
            })
            // Condition 2: Employee is authorized_by AND all sign-off employees have signed
            ->orWhere(function($authQuery) use ($employeeId) {
                $authQuery->where('authorised_by', $employeeId)
                    ->whereNotExists(function($pendingSignoffs) {
                        $pendingSignoffs->select(DB::raw(1))
                            ->from('whsq_signature')
                            ->whereColumn('whsq_signature.whsq_report_id', 'whsq_reports.id')
                            ->whereNull('whsq_signature.signature');
                    });
            });
        })
        ->get();
        
        if ($whsqe_records->isNotEmpty()) {
            $whsqe_report_ids = $whsqe_records->pluck('id');

            $whsqe_files = DB::table('generated_pdf_reports')
                ->whereIn('report_id', $whsqe_report_ids)
                ->where('report_type', 'whsqe_report')
                ->get(['id', 'report_id', 'path']);
            $file_mapping = [];
            $doc_id_mapping = [];
            foreach ($whsqe_files as $file) {
                if (!empty($file->path)) {
                    $file_mapping[$file->report_id] = url($file->path);
                    $doc_id_mapping[$file->report_id] = $file->id;
                }
            }
            foreach ($whsqe_records as $record) {
                $whsqe_signoff = WhsqSignature::where('whsq_report_id', $record->id)
                    ->where('employee_id', $request->employe_id)->first();
                $whsqe_report_file_url = $file_mapping[$record->id] ?? '';
                if ($whsqe_report_file_url !== '') {
                    $whsqeFile_urls[] = [
                        'report_id' => $record->id,
                        'doc_id' => $doc_id_mapping[$record->id] ?? null,
                        'title' => $record->document_title ?? '',
                        'document_number' => $record->document_number ?? '',
                        'revision_number' => $record->revision_number ?? '',
                        'url' => $file_mapping[$record->id] ?? '',
                        'is_signed' => $whsqe_signoff && $whsqe_signoff->signature !== null ? '0' : '1',
                        'type' => 'whsqe_report',
                        'key' => 'whsqe_signatures'
                    ];
                }
            }
        }
        $log = [
            'employee_id' => auth()->user()->id,
            'message' => 'API SignOff Files fetched successfully',
            'report_id' => 0,
            'report_type' => 'incident_report',

        ];
        storeReportsLogs($log);
        $data = [
            'incident_report' => $incidentFile_urls ?? [],
            'inspection_report' => $inspectionFile_urls ?? [],
            'swms_report' => $swmsFile_urls ?? [],
            'whs_report' => $whsFile_urls ?? [],
            'whsqe_report' => $whsqeFile_urls ?? [],
        ];
        return $this->success($data, 'SignOff Files fetched successfully');
    }
    private function isLastAuthorizedPersonToSign($swmsReport, $currentEmployeeId)
    {
        try {
            // Get all authorized persons from the site_manager_or_forman field
            $authorizedPersonIds = [];
            if ($swmsReport->site_manager_or_forman) {
                $authorizedPersonIds = array_map('trim', explode(',', $swmsReport->site_manager_or_forman));
                $authorizedPersonIds = array_filter($authorizedPersonIds, function($id) {
                    return !empty($id) && $id != '0';
                });
            }

            if (empty($authorizedPersonIds)) {
                Log::warning("No authorized persons found for SWMS report ID: {$swmsReport->id}");
                return false;
            }

            // Get all signatures for this SWMS report
            $existingSignatures = DB::table('swms_signatures')
                ->where('swms_id', $swmsReport->id)
                ->whereNotNull('signatures')
                ->pluck('emp_id')
                ->toArray();

            // Check if all authorized persons have signed
            $allAuthorizedPersonsSigned = true;
            $unsignedAuthorizedPersons = [];

            foreach ($authorizedPersonIds as $authorizedPersonId) {
                if (!in_array($authorizedPersonId, $existingSignatures)) {
                    $allAuthorizedPersonsSigned = false;
                    $unsignedAuthorizedPersons[] = $authorizedPersonId;
                }
            }
            // Return true only if all authorized persons have signed
            return $allAuthorizedPersonsSigned;

        } catch (\Exception $e) {
            Log::error("Error checking if last authorized person to sign for SWMS report {$swmsReport->id}: " . $e->getMessage());
            return false;
        }
    }

    
    public function copyIncidentReport($parent_incident_id)
    {
        $incidentReport = IncidentReport::find($parent_incident_id);
        if (!$incidentReport) {
            return $this->error('Incident Report Record Not Found', 404);
        }
        $userTable = $this->getUserTable();
        $user = auth()->user();
        if (
            ($userTable === 'customer' && ($incidentReport->customer_id !== $user->id || $incidentReport->workspace_id !== $user->current_workspace_id)) ||
            ($userTable === 'emp' && ($incidentReport->customer_id !== $user->customer_id || $incidentReport->workspace_id !== $user->workspace_id))
        ) {
            return $this->message('You do not have access to this report.', 403);
        }
        // Create child incident report using replicate method (creates complete copy with new parent_number and revision_number)
        $childIncidentReport = $incidentReport->replicate()->fill([
            'parent_number' => $incidentReport->id,
            'revision_number' => $this->generateRevisionNumber($incidentReport->id),
            'is_published' => "0",
        ]);
        $childIncidentReport->approval_status = 0;
        $childIncidentReport->save();
        $child_incident_id = $childIncidentReport->id;
        if (!$childIncidentReport) {
            return $this->error('Failed to create child incident report.');
        }
        $validatedData['incident_report_id'] = $childIncidentReport->id;

        try {

            $incident_reported_tos = DB::table('incident_reported_tos')->where('incident_report_id', $parent_incident_id)->get();
            $incident_reported_bys = DB::table('incident_reported_bys')->where('incident_report_id', $parent_incident_id)->get();
            $incident_classification_reports = DB::table('incident_classification_reports')->where('incident_report_id', $parent_incident_id)->get();
            $incident_notified_tos = DB::table('incident_notified_tos')->where('incident_report_id', $parent_incident_id)->get();
            $incident_involved_person_details = DB::table('incident_involved_person_details')->where('incident_report_id', $parent_incident_id)->get();
            $incident_involved_person_trainings = DB::table('incident_involved_person_trainings')->where('incident_report_id', $parent_incident_id)->get();
            $incident_employee_injury_types = DB::table('incident_employee_injury_types')->where('incident_report_id', $parent_incident_id)->get();
            $incident_employer_details = DB::table('incident_employer_details')->where('incident_report_id', $parent_incident_id)->get();
            $incident_report_question_answers = DB::table('incident_report_question_answers')->where('incident_report_id', $parent_incident_id)->get();
            $incident_report_metas = DB::table('incident_report_metas')->where('incident_report_id', $parent_incident_id)->get();
            $incident_injury_managements = DB::table('incident_injury_managements')->where('incident_report_id', $parent_incident_id)->get();
            $incident_final_classifications = DB::table('incident_final_classifications')->where('incident_report_id', $parent_incident_id)->get();
            $incident_signoffs = DB::table('incident_signoffs')->where('incident_report_id', $parent_incident_id)->get();
            $incident_risk_category_details = DB::table('incident_risk_category_details')->where('incident_report_id', $parent_incident_id)->get();
            $incident_witness = DB::table('incident_witness')->where('incident_report_id', $parent_incident_id)->get();
            $incident_documents = DB::table('incident_documents')->where('incident_report_id', $parent_incident_id)->get();
            $tosData = $incident_reported_tos->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'reported_to' => $item->reported_to,
                    'company_name' => $item->company_name,
                    'position' => $item->position,
                    'contact_number' => $item->contact_number
                ];
            })->toArray();

            $bysData = $incident_reported_bys->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'reported_by' => $item->reported_by,
                    'company_name' => $item->company_name,
                    'position' => $item->position,
                    'contact_number' => $item->contact_number
                ];
            })->toArray();
            $incident_classification_reportsData = $incident_classification_reports->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'injury_classification_id' => $item->injury_classification_id,
                    'details' => $item->details,
                    'type' => $item->type,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,


                ];
            })->toArray();
            $incident_notified_tos = $incident_notified_tos->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'notified_to' => $item->notified_to,
                    'ohs_regulator' => $item->ohs_regulator,
                    'reference_number' => $item->reference_number,
                    'date' => $item->date,
                    'time' => $item->time,
                    'contact_name' => $item->contact_name,

                ];
            })->toArray();
            $incident_involved_person_details = $incident_involved_person_details->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'employee_id' => $item->employee_id,
                    'surname' => $item->surname,
                    'contact_number' => $item->contact_number,
                    'gender' => $item->gender,
                    'dob' => $item->dob,
                    'age' => $item->age,
                    'occupation' => $item->occupation,
                    'language' => $item->language,
                    'experience_years' => $item->experience_years,
                    'experience_months' => $item->experience_months,
                    'employment_type' => $item->employment_type,
                    'employee_type' => $item->employee_type,
                    'shift_type' => $item->shift_type,
                    'shift_time' => $item->shift_time,

                ];
            })->toArray();
            $incident_involved_person_trainings = $incident_involved_person_trainings->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'training_id' => $item->training_id,
                    'incident_involved_person_id' => $item->incident_involved_person_id,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,


                ];
            })->toArray();
            $incident_employee_injury_types = $incident_employee_injury_types->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'employer_id' => $item->employer_id,
                    'option' => $item->option,
                    'value' => $item->value,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,


                ];
            })->toArray();
            $incident_employer_details = $incident_employer_details->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'employer_id' => $item->employer_id,
                    'employer_name' => $item->employer_name,
                    'employer_address' => $item->employer_address,
                    'employer_number' => $item->employer_number,
                    'supervisor' => $item->supervisor,
                    'contact_number' => $item->contact_number,
                    'is_employer_worker' => $item->is_employer_worker,
                    'is_employer_worker_details' => $item->is_employer_worker_details,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,


                ];
            })->toArray();
            $incident_report_question_answersData = $incident_report_question_answers->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'question_id' => $item->question_id,
                    'answer' => $item->answer,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,


                ];
            })->toArray();

            $incident_report_metas_array = $incident_report_metas->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'equipment_type' => $item->equipment_type,
                    'registration_number' => $item->registration_number,
                    'damage' => $item->damage,
                    'cost' => $item->cost,
                    'incident_response' => $item->incident_response,
                    'shift_type' => $item->shift_type,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                ];
            })->toArray();
            $incident_injury_managements = $incident_injury_managements->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'date' => $item->date,
                    'time' => $item->time,
                    'representative_name' => $item->representative_name,
                    'previous_injury_date' => $item->previous_injury_date,
                    'injured_names' => $item->injured_names,
                    'is_first_aid' => $item->is_first_aid,
                    'is_referred' => $item->is_referred,
                    'is_doctor' => $item->is_doctor,
                    'is_clinic' => $item->is_clinic,
                    'is_admit' => $item->is_admit,
                    'is_doctor_details' => $item->is_doctor_details,
                    'doctor_name' => $item->doctor_name,
                    'doctor_number' => $item->doctor_number,
                    'doctor_address' => $item->doctor_address,
                    'hospital_name' => $item->hospital_name,
                    'hospital_number' => $item->hospital_number,
                    'hospital_address' => $item->hospital_address,
                    'is_recurrence_injury' => $item->is_recurrence_injury,
                    'previous_report_number' => $item->previous_report_number,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                ];
            })->toArray();
            $incident_final_classifications = $incident_final_classifications->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'final_incident_name' => $item->final_incident_name,
                    'final_incident_details' => $item->final_incident_details,
                    'is_rehabilitation' => $item->is_rehabilitation,
                    'return_to_duty_date' => $item->return_to_duty_date,
                    'rtw_date' => $item->rtw_date,
                    'total_lost_days' => $item->total_lost_days,
                    'is_worker_notified' => $item->is_worker_notified,
                    'notified_by_whom' => $item->notified_by_whom,
                    'date' => $item->date,
                    'time' => $item->time,
                    'details' => $item->details,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                ];
            })->toArray();
            $incident_signoffs = $incident_signoffs->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'role_code' => $item->role_code,
                    'emp_id' => $item->emp_id,
                    'name' => $item->name,
                    'signature' => $item->signature,
                    'time' => $item->time,
                    'date' => $item->date,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                ];
            })->toArray();
            $incident_risk_category_details = $incident_risk_category_details->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'incident_risk_category_id' => $item->incident_risk_category_id,
                    'details' => $item->details,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                ];
            })->toArray();
            $incident_witness = $incident_witness->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'name' => $item->name,
                    'date' => $item->date,
                    'time' => $item->time,
                    'statement_number' => $item->statement_number,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                ];
            })->toArray();
            $incident_documents = $incident_documents->map(function ($item) use ($child_incident_id) {
                return [
                    'incident_report_id' => $child_incident_id,
                    'title' => $item->title,
                    'number' => $item->number,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                ];
            })->toArray();


            DB::table('incident_documents')->insert($incident_documents);
            DB::table('incident_reported_tos')->insert($tosData);
            DB::table('incident_reported_bys')->insert($bysData);
            DB::table('incident_classification_reports')->insert($incident_classification_reportsData);
            DB::table('incident_notified_tos')->insert($incident_notified_tos);
            DB::table('incident_involved_person_details')->insert($incident_involved_person_details);
            DB::table('incident_involved_person_trainings')->insert($incident_involved_person_trainings);
            DB::table('incident_employee_injury_types')->insert($incident_employee_injury_types);
            DB::table('incident_employer_details')->insert($incident_employer_details);
            DB::table('incident_report_question_answers')->insert($incident_report_question_answersData);
            DB::table('incident_report_metas')->insert($incident_report_metas_array);
            DB::table('incident_injury_managements')->insert($incident_injury_managements);
            DB::table('incident_final_classifications')->insert($incident_final_classifications);
            DB::table('incident_signoffs')->insert($incident_signoffs);
            DB::table('incident_risk_category_details')->insert($incident_risk_category_details);
            DB::table('incident_witness')->insert($incident_witness);
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'Updated Report version to ' . $child_incident_id . ' from parent id' . $parent_incident_id,
                'report_id' => $parent_incident_id,
                'report_type' => 'incident_report'
            ];
            storeReportsLogs($log);
            return $this->message('Incident Report copied successfully');
        } catch (\Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'Updated Report version to ' . $child_incident_id . ' from parent id' . $parent_incident_id . "error: " .   $shortMessage,
                'report_id' =>  $child_incident_id,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'

            ];
            storeReportsLogs($log);
            return $this->error($shortMessage);
        }
    }
    public function incidentReportDownloadPdf($id, $response = 0)
    {
        if (!$id) {
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'Report ID is required ',
                'report_id' => 0,
                'report_type' => 'incident_report',
                'error_type' => 'Not found error'

            ];
            storeReportsLogs($log);
            return $this->message('Report ID is required', 422);
        }
        try {
            $userTable = $this->getUserTable(); // Get user type (customer or emp)
            $dataClassifications = IncidentReport::where('id', $id)
                ->with([
                    'injuryClassifications' => function ($query) {
                        $query->select('incident_injury_classifications.id as injury_id', 'incident_injury_classifications.title');
                    }
                ])
                ->get()
                ->pluck('injuryClassifications')
                ->flatten()
                ->map(function ($classification) {
                    return ['incident_injury_classifications_title' => $classification->title];
                });
            $data = IncidentReport::with([
                'site:id,title,supervisor_id',
                'project:id,title',
                'authorisedBy:id,first_name,last_name,emp_id',
                'reportedTos' => function ($query) {
                    $query->with([
                        'reportedToEmployee:id,emp_id,first_name,last_name',
                        'positionDetail:id,title'
                    ]);
                },
                'reportedToDetails:emp_id,first_name,last_name',
                'reportedBys' => function ($query) {
                    $query->with([
                        'reportedByEmployee:id,emp_id,first_name,last_name',
                        'positionDetail:id,title'
                    ]);
                },
                'reportedByDetails:emp_id,first_name,last_name',
                'classifications:id,incident_report_id,injury_classification_id,details',
                'injuryClassifications',
                'notifiableClassifications' => function ($query) use ($userTable) {
                    if ($userTable === 'customer') {
                        $query->where('customer_id', auth()->id())
                            ->where('workspace_id', auth()->user()->current_workspace_id);
                    } elseif ($userTable === 'emp') {
                        $query->where('customer_id', auth()->user()->customer_id)
                            ->where('workspace_id', auth()->user()->workspace_id);
                    } else {
                        $query->whereRaw('1 = 0');
                    }
                },
                'notifiedTos' => function ($query) {
                    $query->select('incident_notified_tos.*');
                },
                'involvedPersons' => function ($query) {
                    $query->select('incident_involved_person_details.*')
                        ->with('employmentType:id,title'); // Ensure employmentType is loaded
                },
                'involvedTrainings:id,title',
                'injuryTypes:id,incident_report_id,option',
                'employerDetails:id,incident_report_id,employer_name,is_employer_worker',
                'questions' => function ($query) use ($userTable) {
                    if ($userTable === 'customer') {
                        $query->where('customer_id', auth()->id())
                            ->where('workspace_id', auth()->user()->current_workspace_id);
                    } elseif ($userTable === 'emp') {
                        $query->where('customer_id', auth()->user()->customer_id)
                            ->where('workspace_id', auth()->user()->workspace_id);
                    } else {
                        $query->whereRaw('1 = 0');
                    }
                },
                // 'questionAnswers:id,incident_report_id,question_id,answer',
                'incidentReportMetas:id,incident_report_id,shift_type,equipment_type,registration_number,damage,cost',
                'injuryManagements',
                'finalClassifications:id,incident_report_id,final_incident_details,is_rehabilitation,return_to_duty_date,rtw_date,total_lost_days,is_worker_notified,notified_by_whom,date,time,details',
                'incidentRiskCategoryDetails:id,incident_report_id,incident_risk_category_id,details',
                'incidentWitnesses:id,incident_report_id,name,date,time,statement_number',
                'incidentDocuments:id,incident_report_id,title,number',
                'supervisor:emp_id,first_name,last_name',
                'forman:emp_id,first_name,last_name',
            ])->find($id);
            // $supervisorIds = explode(',', $data->site_supervisor_id);
            $supervisors = EmpPersonalDetails::where('emp_id', $data->site->supervisor_id)
                ->select('first_name as emp_personal_supervisor_detail_f_name', 'last_name as emp_personal_supervisor_detail_last_name')
                ->get();
            $questionsAndAnswers = IncidentReportQuestionAnswer::where('incident_report_id', $id)
                ->with('question:id,question')
                ->get()
                ->map(function ($qa) {
                    return [
                        'question' => $qa->question->question ?? null,
                        'answer' => $qa->answer,
                    ];
                });
            $incidentSignoffs = IncidentSignoff::where('incident_report_id', $id)
                ->with([
                    'employee:emp_id,first_name,last_name' // Load related employee details
                ])
                ->get(['emp_id', 'signature', 'date', 'time', 'role_code'])
                ->map(function ($signoff) {
                    return [
                        'emp_personal_details_first_name' => $signoff->employee->first_name ?? null,
                        'emp_personal_details_last_name' => $signoff->employee->last_name ?? null,
                        'inc_signoffs_signature' => $signoff->signature,
                        'inc_signoffs_date' => $signoff->date,
                        'inc_signoffs_time' => $signoff->time,
                        'inc_signoffs_role_code' => $signoff->role_code,
                    ];
                });
            $reportImages = IncidentImage::where('incident_report_id', $id)->get();
            $viewPath = 'incident_reports_pdf';
            $html = view($viewPath, compact('data', 'questionsAndAnswers', 'incidentSignoffs', 'dataClassifications', 'reportImages', 'supervisors'))->render();
            $filename = sprintf(
                "%s_%s_R%s.pdf",
                preg_replace('/[^A-Za-z0-9_]+/', '_', trim(str_replace(' ', '_', $data->title ?? 'incident_report'))),
                preg_replace('/[^A-Za-z0-9_]+/', '', trim(str_replace(' ', '_', $data->document_number ?? rand(99999, 999999)))),
                preg_replace('/[^A-Za-z0-9_]+/', '', trim(str_replace(' ', '_', $data->revision_number ?? '00')))
            );
            // Define Storage Path
            $folderPath = public_path('IncidentReportDocuments');
            if (!File::exists($folderPath)) {
                File::makeDirectory($folderPath, 0755, true);
            }
            $pdfPath = $folderPath . '/' . $filename;
            // Check if the PDF already exists
            $existingReport = GeneratedPdfReport::where([
                ['report_type', 'incident_report'],
                ['report_id', $id],
                ['path', url('IncidentReportDocuments/' . $filename)]
            ])->first();
            if ($existingReport) {
                return $this->success(['downloadUrl' => url('IncidentReportDocuments/' . $filename)], 'Report already exists..');
            }
            // Generate PDF
            $pdf = PDF::loadHTML($html)->setPaper('A4', 'portrait');
            $pdf->save($pdfPath);
            // Save Report in Database
            if ($userTable === "customer") {
                $customerId = auth()->id();
                $workspaceId = auth()->user()->current_workspace_id;
            } elseif ($userTable === "emp") {
                $customerId = auth()->user()->customer_id;
                $workspaceId = auth()->user()->workspace_id;
            }
            $generatedReport = new GeneratedPdfReport();
            $generatedReport->report_id = $id;
            $generatedReport->path = url('IncidentReportDocuments/' . $filename);
            $generatedReport->report_type = 'incident_report';
            $generatedReport->customer_id = $customerId;
            $generatedReport->workspace_id = $workspaceId;
            $generatedReport->save();
            return $this->success(['downloadUrl' => url('IncidentReportDocuments/' . $filename)], 'Incident report generated successfully.');
        } catch (\Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'Download report id' . $id . ' error ' .   $shortMessage,
                'report_id' =>  $id,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'

            ];
            storeReportsLogs($log);
            return $this->error($shortMessage);
        }
    }

    public function IncidentReportPdfFiles(Request $request)
    {
        try {
            $userTable = $this->getUserTable();
            $reportType = $request->report_type; // Optional filter parameter
            $perPage = $request->input('per_page', 10); // Default 10 items per page
            $page = $request->input('page', 1); // Default page 1
            
            // Validate pagination parameters
            $perPage = max(1, min(100, (int)$perPage)); // Between 1 and 100
            $page = max(1, (int)$page);
            
            // Define all supported report types
            $supportedTypes = ['incident_report', 'inspection_report', 'swms_report', 'whs_report', 'whsqe_report'];
            
            // If specific report type is requested, validate it
            if ($reportType && !in_array($reportType, $supportedTypes)) {
                return $this->message('Invalid report type. Supported types: ' . implode(', ', $supportedTypes), 422);
            }
            
            // Get user context for filtering
            if ($userTable === 'customer') {
                $customerId = auth()->user()->id;
                $workspaceId = auth()->user()->current_workspace_id;
            } elseif ($userTable === 'emp') {
                $customerId = auth()->user()->customer_id;
                $workspaceId = auth()->user()->workspace_id;
            } else {
                return $this->message('You do not have permission to access these records.', 403);
            }
            
            // If specific report type is requested, return paginated results for that type
            if ($reportType) {
                return $this->getSingleReportTypePaginated($reportType, $customerId, $workspaceId, $perPage, $page);
            }
            
            // Default: Return summary of all report types with counts only
            $totalCounts = [];
            
            foreach ($supportedTypes as $type) {
                $count = GeneratedPdfReport::where('report_type', $type)
                    ->where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->count();
                $totalCounts[$type] = $count;
            }
            
            $responseData = [
                'counts' => $totalCounts,
                'total_reports' => array_sum($totalCounts)
            ];
            
            return $this->success($responseData, 'All report types retrieved successfully');
            
        } catch (\Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'IncidentReportPdfFiles error: ' . $shortMessage,
                'report_id' => 0,
                'report_type' => $request->report_type ?? 'all',
                'error_type' => 'Exception error'
            ];
            storeReportsLogs($log);
            return $this->error('Error occurred while fetching records: ' . $shortMessage, 500);
        }
    }
    
    /**
     * Get PDF reports for a specific report type
     */
    private function getSingleReportType($reportType, $customerId, $workspaceId, $returnResponse = true)
    {
        try {
            // Get PDF reports for the specific type
            $query = GeneratedPdfReport::where('report_type', $reportType)
                ->where('customer_id', $customerId)
                ->where('workspace_id', $workspaceId);
            
            $pdfReports = $query->get();
            
            if ($pdfReports->isEmpty()) {
                $result = [
                    'status' => 'error',
                    'message' => 'No records found.',
                    'data' => ['reports' => [], 'count' => 0]
                ];
                
                if ($returnResponse) {
                    return $this->message('No records found.', 404);
                }
                return $result;
            }
            
            $reportIds = $pdfReports->pluck('report_id')->toArray();
            
            // Get titles based on report type
            switch ($reportType) {
                case 'incident_report':
                    $reports = IncidentReport::whereIn('id', $reportIds)
                        ->select('id', 'title', 'report_method')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                case 'inspection_report':
                    $reports = InspectionPlan::whereIn('id', $reportIds)
                        ->select('id', 'title', 'report_method')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                case 'swms_report':
                    $reports = Swms::whereIn('id', $reportIds)
                        ->select('id', 'title', 'report_method')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                case 'whs_report':
                    $reports = WhsReport::whereIn('id', $reportIds)
                        ->select('id', 'title', 'report_method')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                default:
                    $reports = collect();
                    break;
            }
            
            // Attach titles to PDF reports
            $pdfReports->transform(function ($report) use ($reports) {
                $reportRecord = $reports->get($report->report_id);
                $report->title = $reportRecord->title ?? 'N/A';
                $report->report_method = $reportRecord->report_method ?? 0;
                return $report;
            });
            
            $result = [
                'status' => 'success',
                'message' => 'Retrieve all records Successfully',
                'data' => [
                    'reports' => $pdfReports,
                    'count' => $pdfReports->count()
                ]
            ];
            
            if ($returnResponse) {
                return $this->withCount($pdfReports, 'Retrieve all records Successfully');
            }
            
            return $result;
            
        } catch (\Exception $e) {
            $result = [
                'status' => 'error',
                'message' => 'Error occurred while fetching ' . $reportType . ' records',
                'data' => ['reports' => [], 'count' => 0]
            ];
            
            if ($returnResponse) {
                return $this->error('Error occurred while fetching ' . $reportType . ' records', 500);
            }
            
            return $result;
        }
    }
    
    /**
     * Get paginated PDF reports for a specific report type
     */
    private function getSingleReportTypePaginated($reportType, $customerId, $workspaceId, $perPage, $page)
    {
        try {
            // Step 1: Get non-deleted report IDs for the specific type (except whsqe_report which has no del column)
            $reportIds = [];
            
            switch ($reportType) {
                case 'incident_report':
                    $reportIds = IncidentReport::where('customer_id', $customerId)
                        ->where('workspace_id', $workspaceId)
                        ->where('del', 0)
                        ->pluck('id')
                        ->toArray();
                    break;
                    
                case 'inspection_report':
                    $reportIds = InspectionPlan::where('customer_id', $customerId)
                        ->where('workspace_id', $workspaceId)
                        ->where('del', '0')
                        ->pluck('id')
                        ->toArray();
                    break;
                    
                case 'swms_report':
                    $reportIds = Swms::where('customer_id', $customerId)
                        ->where('workspace_id', $workspaceId)
                        ->where('del', '0')
                        ->pluck('id')
                        ->toArray();
                    break;
                    
                case 'whs_report':
                    $reportIds = WhsReport::where('customer_id', $customerId)
                        ->where('workspace_id', $workspaceId)
                        ->where('del', '0')
                        ->pluck('id')
                        ->toArray();
                    break;
                    
                case 'whsqe_report':
                    // whsqe_report has no del column, so get all reports
                    $reportIds = WhsqReport::where('customer_id', $customerId)
                        ->where('workspace_id', $workspaceId)
                        ->pluck('id')
                        ->toArray();
                    break;
                    
                default:
                    $reportIds = [];
                    break;
            }
            
            // Step 2: Get GeneratedPdfReport records that match the report IDs and type
            if (empty($reportIds)) {
                // No non-deleted reports found, return empty response
                $supportedTypes = ['incident_report', 'inspection_report', 'swms_report', 'whs_report', 'whsqe_report'];
                $totalCounts = [];
                
                foreach ($supportedTypes as $type) {
                    $totalCounts[$type] = $this->getReportTypeCount($type, $customerId, $workspaceId);
                }
                
                return $this->success([
                    'reports' => [],
                    'pagination' => [
                        'current_page' => $page,
                        'per_page' => $perPage,
                        'total' => 0,
                        'total_pages' => 0,
                        'has_more_pages' => false
                    ],
                    'counts' => $totalCounts,
                    'total_reports' => array_sum($totalCounts)
                ], 'No records found.');
            }
            
            // Get GeneratedPdfReport records for the filtered report IDs
            $query = GeneratedPdfReport::where('report_type', $reportType)
                ->where('customer_id', $customerId)
                ->where('workspace_id', $workspaceId)
                ->whereIn('report_id', $reportIds)
                ->orderBy('created_at', 'desc');
            
            // Get total count before pagination
            $totalCount = $query->count();
            
            // Apply pagination
            $offset = ($page - 1) * $perPage;
            $pdfReports = $query->skip($offset)->take($perPage)->get();
            
            // Calculate pagination metadata
            $totalPages = ceil($totalCount / $perPage);
            $hasMorePages = $page < $totalPages;
            
            // Get counts for all report types (filtered by del = 0 except whsqe_report)
            $supportedTypes = ['incident_report', 'inspection_report', 'swms_report', 'whs_report', 'whsqe_report'];
            $totalCounts = [];
            
            foreach ($supportedTypes as $type) {
                $totalCounts[$type] = $this->getReportTypeCount($type, $customerId, $workspaceId);
            }
             
            if ($pdfReports->isEmpty() && $page == 1) {
                return $this->success([
                    'reports' => [],
                    'pagination' => [
                        'current_page' => $page,
                        'per_page' => $perPage,
                        'total' => 0,
                        'total_pages' => 0,
                        'has_more_pages' => false
                    ],
                    'counts' => $totalCounts,
                    'total_reports' => array_sum($totalCounts)
                ], 'No records found.');
            }
            
            if ($pdfReports->isEmpty() && $page > 1) {
                return $this->message('Page not found. Total pages available: ' . $totalPages, 404);
            }
            
            $pdfReportIds = $pdfReports->pluck('report_id')->toArray();
            
            // Step 3: Get titles based on report type
            switch ($reportType) {
                case 'incident_report':
                    $reports = IncidentReport::whereIn('id', $pdfReportIds)
                        ->select('id', 'title', 'report_method')
                        ->latest('id')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                case 'inspection_report':
                    $reports = InspectionPlan::whereIn('id', $pdfReportIds)
                        ->select('id', 'title', 'report_method')
                        ->latest('id')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                case 'swms_report':
                    $reports = Swms::whereIn('id', $pdfReportIds)
                        ->select('id', 'title', 'report_method')
                        ->latest('id')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                case 'whs_report':
                    $reports = WhsReport::whereIn('id', $pdfReportIds)
                        ->select('id', 'title', 'report_method')
                        ->latest('id')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                case 'whsqe_report':
                    $reports = WhsqReport::whereIn('id', $pdfReportIds)
                        ->select('id', 'document_title','report_method')
                        ->latest('id')
                        ->get()
                        ->keyBy('id');
                    break;
                    
                default:
                    $reports = collect();
                    break;
            }
            
            // Attach titles to PDF reports
            $pdfReports->transform(function ($report) use ($reports, $reportType) {
                $reportRecord = $reports->get($report->report_id);
                if ($reportType === 'whsqe_report') {
                    $report->title = $reportRecord->document_title ?? 'N/A';
                } else {
                    $report->title = $reportRecord->title ?? 'N/A';
                }
                $report->report_method = $reportRecord->report_method ?? 0;
                return $report;
            });
            
            $responseData = [
                'reports' => $pdfReports->toArray(),
                'pagination' => [
                    'current_page' => $page,
                    'per_page' => $perPage,
                    'total' => $totalCount,
                    'total_pages' => $totalPages,
                    'has_more_pages' => $hasMorePages,
                    'from' => $offset + 1,
                    'to' => min($offset + $perPage, $totalCount)
                ],
                'counts' => $totalCounts,
                'total_reports' => array_sum($totalCounts)
            ];
            
            return $this->success($responseData, 'Records retrieved successfully');
            
        } catch (\Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'getSingleReportTypePaginated error: ' . $shortMessage,
                'report_id' => 0,
                'report_type' => $reportType,
                'error_type' => 'Exception error'
            ];
            storeReportsLogs($log);
            return $this->error('Error occurred while fetching ' . $reportType . ' records: ' . $shortMessage, 500);
        }
    }
    
    private function getReportTypeCount($reportType, $customerId, $workspaceId)
    {
        $reportIds = [];
        
        switch ($reportType) {
            case 'incident_report':
                $reportIds = IncidentReport::where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('del', 0)
                    ->pluck('id')
                    ->toArray();
                break;
                
            case 'inspection_report':
                $reportIds = InspectionPlan::where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('del', '0')
                    ->pluck('id')
                    ->toArray();
                break;
                
            case 'swms_report':
                $reportIds = Swms::where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('del', '0')
                    ->pluck('id')
                    ->toArray();
                break;
                
            case 'whs_report':
                $reportIds = WhsReport::where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->where('del', '0')
                    ->pluck('id')
                    ->toArray();
                break;
                
            case 'whsqe_report':
                // whsqe_report has no del column, so get all reports
                $reportIds = WhsqReport::where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId)
                    ->pluck('id')
                    ->toArray();
                break;
        }
        
        if (empty($reportIds)) {
            return 0;
        }
        
        return GeneratedPdfReport::where('report_type', $reportType)
            ->where('customer_id', $customerId)
            ->where('workspace_id', $workspaceId)
            ->whereIn('report_id', $reportIds)
            ->count();
    }
    
    public function downloadPdfFile($filename)
    {
        $path = public_path("Files_manager/inspection_reports/");

        if (!file_exists($path . $filename)) {
            $html = '<html>
            <head>
                <style>
                    body {
                        font-family: Arial, sans-serif;
                        text-align: center;
                        padding: 50px;
                        background-color: #f8f9fa;
                    }
                    .container {
                        max-width: 600px;
                        margin: 0 auto;
                        border: 1px solid #ddd;
                        padding: 20px;
                        border-radius: 5px;
                        background-color: #fff;
                    }
                    h1 {
                        color: #dc3545;
                    }
                    p {
                        color: #333;
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <h1>File Not Found</h1>
                    <p>The file is not found or has been deleted.</p>
                </div>
            </body>
        </html>';

            return response($html, 404)
                ->header('Content-Type', 'text/html');
        }

        return response()->download($path . $filename);
    }


    public function incidentReportDownloadPdfRegenerate($id)
    {
        if (!$id) {
            $log = [
                'employee_id' => auth()->user()->id,
                'message' => 'Report ID is required ',
                'report_id' => 0,
                'report_type' => 'incident_report',
                'error_type' => 'Not found error'

            ];
            storeReportsLogs($log);
            return $this->message('Report ID is required', 422);
        }
        // try {
            $userTable = $this->getUserTable(); // Get user type (customer or emp)
            $data_classifications = DB::table('incident_reports')
                ->leftJoin('incident_classification_reports', 'incident_reports.id', '=', 'incident_classification_reports.incident_report_id')
                ->leftJoin('incident_injury_classifications', 'incident_classification_reports.injury_classification_id', '=', 'incident_injury_classifications.id')
                ->where('incident_reports.id', $id)
                ->select(
                    'incident_injury_classifications.title as incident_injury_classifications_title',
                )
                ->get();
            $incident_involved = DB::table('incident_involved_person_details')
                ->leftJoin('incident_reports', 'incident_involved_person_details.incident_report_id', '=', 'incident_reports.id')
                ->leftJoin('emp_personal_details as injured_employee', 'incident_involved_person_details.employee_id', '=', 'injured_employee.emp_id')
                ->leftJoin('emp_types as employee_types', 'incident_involved_person_details.employment_type', '=', 'employee_types.id')
                ->leftJoin('incident_notified_tos', 'incident_reports.id', '=', 'incident_notified_tos.incident_report_id')
                ->leftJoin(DB::raw('(SELECT * FROM incident_employer_details) as incident_employer_details'), function ($join) {
                    $join->on('incident_involved_person_details.employee_id', '=', 'incident_employer_details.employer_id')
                        ->whereColumn('incident_involved_person_details.incident_report_id', '=', 'incident_employer_details.incident_report_id');
                })
                ->leftJoin('emp_personal_details as supervisor', 'incident_employer_details.supervisor', '=', 'supervisor.emp_id')  // Adjusted join to get supervisor details from incident_employer_details
                ->leftJoin('incident_involved_person_trainings', 'incident_involved_person_details.employee_id', '=', 'incident_involved_person_trainings.incident_involved_person_id')
                ->leftJoin('trainings', 'incident_involved_person_trainings.training_id', '=', 'trainings.id')
                ->select(
                    'incident_involved_person_details.*',
                    'injured_employee.first_name as injured_employee_first_name',
                    'injured_employee.middle_name as injured_employee_middle_name',
                    'injured_employee.last_name as injured_employee_last_name',
                    'supervisor.first_name as supervisor_first_name',  // Selecting supervisor's first name
                    'supervisor.last_name as supervisor_last_name',  // Selecting supervisor's last name
                    'employee_types.title as employee_types_title',
                    'incident_notified_tos.reference_number as incident_notified_tos_reference_number',
                    'incident_notified_tos.date as incident_notified_tos_date',
                    'incident_notified_tos.time as incident_notified_tos_time',
                    'incident_employer_details.is_employer_worker as incident_employer_details_is_employer_worker',
                    // 'incident_involved_person_trainings.other_note as training_other_note',
                    DB::raw('(
                    SELECT GROUP_CONCAT(DISTINCT training_id)
                    FROM incident_involved_person_trainings
                    WHERE incident_involved_person_id = incident_involved_person_details.employee_id
                    AND incident_report_id = incident_involved_person_details.incident_report_id
                ) as training_ids'),
                    DB::raw('(
                    SELECT GROUP_CONCAT(DISTINCT t.title SEPARATOR ", ")
                    FROM trainings t
                    WHERE FIND_IN_SET(t.id, (
                        SELECT GROUP_CONCAT(training_id)
                        FROM incident_involved_person_trainings
                        WHERE incident_involved_person_id = incident_involved_person_details.employee_id
                        AND incident_report_id = incident_involved_person_details.incident_report_id
                    ))
                ) as employee_trainings_title')
                )
                ->where('incident_involved_person_details.incident_report_id', $id)
                ->distinct() // Add distinct to ensure no duplicates
                ->get()
                ->toArray();



            foreach ($incident_involved as $key => $person) {
                $incident_employee_injury_types = DB::table('incident_employee_injury_types')
                    ->join('incident_injury_types', 'incident_employee_injury_types.value', '=', 'incident_injury_types.id')
                    ->select(
                        'incident_employee_injury_types.*',
                        'incident_injury_types.title as value'
                    )
                    ->where('incident_report_id', $person->incident_report_id)
                    ->where('employer_id', $person->employee_id)
                    ->get();

                // Convert object to an array before assigning new values
                $incident_involved[$key] = (array) $person;
                $incident_involved[$key]['incident_employee_injury_types'] = $incident_employee_injury_types;
            }

            $incident_employer_details = DB::table('incident_employer_details')
                ->leftJoin('emp_personal_details as incident_employer_injured_employee', 'incident_employer_details.employer_id', '=', 'incident_employer_injured_employee.emp_id')
                ->select(

                    'incident_employer_injured_employee.first_name as incident_employer_injured_first_name ',
                    'incident_employer_injured_employee.last_name as incident_employer_injured_last_name ',
                    'incident_employer_details.is_employer_worker as incident_employer_details_is_employer_worker ',

                )
                ->where('incident_employer_details.incident_report_id', $id)
                ->get();
            $incident_involved_person_details = [
                'incident_involved' => $incident_involved,
                'incident_employer_details' => $incident_employer_details
            ];

            $data = DB::table('incident_reports')
                ->leftJoin('sites', 'incident_reports.site_id', '=', 'sites.id')
                ->leftJoin('incident_reported_tos', 'incident_reports.id', '=', 'incident_reported_tos.incident_report_id')
                ->leftJoin('incident_reported_bys', 'incident_reports.id', '=', 'incident_reported_bys.incident_report_id')
                ->leftJoin('incident_classification_reports', 'incident_reports.id', '=', 'incident_classification_reports.incident_report_id')
                ->leftJoin('incident_injury_classifications', 'incident_classification_reports.injury_classification_id', '=', 'incident_injury_classifications.id')
                ->leftJoin('incident_notified_tos', 'incident_reports.id', '=', 'incident_notified_tos.incident_report_id')
                ->leftJoin('incident_involved_person_details', 'incident_reports.id', '=', 'incident_involved_person_details.incident_report_id')
                ->leftJoin('incident_involved_person_trainings', 'incident_reports.id', '=', 'incident_involved_person_trainings.incident_report_id')
                ->leftJoin('incident_employee_injury_types', 'incident_reports.id', '=', 'incident_employee_injury_types.incident_report_id')
                ->leftJoin('incident_employer_details', 'incident_reports.id', '=', 'incident_employer_details.incident_report_id')

                ->leftJoin('incident_report_question_answers', 'incident_reports.id', '=', 'incident_report_question_answers.incident_report_id')
                ->leftJoin('incident_report_metas', 'incident_reports.id', '=', 'incident_report_metas.incident_report_id')
                ->leftJoin('incident_injury_managements', 'incident_reports.id', '=', 'incident_injury_managements.incident_report_id')
                ->leftJoin('incident_final_classifications', 'incident_reports.id', '=', 'incident_final_classifications.incident_report_id')
                ->leftJoin('incident_signoffs', 'incident_reports.id', '=', 'incident_signoffs.incident_report_id')
                ->leftJoin('incident_risk_category_details', 'incident_reports.id', '=', 'incident_risk_category_details.incident_report_id')
                ->leftJoin('incident_risk_categories', 'incident_risk_category_details.incident_risk_category_id', '=', 'incident_risk_categories.id')
                ->leftJoin('incident_witness', 'incident_reports.id', '=', 'incident_witness.incident_report_id')
                ->leftJoin('incident_documents', 'incident_reports.id', '=', 'incident_documents.incident_report_id')

                ->leftJoin('projects', 'incident_reports.project_id', '=', 'projects.id')
                ->leftJoin('incident_report_notifiable_classifications', 'incident_reports.id', '=', 'incident_report_notifiable_classifications.incident_report_id')
                ->leftJoin('incident_notifiable_classifications', 'incident_report_notifiable_classifications.notifiable_classification_id', '=', 'incident_notifiable_classifications.id')
                ->leftJoin('emp_personal_details as reported_to_details', 'incident_reported_tos.reported_to', '=', 'reported_to_details.emp_id')
                ->leftJoin('emp_personal_details as report_compiled_by_details', 'incident_reports.report_compiled_by', '=', 'report_compiled_by_details.emp_id')
                ->leftJoin('emp_personal_details as reported_by_details', 'incident_reported_bys.reported_by', '=', 'reported_by_details.emp_id')
                ->leftJoin('emp_personal_details as main_details', 'incident_reports.authorised_by', '=', 'main_details.emp_id')
                ->leftJoin('emp_personal_details as injured_employee', 'incident_involved_person_details.employee_id', '=', 'injured_employee.emp_id')
                ->leftJoin('emp_types as employee_types', 'incident_involved_person_details.employment_type', '=', 'employee_types.id')
                ->leftJoin('trainings as employee_trainings', 'incident_involved_person_trainings.training_id', '=', 'employee_trainings.id')
                ->leftJoin('incident_report_questions as incident_report_questions', 'incident_report_question_answers.question_id', '=', 'incident_report_questions.id')
                ->leftJoin('roles as roles_position_tos', 'incident_reported_tos.position', '=', 'roles_position_tos.id')
                ->leftJoin('roles as roles_position_bys', 'incident_reported_bys.position', '=', 'roles_position_bys.id')
                ->leftJoin('emp_personal_details as emp_personal_details_reported_to', 'incident_reported_tos.reported_to', '=', 'emp_personal_details_reported_to.emp_id')
                ->leftJoin('emp_personal_details as emp_personal_supervisor_detail', 'sites.supervisor_id', '=', 'emp_personal_supervisor_detail.emp_id')
                ->leftJoin('emp_personal_details as emp_personal_forman_detail', 'sites.forman_id', '=', 'emp_personal_forman_detail.emp_id')
                ->leftJoin('emp_personal_details as emp_personal_forman_notified_by_whom', 'incident_final_classifications.notified_by_whom', '=', 'emp_personal_forman_notified_by_whom.emp_id')
                ->leftJoin('emp_company_details as report_compiled_by_company', 'incident_reports.report_compiled_by', '=', 'report_compiled_by_company.id')
                ->leftJoin('roles as roles_position_report_compiled_by', 'report_compiled_by_company.access_role', '=', 'roles_position_report_compiled_by.code')


                ->where('incident_reports.id', $id)
                ->select(
                    'incident_reports.*',
                    'sites.title as site_title',
                    'sites.supervisor_id as site_supervisor_id',
                    'projects.id as project_id',
                    'projects.title as project_title',

                    'main_details.first_name as authorized_first_name',
                    'main_details.last_name as authorized_last_name',
                    'incident_reports.plant_name as plant_id',
                    'incident_reported_tos.id as incident_report_to_id',
                    'emp_personal_details_reported_to.first_name as roles_reported_to_first_name',
                    'emp_personal_details_reported_to.last_name as roles_reported_to_last_name',
                    'incident_reported_tos.reported_to as roles_reported_to_last_name_reported_to',
                    'incident_reported_tos.incident_report_id as incident_report_id',
                    'incident_reported_tos.reported_to as incident_report_reported_to',
                    'incident_reported_tos.company_name as incident_report_to_company_name',
                    'incident_reported_tos.position as incident_report_to_position',
                    'incident_reported_tos.contact_number as incident_report_to_contact_number',
                    'reported_to_details.first_name as reported_to_first_name',
                    'reported_to_details.last_name as reported_to_last_name',
                    'roles_position_tos.title as reported_tos_title',
                    'report_compiled_by_details.first_name as report_compiled_by_first_name',
                    'report_compiled_by_details.last_name as report_compiled_by_last_name',
                    'roles_position_report_compiled_by.title as report_compiled_by_role_title', // Adding role title for compiled by

                    'incident_reported_bys.id as incident_report_bys_id',
                    'incident_reported_bys.incident_report_id as incident_report_bys_incident_report_id',
                    'incident_reported_bys.reported_by as incident_report_bys_reported_by',
                    'incident_reported_bys.company_name as incident_report_bys_company_name',
                    'incident_reported_bys.position as incident_report_bys_position',
                    'incident_reported_bys.contact_number as incident_report_bys_contact_number',
                    'reported_by_details.first_name as reported_by_first_name',
                    'reported_by_details.middle_name as reported_by_middle_name',
                    'reported_by_details.last_name as reported_by_last_name',
                    'roles_position_bys.title as reported_bys_title',

                    'incident_classification_reports.id as classification_report_id',
                    'incident_classification_reports.injury_classification_id as classification_injury_classification_id',
                    'incident_classification_reports.details as classification_details',

                    'incident_injury_classifications.title as injury_classification_title',
                    'incident_injury_classifications.description as injury_classification_description',

                    'incident_notifiable_classifications.id as notifiable_classification_id',
                    'incident_notifiable_classifications.title as notifiable_classification_title',
                    'incident_notifiable_classifications.description as notifiable_classification_description',

                    'incident_notified_tos.id as incident_notified_tos_id',
                    'incident_notified_tos.reference_number as incident_notified_tos_reference_number',
                    'incident_notified_tos.date as incident_notified_tos_date',
                    'incident_notified_tos.time as incident_notified_tos_time',
                    'incident_notified_tos.contact_name as incident_notified_tos_contact_name',
                    'incident_notified_tos.ohs_regulator as incident_notified_tos_ohs_regulator',

                    'injured_employee.first_name as employee_incident_tos_first_name',
                    'incident_involved_person_details.surname as incident_involved_person_details_surname',
                    'incident_involved_person_details.age as incident_involved_person_details_age',
                    'incident_involved_person_details.occupation as incident_involved_person_details_occupation',
                    'incident_involved_person_details.language as incident_involved_person_details_language',
                    'incident_involved_person_details.dob as incident_involved_person_details_dob',
                    'incident_involved_person_details.experience_years as incident_involved_person_details_experience_years',
                    'incident_involved_person_details.experience_months as incident_involved_person_details_experience_months',
                    'incident_involved_person_details.gender as incident_involved_person_details_gender',
                    'incident_involved_person_details.employee_type as incident_involved_person_details_employee_type',
                    'employee_types.title as employee_types_title',
                    'employee_trainings.title as employee_trainings_title',
                    'incident_employee_injury_types.option as incident_employee_injury_types_options',
                    'incident_employer_details.employer_name as incident_employer_details_employer_name',

                    'incident_employer_details.is_employer_worker as incident_employer_details_is_employer_worker',
                    'incident_involved_person_details.contact_number as incident_involved_person_contact_number',
                    'emp_personal_supervisor_detail.first_name as emp_personal_supervisor_detail_f_name',
                    'emp_personal_supervisor_detail.last_name as emp_personal_supervisor_detail_last_name',
                    'emp_personal_forman_detail.first_name as emp_personal_forman_detail_f_name',
                    'emp_personal_forman_detail.last_name as emp_personal_forman_detail_last_name',

                    'incident_report_questions.question as incident_report_question_question',
                    'incident_report_question_answers.answer as incident_report_question_answer',
                    'incident_report_metas.shift_type as incident_report_employee_shift_type',
                    'incident_report_metas.shift_time as incident_report_employee_shift_time',
                    'incident_report_metas.equipment_type as incident_report_employee_equipment_type',
                    'incident_report_metas.registration_number as incident_report_employee_registration_number',
                    'incident_report_metas.damage as incident_report_employee_damage',
                    'incident_report_metas.cost as incident_report_employee_cost',

                    'incident_injury_managements.date as incident_injury_managements_date',
                    'incident_injury_managements.return_to_work as return_to_work',
                    'incident_injury_managements.time as incident_injury_managements_time',
                    'incident_injury_managements.representative_name as incident_injury_managements_representative_name',
                    'incident_injury_managements.injured_names as incident_injury_managements_injured_names',
                    'incident_injury_managements.is_first_aid as incident_injury_managements_is_first_aid',
                    'incident_injury_managements.is_referred as incident_injury_managements_is_referred',
                    'incident_injury_managements.is_first_aid as incident_injury_managements_is_first_aid',
                    DB::raw('CASE WHEN incident_injury_managements.is_doctor = 1 THEN "Doctor" ELSE "Clinic / Hospital" END as incident_injury_managements_is_doctor'),
                    DB::raw('CASE WHEN incident_injury_managements.is_admit = 1 THEN "Outpatient" ELSE "Inpatient" END as incident_injury_managements_is_admit'),
                    DB::raw('CASE WHEN incident_reports.lti_or_rwi = 1 THEN "LTI" ELSE "RWI" END as lti_or_rwi'),
                    DB::raw('CASE WHEN incident_injury_managements.is_first_aid = 1 THEN "First Aid & Return to Work" ELSE "Medical - Referred to" END as incident_injury_managements_is_first_aid'),
                    DB::raw('CASE WHEN incident_reports.involved_persons = 1 THEN "Yes (If Yes, Then Complete An Incident Investigation Report For Each Injured / Involved Person)" ELSE "NO" END as involved_persons'),
                    DB::raw('CASE WHEN incident_final_classifications.final_incident_name = 1 THEN "Property" ELSE "Plant" END as final_incident_name'),
                    'incident_injury_managements.is_clinic as incident_injury_managements_is_clinic',
                    'incident_injury_managements.is_doctor_details as incident_injury_managements_is_doctor_details',
                    'incident_injury_managements.is_hospital_details as incident_injury_managements_is_hospital_details',
                    'incident_injury_managements.doctor_name as incident_injury_managements_doctor_name',
                    'incident_injury_managements.doctor_number as incident_injury_managements_doctor_number',
                    'incident_injury_managements.doctor_address as incident_injury_managements_doctor_address',
                    'incident_injury_managements.hospital_name as incident_injury_managements_hospital_name',
                    'incident_injury_managements.hospital_number as incident_injury_managements_hospital_number',
                    'incident_injury_managements.hospital_address as incident_injury_managements_hospital_address',
                    'incident_injury_managements.is_recurrence_injury as incident_injury_managements_is_recurrence_injury',
                    'incident_injury_managements.previous_injury_date as incident_injury_managements_previous_injury_date',
                    'incident_injury_managements.previous_report_number as incident_injury_managements_previous_report_number',
                    'incident_final_classifications.final_incident_details as final_incident_details_incident_details',
                    'incident_final_classifications.is_rehabilitation as final_incident_details_is_rehabilitation',
                    'incident_final_classifications.return_to_duty_date as final_incident_details_return_to_duty_date',
                    'incident_final_classifications.rtw_date as final_incident_details_rtw_date',
                    'incident_final_classifications.total_lost_days as final_incident_details_total_lost_days',
                    'incident_final_classifications.is_worker_notified as final_incident_details_is_worker_notified',
                    'incident_final_classifications.notified_by_whom as final_incident_details_notified_by_whom',
                    'emp_personal_forman_notified_by_whom.first_name as emp_personal_forman_notified_by_whom_f_name',
                    'emp_personal_forman_notified_by_whom.last_name as emp_personal_forman_notified_by_whom_l_name',
                    'incident_final_classifications.date as final_incident_details_date',
                    'incident_final_classifications.time as final_incident_details_time',
                    'incident_final_classifications.details as final_incident_details_details',
                    'incident_risk_category_details.incident_risk_category_id as incident_risk_category_details_incident_risk_category_id',
                    'incident_risk_categories.title as incident_risk_category_details_incident_risk_category_title',
                    'incident_risk_category_details.details as incident_risk_category_details_details',
                )
                ->first();
            unset($data->project_name);
            unset($data->project_number);
            unset($data->project_id);
            unset($data->plant_name);
            $incident_witnesses = DB::table('incident_witness')
                ->where('incident_report_id', $id)
                ->select(
                    'name as witness_name',
                    'date as witness_date',
                    'time as witness_time',
                    'statement_number as witness_statement_number'
                )
                ->get()
                ->map(function ($item) {
                    return (array) $item;
                })
                ->toArray();
            $incident_documents = DB::table('incident_documents')
                ->where('incident_report_id', $id)
                ->select(
                    'id',
                    'title as document_title',
                    'number as document_number',
                )
                ->get()
                ->map(function ($item) {
                    return (array) $item;
                })
                ->toArray();
            $supervisorIds = explode(',', $data->site_supervisor_id);
            $supervisors = DB::table('emp_personal_details')->whereIn('emp_id', $supervisorIds)
                ->select(
                    'emp_personal_details.first_name as emp_personal_supervisor_detail_f_name',
                    'emp_personal_details.last_name as emp_personal_supervisor_detail_last_name'
                )
                ->get();
            $questionsAndAnswers = DB::table('incident_report_question_answers')
                ->join('incident_report_questions', 'incident_report_question_answers.question_id', '=', 'incident_report_questions.id')
                ->where('incident_report_question_answers.incident_report_id', $id)
                ->select(
                    'incident_report_questions.question as question',
                    'incident_report_question_answers.answer as answer'
                )
                ->get();
            // $incident_signoffs = DB::table('incident_reports')
            //     ->join('incident_signoffs', 'incident_reports.id', '=', 'incident_signoffs.incident_report_id')
            //     ->leftJoin('emp_personal_details', 'incident_signoffs.emp_id', '=', 'emp_personal_details.emp_id')
            //     ->where('incident_reports.id', $id)
            //     ->select(
            //         'emp_personal_details.first_name as emp_first_name',
            //         'emp_personal_details.middle_name as emp_middle_name',
            //         'emp_personal_details.last_name as emp_last_name',
            //         'incident_signoffs.signature',
            //         'incident_signoffs.date as signoff_date',
            //         'incident_signoffs.time as signoff_time',
            //         'incident_signoffs.role_code'
            //     )
            //     ->get()
            //     ->map(function ($item) {
            //         // First convert to array
            //         $itemArray = (array) $item;

            //         // Now work with the array
            //         switch ($itemArray['role_code']) {
            //             case 'fm':
            //                 $itemArray['role_code'] = 'Foreman';
            //                 break;
            //             case 'sm':
            //                 $itemArray['role_code'] = 'Site Manager';
            //                 break;
            //             case 'dir':
            //                 $itemArray['role_code'] = 'Director';
            //                 break;
            //             case 'sso':
            //                 $itemArray['role_code'] = 'Site Safety Officer';
            //                 break;
            //             default:
            //                 // Keep original code if no match found
            //                 break;
            //         }
            //         return $itemArray;
            //     })
            //     ->toArray();
            //
            $report_images =  DB::table('incident_images')
                ->where('incident_report_id', $id)
                ->get();


            if ($userTable === "customer") {
                $customerId = auth()->id();
                $workspaceId = auth()->user()->current_workspace_id;
            } elseif ($userTable === "emp") {
                $customerId = auth()->user()->customer_id;
                $workspaceId = auth()->user()->workspace_id;
            }
            if($data->report_method == 1){
                $uploaded_report=GeneratedPdfReport::where('report_type', 'incident_report')->where('report_id', $id)->first();
            }
            else{
            GeneratedPdfReport::updateOrCreate(
                [
                    'report_id' => $id,
                    'report_type' => 'incident_report'
                ],
                [
                    'report_id' => $id,
                    'path' => null,
                    'report_type' => 'incident_report',
                    'customer_id' => $customerId,
                    'workspace_id' => $workspaceId
                ]
            );
            $uploaded_report=null;
            }
            // Format issue_date and revision_date to date-only format
            if ($data && isset($data->issue_date) && $data->issue_date) {
                try {
                    $carbonDate = \Carbon\Carbon::parse($data->issue_date);
                    $data->issue_date = $carbonDate->format('d-m-Y');
                } catch (\Exception $e) {
                    // Keep original if parsing fails
                }
            }
            
            if ($data && isset($data->revision_date) && $data->revision_date) {
                try {
                    $carbonDate = \Carbon\Carbon::parse($data->revision_date);
                    $data->revision_date = $carbonDate->format('d-m-Y');
                } catch (\Exception $e) {
                    // Keep original if parsing fails
                }
            }
            $incident_signoffs = DB::table('incident_signoffs')
                ->where('incident_report_id', $id)
                ->select('emp_id', 'signature', 'date', 'time', 'role_code')
                ->get();
            $incident_signoffs_array = [];
            foreach ($incident_signoffs as $signoff) {
                $emp_company = EmpCompanyDetails::where('id', $signoff->emp_id)->first();
                $emp_personal_details = EmpPersonalDetails::where('emp_id', $signoff->emp_id)->first();
                $role_title = null;
                if ($emp_company && $emp_company->access_role) {
                    $role_title = Role::where('code', $emp_company->access_role)->first();
                }
                $incident_signoffs_array[] = [
                    'employee_name' => ($emp_personal_details ? ($emp_personal_details->first_name ?? '') . ' ' . 
                    ($emp_personal_details->middle_name ?? '') . ' ' . 
                    ($emp_personal_details->last_name ?? '') : 'Unknown Employee'),
                    'role_title' => $role_title ? $role_title->title : null,
                    'signatures' => $signoff->signature,
                    'inductance_date' => $signoff->date,
                    'inductance_time' => $signoff->time,
                ];
            }
            $data = [
                'incident_report_data' => $data,
                'questionsAndAnswers' => $questionsAndAnswers,
                'incident_signoffs' => $incident_signoffs_array,
                'incident_witnesses' => $incident_witnesses,
                'incident_documents' => $incident_documents,
                'initail_injury_classifications' => $data_classifications,
                'report_images' => $report_images,
                'supervisors' => $supervisors,
                'incident_involved_person_details' => $incident_involved_person_details,
                'uploaded_report' => $uploaded_report,
            ];


            // Return all the data in the response
            return $this->success($data, 'Incident Report Data Retrieved Successfully.');
        // } catch (\Exception $e) {
        //     $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
        //     $log = [
        //         'employee_id' => auth()->user()->id,
        //         'message' => 'Download report id' . $id . ' error ' .   $shortMessage,
        //         'report_id' =>  $id,
        //         'report_type' => 'incident_report',
        //         'error_type' => 'Exception error'

        //     ];
        //     storeReportsLogs($log);
        //     return $this->error($shortMessage);
        // }
    }
    public function incidentReportViewSignature(Request $request, $id)
    {
        $user = auth()->user();
        $userTable = $this->getUserTable();

        // Define conditions based on user type
        $customerCondition = function ($query) use ($user) {
            return $query->where([
                ['customer_id', $user->id],
                ['workspace_id', $user->current_workspace_id]
            ]);
        };

        $employeeCondition = function ($query) use ($user) {
            return $query->where([
                ['customer_id', $user->customer_id],
                ['workspace_id', $user->workspace_id]
            ]);
        };

        // First, get the incident report to check authorized_by value
        $incidentReportQuery = IncidentReport::where('id', $id)
            ->when($userTable === 'customer', $customerCondition)
            ->when($userTable === 'emp', $employeeCondition);

        // Check if authorized_by is 0 or not
        $tempIncidentReport = $incidentReportQuery->first(['authorised_by']);

        if (!$tempIncidentReport) {
            return $this->error('Incident Report Not Found', 404);
        }

        // Now fetch the complete incident report with appropriate relationships
        if ($tempIncidentReport->authorised_by == 0) {
            // Use customer relationship when authorized_by is 0
            $incidentReport = IncidentReport::where('id', $id)
                ->when($userTable === 'customer', $customerCondition)
                ->when($userTable === 'emp', $employeeCondition)
                ->whereHas('customer', function ($query) {
                    return $query->where('del', 0);
                })
                ->with([
                    'authorisedByCompany:id,access_role,customer_id,workspace_id',
                    'customer:id,name' // Only load needed fields
                ])
                ->first();
        } else {
            // Use authorisedBy relationship when authorized_by is not 0
            $incidentReport = IncidentReport::where('id', $id)
                ->when($userTable === 'customer', $customerCondition)
                ->when($userTable === 'emp', $employeeCondition)
                ->whereHas('authorisedByCompany', function ($query) use ($userTable, $customerCondition, $employeeCondition) {
                    $query->where([['status', 1], ['approved', 1], ['compeleted', 1]]);
                })
                ->whereHas('authorisedBy', function ($query) {
                    return $query->where('del', 0);
                })
                ->with([
                    'authorisedByCompany:id,access_role,customer_id,workspace_id',
                    'authorisedBy:emp_id,first_name,last_name'
                ])
                ->first();
        }

        if (!$incidentReport) {
            return $this->error('Incident Report Not Found', 404);
        }

        // Normalize the authorized_by data structure
        if ($incidentReport->authorised_by == 0 && $incidentReport->customer) {
            // Convert customer data to match employee structure
            $authorizedBy = [
                'emp_id' => $incidentReport->customer->id,
                'first_name' => $incidentReport->customer->name,

            ];

            // Set the normalized authorized_by and remove customer from response
            $incidentReport->setAttribute('authorized_by', (object) $authorizedBy);
            $incidentReport->unsetRelation('customer');
        } else if ($incidentReport->authorisedBy) {
            // Employee data is already in correct format, just rename the key
            $incidentReport->setAttribute('authorized_by', $incidentReport->authorisedBy);
            $incidentReport->unsetRelation('authorisedBy');
        }

        // Fetch incident signoffs
        $incidentSignoffs = IncidentSignoff::where('incident_report_id', $id)
            ->whereHas('employee', function ($query) {
                return $query->where('emp_personal_details.del', 0);
            })
            ->whereHas('companyDetails', function ($query) use ($userTable, $customerCondition, $employeeCondition) {
                $query->where([['status', 1], ['approved', 1], ['compeleted', 1]]);
                if ($userTable === 'customer') {
                    $customerCondition($query);
                } elseif ($userTable === 'emp') {
                    $employeeCondition($query);
                }
            })
            ->with([
                'employee:emp_id,first_name,middle_name,last_name',
                'companyDetails:id,status,approved,compeleted'  // Removed 'user_type' as it doesn't exist
            ])
            ->get();

        // Convert to collection for easier manipulation
        $incidentSignoffCollection = collect($incidentSignoffs);

        // Check if authorised_by employee is already in the signoff data
        $authorisedByInSignoffs = $incidentSignoffCollection->contains('emp_id', $incidentReport->authorised_by);

        // If authorised_by is not in signoffs table and not 0 (customer), add them with null signature
        if (!$authorisedByInSignoffs && $incidentReport->authorised_by && $incidentReport->authorised_by != 0) {
            // Fetch authorised_by employee details
            $authorisedByDetails = DB::table('emp_personal_details')
                ->leftJoin('emp_company_details', 'emp_personal_details.emp_id', '=', 'emp_company_details.id')
                ->leftJoin('roles', 'emp_company_details.access_role', '=', 'roles.code')
                ->where('emp_personal_details.emp_id', $incidentReport->authorised_by)
                ->where('emp_personal_details.del', '0')
                ->where('emp_company_details.status', '1')
                ->where('emp_company_details.approved', '1')
                ->where('emp_company_details.compeleted', '1')
                ->where('emp_company_details.customer_id', $incidentReport->customer_id)
                ->where('emp_company_details.workspace_id', $incidentReport->workspace_id)
                ->where('roles.del', '0')
                ->select(
                    'emp_personal_details.emp_id',
                    'emp_personal_details.first_name',
                    'emp_personal_details.middle_name',
                    'emp_personal_details.last_name',
                    'emp_company_details.access_role',
                    'roles.title as role_title'
                )->first();

            if ($authorisedByDetails) {
                // Create complete array structure for authorised_by to match existing signoff format
                $authorisedBySignoffArray = [
                    'id' => null,
                    'incident_report_id' => $incidentReport->id,
                    'role_code' => $authorisedByDetails->access_role,
                    'emp_id' => $incidentReport->authorised_by,
                    'name' => trim(($authorisedByDetails->first_name ?? '') . ' ' . 
                             ($authorisedByDetails->middle_name ?? '') . ' ' . 
                             ($authorisedByDetails->last_name ?? '')),
                    'signature' => null, // Null indicates signature is required
                    'date' => $incidentReport->issue_date,
                    'created_at' => null,
                    'updated_at' => null,
                    'role_title' => $authorisedByDetails->role_title,
                    'employee' => [
                        'emp_id' => (string) $authorisedByDetails->emp_id,
                        'first_name' => $authorisedByDetails->first_name,
                        'middle_name' => $authorisedByDetails->middle_name,
                        'last_name' => $authorisedByDetails->last_name,
                        'laravel_through_key' => $authorisedByDetails->emp_id
                    ],
                    'company_details' => [
                        'id' => $incidentReport->authorised_by,
                        'status' => '1',
                        'approved' => '1',
                        'compeleted' => '1'
                    ]
                ];

                // Add to signoff collection
                $incidentSignoffCollection->push((object) $authorisedBySignoffArray);
            }
        }

        // Add role information to each signoff (only for Eloquent models)
        foreach ($incidentSignoffCollection as $signoff) {
            // Check if this is an Eloquent model (has getAttribute method) and doesn't have role_title
            if (method_exists($signoff, 'getAttribute') && $signoff->role_code && !$signoff->getAttribute('role_title')) {
                // Get role title based on role_code and customer/workspace context
                $role = Role::where('code', $signoff->role_code)
                    ->where('del', '0')
                    ->first();
                
                $signoff->setAttribute('role_title', $role ? $role->title : null);
            } else if (method_exists($signoff, 'getAttribute') && !$signoff->role_code) {
                $signoff->setAttribute('role_title', null);
            }
        }

        return $this->success([
            'incident_report' => $incidentReport,
            'incident_signoffs' => $incidentSignoffCollection->values()->toArray()
        ], 'Data retrieved successfully');
    }




    public function imageStore(Request $request)
    {
        // Validate request
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
            'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:10240',
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Step 3 store: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error',
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        $incidentReport = IncidentReport::findOrFail($request->incident_report_id);
        $userTable = $this->getUserTable();
        $user = auth()->user();
        if (
            ($userTable === 'customer' && ($incidentReport->customer_id !== $user->id || $incidentReport->workspace_id !== $user->current_workspace_id)) ||
            ($userTable === 'emp' && ($incidentReport->customer_id !== $user->customer_id || $incidentReport->workspace_id !== $user->workspace_id))
        ) {
            return $this->message('You do not have access to this report.', 403);
        }
        // Upload Image
        if ($request->hasFile('image') && $request->file('image')->isValid()) {
            $imagePath = $this->handleFileImageUpload($request, 'IncidentReportDocuments')['path'] ?? null;
            if (!$imagePath) {
                return $this->message('Image upload failed.', 422);
            }
            $image = IncidentImage::create([
                'incident_report_id' => $request->incident_report_id,
                'image' => $imagePath,
            ]);
            return $this->success($image, 'Image uploaded successfully');
        }

        return $this->message('No valid image provided.', 422);
    }


    public function getImages(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
        ]);
        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Step 3 store: ' . $validator->errors()->first(),
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error',
            ]);
            return $this->message($validator->errors()->first(), 422);
        }
        $incidentReport = IncidentReport::find($request->incident_report_id);
        if (!$incidentReport) {
            return $this->message('Incident report not found.', 404);
        }
        $userTable = $this->getUserTable();
        $user = auth()->user();
        if (
            ($userTable === 'customer' && ($incidentReport->customer_id !== $user->id || $incidentReport->workspace_id !== $user->current_workspace_id)) ||
            ($userTable === 'emp' && ($incidentReport->customer_id !== $user->customer_id || $incidentReport->workspace_id !== $user->workspace_id))
        ) {
            return $this->message('You do not have access to this report.', 403);
        }
        // Fetch Images
        $images = IncidentImage::where('incident_report_id', $request->incident_report_id)->get();
        if (!$images) {
            return $this->message('No images found.', 404);
        }
        return $this->withCount($images, 'Images retrieved successfully!');
    }

    public function deleteImage(Request $request)
    {
        // Validate request
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|exists:incident_reports,id',
            'id' => 'required', // Can be a single ID or an array of IDs
        ]);
        if ($validator->fails()) {
            return $this->message($validator->errors()->first(), 422);
        }
        $imageIds = is_array($request->id) ? $request->id : [$request->id];
        $incidentReport = IncidentReport::findOrFail($request->incident_report_id);
        $userTable = $this->getUserTable();
        $user = auth()->user();
        if (
            ($userTable === 'customer' && ($incidentReport->customer_id !== $user->id || $incidentReport->workspace_id !== $user->current_workspace_id)) ||
            ($userTable === 'emp' && ($incidentReport->customer_id !== $user->customer_id || $incidentReport->workspace_id !== $user->workspace_id))
        ) {
            return $this->message('You do not have permission to delete these images.', 403);
        }
        // Fetch all images matching the provided IDs
        $images = IncidentImage::whereIn('id', $imageIds)
            ->where('incident_report_id', $request->incident_report_id)
            ->get();
        if ($images->isEmpty()) {
            return $this->message('No matching images found.', 404);
        }
        foreach ($images as $image) {
            $imagePath = public_path($image->image);
            if ($image->image && file_exists($imagePath)) {
                unlink($imagePath); // Remove from folder
            }
            $image->delete(); // Remove from database
        }
        return $this->message(count($imageIds) > 1 ? 'Images deleted successfully.' : 'Image deleted successfully.');
    }
    public function uploadReportPdf(Request $request)
    {
        // Enhanced validation
        $validator = Validator::make($request->all(), [
            'report_id' => 'required|integer',
            'report_type' => 'required|string|in:incident_report,swms_report,inspection_report,whs_report,whsqe_report',
            'file' => 'required|file|mimes:pdf,doc,docx,jpg,jpeg,png,gif|max:20480', // 20MB max
        ]);

        if ($validator->fails()) {
            return $this->message($validator->errors()->first(), 422);
        }

        $reportId = $request->report_id;
        $reportType = $request->report_type;
        $userTable = $this->getUserTable();
        $user = auth()->user();

        // Model mapping for dynamic report finding
        $modelMap = [
            'incident_report' => IncidentReport::class,
            'swms_report' => Swms::class,
            'inspection_report' => InspectionPlan::class,
            'whs_report' => WhsReport::class,
            'whsqe_report' => WhsqReport::class,
        ];

        $report = isset($modelMap[$reportType]) ? $modelMap[$reportType]::find($reportId) : null;

        if (!$report) {
            return $this->message('Report not found.', 404);
        }else{
            $report->send_by = $user->id;
            $report->sender_type= $userTable;
            $report->save();
        }


        // Consolidated authorization check
        $isAuthorized = ($userTable === "customer")
            ? ($report->customer_id == $user->id && $report->workspace_id == $user->current_workspace_id)
            : ($userTable === "emp" && $report->customer_id == $user->customer_id && $report->workspace_id == $user->workspace_id);

        if (!$isAuthorized) {
            return $this->message('Unauthorized access to this report.', 403);
        }

        try {
            // Check for existing record with the same report_type and report_id
            $existingRecord = GeneratedPdfReport::where([
                'report_type' => $reportType, 
                'report_id' => $reportId
            ])->first();

            // Debug: Log the existing record for verification
            Log::info("Upload request for report_type: {$reportType}, report_id: {$reportId}", [
                'existing_record' => $existingRecord ? $existingRecord->toArray() : null,
                'user_table' => $userTable,
                'user_id' => $user->id,
                'request_data' => $request->all()
            ]);

            // Also check for any existing records with the same report_id but different report_type
            $otherRecords = GeneratedPdfReport::where('report_id', $reportId)
                ->where('report_type', '!=', $reportType)
                ->get();
            
            if ($otherRecords->isNotEmpty()) {
                Log::info("Found other records with same report_id but different report_type", [
                    'report_id' => $reportId,
                    'current_report_type' => $reportType,
                    'other_records' => $otherRecords->toArray()
                ]);
            }

            // Handle file upload directly
            $file = $request->file('file');
            $uploadPath = 'reports';

            // Create directory if it doesn't exist
            $fullUploadPath = public_path($uploadPath);
            if (!file_exists($fullUploadPath)) {
                mkdir($fullUploadPath, 0755, true);
            }

            // Generate unique filename
            $filename = time() . '_' . uniqid() . '.' . $file->getClientOriginalExtension();
            $filePath = $uploadPath . '/' . $filename;
            $fullFilePath = public_path($filePath);

            // Delete old file if exists (only for the same report_type)
            if ($existingRecord && $existingRecord->path && file_exists(public_path($existingRecord->path))) {
                unlink(public_path($existingRecord->path));
            }

            // Move uploaded file to destination
            if (!$file->move($fullUploadPath, $filename)) {
                return $this->message('Failed to upload file.', 500);
            }

            // Get user context based on user table
            [$customerId, $workspaceId] = ($userTable === "customer")
                ? [$user->id, $user->current_workspace_id]
                : [$user->customer_id, $user->workspace_id];

            // Prepare and save record data
            $recordData = [
                'report_id' => $reportId,
                'report_type' => $reportType,
                'path' => $filePath,
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
                'updated_at' => now()
            ];

            $action = $existingRecord ? 'updated' : 'created';

            // Use updateOrCreate with proper unique constraint
            // This will only update if both report_type AND report_id match
            $savedRecord = GeneratedPdfReport::updateOrCreate(
                [
                    'report_type' => $reportType, 
                    'report_id' => $reportId
                ],
                $recordData
            );

            // Debug: Log the result for verification
            Log::info("Upload completed", [
                'action' => $action,
                'saved_record_id' => $savedRecord->id,
                'report_type' => $savedRecord->report_type,
                'report_id' => $savedRecord->report_id,
                'file_path' => $savedRecord->path
            ]);

            if($request->approval_status == 1){
                $report->approval_status = 1;
                $report->save();
            }

            // Send notifications to authorized users and employees who signed off
            $this->sendReportPdfUploadNotifications($report, $reportType, $reportId, $customerId, $workspaceId, $filePath);

            return $this->success([
                'file_path' => $filePath,
                'file_url' => url($filePath),
                'original_name' => $file->getClientOriginalName(),
                'report_id' => $reportId,
                'report_type' => $reportType,
                'action' => $action
            ], 'File generated and saved successfully.');
        } catch (\Exception $e) {
            Log::error("File upload failed for report {$reportType}:{$reportId} - " . $e->getMessage());
            return $this->message('Failed to generate file. Please try again.', 500);
        }
    }

    public function updateReportStatus(Request $request)
    {
        // Validation
        $validator = Validator::make($request->all(), [
            'report_id' => 'required|integer',
            'report_type' => 'required|string|in:incident_report,swms_report,inspection_report,whs_report,whsqe_report',
            'status' => 'required|integer', // 0 = not approved, 1 = approved
        ]);

        if ($validator->fails()) {
            return $this->message($validator->errors()->first(), 422);
        }

        $reportId = $request->report_id;
        $reportType = $request->report_type;
        $status = $request->status;
        $userTable = $this->getUserTable();
        $user = auth()->user();

        try {
            // Model mapping for dynamic report finding
            $modelMap = [
                'incident_report' => IncidentReport::class,
                'swms_report' => Swms::class,
                'inspection_report' => InspectionPlan::class,
                'whs_report' => WhsReport::class,
                'whsqe_report' => WhsqReport::class,
            ];

            $report = isset($modelMap[$reportType]) ? $modelMap[$reportType]::find($reportId) : null;

            if (!$report) {
                return $this->message('Report not found.', 404);
            }

            // Authorization check
            $isAuthorized = ($userTable === "customer")
                ? ($report->customer_id == $user->id && $report->workspace_id == $user->current_workspace_id)
                : ($userTable === "emp" && $report->customer_id == $user->customer_id && $report->workspace_id == $user->workspace_id);

            if (!$isAuthorized) {
                return $this->message('Unauthorized access to this report.', 403);
            }
            if ($status == 2) {
                $this->deleteReportSignatures($reportId, $reportType);
                if($report->report_method == 1){
                }else{
                    $this->deleteGeneratedPdfs($reportId, $reportType);
                }
            }
            // Update approval status
            $report->approval_status = $status;
            $report->save();

            // Log the status change
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => "Report approval status updated to " . ($status == 1 ? 'approved' : 'not approved') . " for {$reportType} with id " . $reportId,
                'report_id' => $reportId,
                'report_type' => $reportType
            ]);

            return $this->success([
                'report_id' => $reportId,
                'report_type' => $reportType,
                'approval_status' => $status
            ], 'Report status updated successfully.');

        } catch (\Exception $e) {
            Log::error("Failed to update report status for {$reportType}:{$reportId} - " . $e->getMessage());
            return $this->message('Failed to update report status. Please try again.', 500);
        }
    }
    private function deleteReportSignatures($reportId, $reportType)
    {
        try {
            switch ($reportType) {
                case 'incident_report':
                    // Delete incident report signatures
                    $deletedCount = DB::table('incident_signoffs')
                        ->where('incident_report_id', $reportId)
                        ->update(['signature' => null]);
                    break;

                case 'swms_report':
                    // Delete SWMS signatures
                    $deletedCount = DB::table('swms_signatures')
                        ->where('swms_id', $reportId)
                        ->update(['signatures' => null]);
                    break;

                case 'whs_report':
                    // Delete WHS signatures
                    $deletedCount = DB::table('whs_signatures')
                        ->where('whs_id', $reportId)
                        ->update(['signatures' => null]);
                    break;

                case 'inspection_report':
                    // Delete inspection plan signatures
                    $deletedCount = DB::table('inspection_plan_signatures')
                        ->where('inspection_plan_id', $reportId)
                        ->update(['signature' => null]);
                    break;

                case 'whsqe_report':
                    // Delete WHSQ&E signatures
                    $deletedCount = DB::table('whsq_signature')
                        ->where('whsq_report_id', $reportId)
                        ->update( ['signature' => null]);
                    break;

                default:
                    Log::warning("Unknown report type for signature deletion: {$reportType}");
                    break;
            }
        } catch (\Exception $e) {
            Log::error("Failed to delete signatures for {$reportType} ID {$reportId}: " . $e->getMessage());
            // Don't throw the exception as the main operation (status update) should still succeed
        }
    }
    private function deleteGeneratedPdfs($reportId, $reportType)
    {
        try {
            // Find all generated PDF records for this report
            $generatedPdfs = DB::table('generated_pdf_reports')
                ->where('report_id', $reportId)
                ->where('report_type', $reportType)
                ->get();

            $deletedCount = 0;
            foreach ($generatedPdfs as $pdfRecord) {
                // Delete the physical file if it exists
                if ($pdfRecord->path && file_exists(public_path($pdfRecord->path))) {
                    try {
                        unlink(public_path($pdfRecord->path));
                        Log::info("Deleted physical PDF file: {$pdfRecord->path}");
                    } catch (\Exception $fileError) {
                        Log::warning("Failed to delete physical PDF file {$pdfRecord->path}: " . $fileError->getMessage());
                    }
                }

                // Delete the database record
                DB::table('generated_pdf_reports')
                    ->where('id', $pdfRecord->id)
                    ->update(['path' => null]);
                
                $deletedCount++;
            }

            Log::info("Deleted {$deletedCount} generated PDF records for {$reportType} ID: {$reportId}");

        } catch (\Exception $e) {
            Log::error("Failed to delete generated PDFs for {$reportType} ID {$reportId}: " . $e->getMessage());
            // Don't throw the exception as the main operation (status update) should still succeed
        }
    }

    /**
     * Send notification to customer when signature is added to a report
     */
    private function sendSignatureNotification($reportId, $reportType, $employeeId, $customerId, $workspaceId)
    {
        try {
            // Get employee details
            $employee = EmpPersonalDetails::where('emp_id', $employeeId)->first();
            if (!$employee) {
                Log::warning('Employee not found for signature notification: ' . $employeeId);
                return;
            }

            // Prepare notification message
            $employeeName = trim($employee->first_name . ' ' . $employee->middle_name . ' ' . $employee->last_name);
            $reportTypeDisplay = $this->formatReportTypeDisplay($reportType);
            
            $notificationTitle = "Signature Added to {$reportTypeDisplay}";
            $notificationMessage = "Employee {$employeeName} has signed the {$reportTypeDisplay} (ID: {$reportId})";

            // Send notification to customer
            $this->save_notifications(
                $notificationTitle,
                $notificationMessage,
                config('constants.employee_types.employee'),
                $employeeId, // sender_id
                config('constants.employee_types.customer'),
                $customerId, // receiver_id (customer)
                config('constants.notification_types.signature_added'),
                $customerId,
                $workspaceId
            );

            Log::info("Signature notification sent to customer {$customerId} for {$reportType} ID {$reportId}");
        } catch (\Exception $e) {
            Log::error("Failed to send signature notification: " . $e->getMessage());
        }
    }

    /**
     * Send notification to customer when report is approved
     */
    private function sendReportApprovalNotification($reportId, $reportType, $employeeId, $customerId, $workspaceId)
    {
        try {
            Log::info("sendReportApprovalNotification called", [
                'reportId' => $reportId,
                'reportType' => $reportType,
                'employeeId' => $employeeId,
                'customerId' => $customerId,
                'workspaceId' => $workspaceId
            ]);

            // Get employee details
            $employee = EmpPersonalDetails::where('emp_id', $employeeId)->first();
            if (!$employee) {
                Log::warning('Employee not found for approval notification: ' . $employeeId);
                return;
            }

            // Prepare notification message
            $employeeName = trim($employee->first_name . ' ' . $employee->middle_name . ' ' . $employee->last_name);
            $reportTypeDisplay = $this->formatReportTypeDisplay($reportType);
            
            $notificationTitle = "Report Approved - {$reportTypeDisplay}";
            $notificationMessage = "{$reportTypeDisplay} (ID: {$reportId}) has been approved.";

            Log::info("Sending customer notification", [
                'title' => $notificationTitle,
                'message' => $notificationMessage
            ]);

            // 1. Send notification to customer
            $this->save_notifications(
                $notificationTitle,
                $notificationMessage,
                config('constants.employee_types.employee'),
                $employeeId, // sender_id
                config('constants.employee_types.customer'),
                $customerId, // receiver_id (customer)
                config('constants.notification_types.report_approved'),
                $customerId,
                $workspaceId
            );

           

            Log::info("Report approval notifications sent to customer {$customerId} and signoff employees for {$reportType} ID {$reportId}");
        } catch (\Exception $e) {
            Log::error("Failed to send report approval notification: " . $e->getMessage());
        }
    }

    /**
     * Send notifications to authorized users and employees who signed off when report PDF is uploaded
     */
    private function sendReportPdfUploadNotifications($report, $reportType, $reportId, $customerId, $workspaceId, $filePath)
    {
        try {
            $reportTypeDisplay = $this->formatReportTypeDisplay($reportType);
            $currentUserId = auth()->user()->id;
            
            // Get current user details for sender information
            $currentUser = EmpPersonalDetails::where('emp_id', $currentUserId)->first();
            $currentUserName = $currentUser ? trim($currentUser->first_name . ' ' . $currentUser->middle_name . ' ' . $currentUser->last_name) : 'User';

          // 1. Notify the customer (authorized by)
            $notificationTitle = "{$reportTypeDisplay} - Generated"; 
            $pdfUrl = url($filePath);
            $notificationMessage = "A {$reportTypeDisplay} has been generated and sent for approval. [PDF_LINK:{$pdfUrl}]";


            $this->save_notifications(
                $notificationTitle,
                $notificationMessage,
                config('constants.employee_types.customer'),
                $currentUserId, // sender_id
                config('constants.employee_types.customer'),
                $currentUserId, // receiver_id (customer)
                config('constants.notification_types.report_pdf_uploaded'),
                $customerId,
                $workspaceId
            );

            // 2. Notify employees who have signed off for this report
            $this->notifyReportSignOffEmployees($report, $reportType, $reportId, $currentUserId, $currentUserName, $customerId, $workspaceId, $filePath);

            Log::info("PDF upload notifications sent for {$reportType} ID {$reportId}");
        } catch (\Exception $e) {
            Log::error("Failed to send PDF upload notifications: " . $e->getMessage());
        }
    }

    /**
     * Notify employees who have signed off for the report
     */
    private function notifyReportSignOffEmployees($report, $reportType, $reportId, $currentUserId, $currentUserName, $customerId, $workspaceId, $filePath)
    {

        try {
            $reportTypeDisplay = $this->formatReportTypeDisplay($reportType);
            $signOffEmployees = [];
            $authorisedBy = [];

            // Get employees who have signed off based on report type
            switch ($reportType) {
                case 'incident_report':
                    $signOffEmployees = IncidentSignoff::where('incident_report_id', $reportId)
                        ->pluck('emp_id')
                        ->toArray();
                    
                        $authorisedBy = IncidentReport::where('id', $reportId)->pluck('authorised_by')->toArray();

                    break;

                case 'swms_report':
                    $signOffEmployees = SwmsSignature::where('swms_id', $reportId)
                        ->pluck('emp_id')
                        ->toArray();
                        $authorisedBy = Swms::where('id', $reportId)->pluck('site_manager_or_forman')->toArray();
                    break;

                case 'inspection_report':
                    $signOffEmployees = InspectionPlanSignature::where('inspection_plan_id', $reportId)
                        ->pluck('employee_id')
                        ->toArray();
                        $authorisedBy = InspectionPlan::where('id', $reportId)->pluck('authorised_by')->toArray();
                    break;

                case 'whs_report':
                    $signOffEmployees = WhsSignature::where('whs_id', $reportId)
                        ->pluck('employee_id')
                        ->toArray();
                        $authorisedBy = WhsReport::where('id', $reportId)->pluck('authorised_by')->toArray();
                    break;
            }

            $signOffEmployees = array_values(array_unique(array_filter($signOffEmployees, function ($employeeId) {
                return !empty($employeeId) && $employeeId !== '0';
            })));
            $authorisedBy = array_values(array_unique(array_filter($authorisedBy, function ($employeeId) {
                return !empty($employeeId) && $employeeId !== '0';
            })));

            if (!empty($signOffEmployees) || !empty($authorisedBy)) {
                $notificationTitle = "{$reportTypeDisplay} - Approval Needed";
                $notificationMessage = "Your approval signature is required for {$reportTypeDisplay}. Awaiting your review and approval.";

                // Send notifications to each employee who signed off
                foreach ($signOffEmployees as $employeeId) {
                    if ((string) $employeeId === (string) $currentUserId) {
                        continue;
                    }

                    $this->save_notifications(
                        $notificationTitle,
                        $notificationMessage,
                        config('constants.employee_types.customer'),
                        $currentUserId, // sender_id
                        config('constants.employee_types.employee'),
                        $employeeId, // receiver_id (employee who signed off)
                        config('constants.notification_types.report_approval_needed'),
                        $customerId,
                        $workspaceId
                    );

                    Log::info("notification send to this employee", [$employeeId]);
                }

                if (!empty($authorisedBy)) {
                    foreach ($authorisedBy as $authorisedByEmployee) {
                        if ((string) $authorisedByEmployee === (string) $currentUserId) {
                            continue;
                        }

                        $this->save_notifications(
                            $notificationTitle,
                            $notificationMessage,
                            config('constants.employee_types.customer'),
                            $currentUserId, // sender_id
                            config('constants.employee_types.employee'),
                            $authorisedByEmployee, // receiver_id (authorized approver)
                            config('constants.notification_types.report_approval_needed'),
                            $customerId,
                            $workspaceId
                        );
                    }
                }
            }

            Log::info("Notified {$reportType} sign-off employees: " . implode(', ', $signOffEmployees));
        } catch (\Exception $e) {
            Log::error("Failed to notify report sign-off employees: " . $e->getMessage());
        }
    }

    public function incidentQuickEntryStore(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            [
                'title' => 'required|string|max:255',
                'document_number' => 'required|string|max:255',
                'authorised_by' => 'required|integer|exists:emp_company_details,id',
                'site_id' => 'required|integer|exists:sites,id',
                'issue_date' => 'nullable|date',
                'revision_date' => 'nullable|date|after_or_equal:issue_date',
                'sign_off' => 'nullable|array',
                'sign_off.*.emp_id' => 'required_with:sign_off|integer|exists:emp_company_details,id',
                'file' => 'required|file|max:20480',
            ],
            [
                'file.required' => 'Incident report summary PDF is required.',
            ]
        );

        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident quick entry validation error: ' . $validator->errors()->first(),
                'report_id' => 0,
                'report_type' => 'incident_report',
                'error_type' => 'Validation error',
            ]);
            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);
            }

            $revisionNumber = $this->generateRevisionNumber();

            $incidentReport = IncidentReport::create([
                'title' => $validator->validated()['title'],
                'document_number' => $validator->validated()['document_number'],
                'authorised_by' => $validator->validated()['authorised_by'],
                'site_id' => $validator->validated()['site_id'],
                'revision_number' => $revisionNumber,
                'issue_date' => $validator->validated()['issue_date'],
                'revision_date' => $validator->validated()['revision_date'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
                'report_method' => 1,
                'process' => 1,
            ]);

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

            foreach ($signOffEntries as $entry) {
                // Get employee access role
                $userAuthorizedBy = EmpCompanyDetails::with(['EmpPersonalDetails', 'accessRole', 'accessTier'])
                    ->find($entry['emp_id']);
                $accessRole = $userAuthorizedBy->accessRole->code ?? null;

                IncidentSignoff::create([
                    'incident_report_id' => $incidentReport->id,
                    'emp_id' => $entry['emp_id'],
                    'role_code' => $accessRole,
                    'date' => now()->format('Y-m-d'),
                ]);
            }

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

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

            DB::commit();

            storeReportsLogs([
                'employee_id' => $authUser->id,
                'message' => 'Incident quick entry saved successfully.',
                'report_id' => $incidentReport->id,
                'report_type' => 'incident_report'
            ]);

            return $this->success([
                'incident_report_id' => $incidentReport->id,
                'pdf_url' => $fileUrl,
            ], 'Incident quick entry saved successfully.');
        } catch (Exception $e) {
            DB::rollBack();
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident quick entry error: ' . $shortMessage,
                'report_id' => 0,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred: ' . $shortMessage, 500);
        }
    }

    public function incidentQuickEntryEdit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'incident_report_id' => 'required|integer|exists:incident_reports,id',
        ]);

        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident quick entry edit validation error: ' . $validator->errors()->first(),
                'report_id' => $request->get('incident_report_id', 0),
                'report_type' => 'incident_report',
                'error_type' => 'Validation error',
            ]);
            return $this->error($validator->errors()->first(), 422);
        }

        try {
            $incidentReport = IncidentReport::with('sitesData')->find($request->incident_report_id);
            if (!$incidentReport) {
                return $this->error('Incident record 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 ($incidentReport->customer_id !== $customerId || $incidentReport->workspace_id !== $workspaceId) {
                return $this->error('You do not have access to this report.', 403);
            }

            // Get sign_off entries
            $signOffEntries = IncidentSignoff::where('incident_report_id', $incidentReport->id)
                ->get()
                ->map(function ($signoff) {
                    return [
                        'emp_id' => $signoff->emp_id,
                        'role_code' => $signoff->role_code,
                        'date' => $signoff->date,
                    ];
                })
                ->toArray();

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

            $responseData = [
                'incident_report_id' => $incidentReport->id,
                'title' => $incidentReport->title,
                'document_number' => $incidentReport->document_number,
                'authorised_by' => $incidentReport->authorised_by,
                'site_id' => $incidentReport->site_id,
                'issue_date' => $incidentReport->issue_date,
                'revision_date' => $incidentReport->revision_date,
                'sign_off' => $signOffEntries,
                'pdf_url' => $generatedReport->path ?? null,
            ];

            return $this->success($responseData, 'Incident quick entry fetched successfully.');
        } catch (Exception $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident quick entry edit error: ' . $shortMessage,
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error',
            ]);
            return $this->error('An error occurred: ' . $shortMessage, 500);
        }
    }

    public function incidentQuickEntryUpdate(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            [
                'incident_report_id' => 'required|integer|exists:incident_reports,id',
                'title' => 'required|string|max:255',
                'document_number' => 'required|string|max:255',
                'authorised_by' => 'required|integer|exists:emp_company_details,id',
                'site_id' => 'required|integer|exists:sites,id',
                'issue_date' => 'nullable|date',
                'revision_date' => 'nullable|date|after_or_equal:issue_date',
                'sign_off' => 'nullable|array',
                'sign_off.*.emp_id' => 'required_with:sign_off|integer|exists:emp_company_details,id',
                'file' => 'nullable|file|max:20480',
            ]
        );

        if ($validator->fails()) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident quick entry update validation error: ' . $validator->errors()->first(),
                'report_id' => $request->get('incident_report_id', 0),
                'report_type' => 'incident_report',
                'error_type' => 'Validation error',
            ]);
            return $this->error($validator->errors()->first(), 422);
        }

        try {
            DB::beginTransaction();
            
            $incidentReport = IncidentReport::find($request->incident_report_id);
            if (!$incidentReport) {
                return $this->error('Incident record 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 ($incidentReport->customer_id !== $customerId || $incidentReport->workspace_id !== $workspaceId) {
                return $this->error('You do not have access to this report.', 403);
            }

            $incidentReport->update([
                'title' => $request->title,
                'document_number' => $request->document_number,
                'authorised_by' => $request->authorised_by,
                'site_id' => $request->site_id,
                'issue_date' => $request->issue_date,
                'revision_date' => $request->revision_date,
                'report_method' => 1,
                'process' => 1,
            ]);

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

            $existingEmployeeIds = IncidentSignoff::where('incident_report_id', $incidentReport->id)
                ->pluck('emp_id')
                ->toArray();

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

            if (!empty($employeesToRemove)) {
                IncidentSignoff::where('incident_report_id', $incidentReport->id)
                    ->whereIn('emp_id', $employeesToRemove)
                    ->delete();
            }

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

                $existingRecord = IncidentSignoff::where('incident_report_id', $incidentReport->id)
                    ->where('emp_id', $entry['emp_id'])
                    ->first();

                // Get employee access role
                $userAuthorizedBy = EmpCompanyDetails::with(['EmpPersonalDetails', 'accessRole', 'accessTier'])
                    ->find($entry['emp_id']);
                $accessRole = $userAuthorizedBy->accessRole->code ?? null;

                if ($existingRecord) {
                    $existingRecord->update([
                        'role_code' => $accessRole,
                        'date' => now()->format('Y-m-d'),
                    ]);
                } else {
                    IncidentSignoff::create([
                        'incident_report_id' => $incidentReport->id,
                        'emp_id' => $entry['emp_id'],
                        'role_code' => $accessRole,
                        'date' => now()->format('Y-m-d'),
                    ]);
                }
            }

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

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

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

            DB::commit();

            storeReportsLogs([
                'employee_id' => $authUser->id,
                'message' => 'Incident quick entry updated successfully.',
                'report_id' => $incidentReport->id,
                'report_type' => 'incident_report'
            ]);

            return $this->success([
                'incident_report_id' => $incidentReport->id,
                'pdf_url' => $fileUrl,
            ], 'Incident quick entry updated successfully.');
        } catch (Exception $e) {
            DB::rollBack();
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Incident quick entry update error: ' . $shortMessage,
                'report_id' => $request->incident_report_id,
                'report_type' => 'incident_report',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred: ' . $shortMessage, 500);
        }
    }
}
