<?php

namespace App\Http\Controllers;

use PDF;
use Illuminate\Support\Facades\DB;
use App\Models\WhsReport;
use App\Models\WhsReportItem;
use App\Models\GeneratedPdfReport;
use App\Models\HazardObs;
use Illuminate\Http\Request;
use App\Models\EmpCompanyDetails;
use App\Models\EmpPersonalDetails;
use App\Models\HazardObsImage;
use App\Models\Role;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class WhsReportController extends Controller
{

    public function whsReportDownloadPdfRegenerate($id)
    {
        if (!$id) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Report Download ID is required',
                'report_id' => 0,
                'report_type' => 'whs_report',
                'error_type' => 'Validation error',
            ]);
            return $this->error('Report ID is required.', 422);
        }
        try {
            // Fetch WHS report and add employee/customer checks
            $userTable = $this->getUserTable();
            $whsReport = WhsReport::find($id);
            if (!$whsReport) {
                return $this->error('WHS report not found.', 404);
            }
            if ($userTable === 'customer' && ($whsReport->customer_id !== auth()->id() || $whsReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->error('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->error('You do not have access to this report.', 403);
            }
            // Fetch all related data based on customer/employee
            $customerId = auth()->user()->customer_id ?? auth()->id();
            $workspaceId = auth()->user()->workspace_id ?? auth()->user()->current_workspace_id;
            $whs_data = DB::table('whs_reports')
                ->leftJoin('emp_personal_details as authorised_by', 'whs_reports.authorised_by', '=', 'authorised_by.emp_id')
                ->leftJoin('projects as projects', 'whs_reports.project_id', '=', 'projects.id')
                ->leftJoin('swms as swms', 'whs_reports.swms_id', '=', 'swms.id')
                ->leftJoin('sites', 'whs_reports.site_id', '=', 'sites.id')
                ->where('whs_reports.id', $id)
                ->where('whs_reports.customer_id', $customerId)
                ->where('whs_reports.workspace_id', $workspaceId)
                ->select(
                    'whs_reports.*',
                    'sites.title as site_title',
                    'projects.title as project_title',
                    'swms.title as swms_title',
                    'swms.swms_number as swms_number',
                    'swms.revision_number as swms_revision_number',
                    'swms.version_number as version_number',
                    'authorised_by.first_name as authorised_by_first_name',
                    'authorised_by.middle_name as authorised_by_middle_name',
                    'authorised_by.last_name as authorised_by_or_forman_last_name'
                )->first();
            if (!$whs_data) {
                return $this->error('WHS report not found or not accessible.', 404);
            }
            $positions_responsible = DB::table('whs_responsible')
                ->join('roles', 'whs_responsible.role_id', '=', 'roles.id')
                ->where('whs_responsible.whs_report_id', $id)
                ->select('roles.*')
                ->get();
            $personal_attending = DB::table('whs_additional_persons')
                ->join('emp_personal_details', 'whs_additional_persons.employee_id', '=', 'emp_personal_details.emp_id')
                ->where('whs_additional_persons.whs_report_id', $id)
                ->select('emp_personal_details.*')
                ->get();
            $whs_conducted_by = DB::table('whs_conducted_by')
                ->join('emp_personal_details', 'whs_conducted_by.employee_id', '=', 'emp_personal_details.emp_id')
                ->where('whs_conducted_by.whs_report_id', $id)
                ->select('emp_personal_details.*')
                ->get();
            $whs_item = DB::table('whs_items')
                ->where('customer_id', $customerId)
                ->where('status', 1)
                ->get();
            $whs_hazards = DB::table('whs_report_hazards')
                ->join('roles', 'whs_report_hazards.role_id', '=', 'roles.id')
                ->where('whs_report_hazards.whs_report_id', $id)
                ->select('whs_report_hazards.*', 'roles.title as role_title')
                ->get();
            $report_images = DB::table('whs_images')
                ->where('whs_report_id', $id)
                ->get();
            $whsReportItems = WhsReportItem::where('whs_report_id', $id)->get()->keyBy('whs_items_id')->map(function ($item) {
                return $item->values;
            });
            // Map report values into whs_item
            $whs_item = $whs_item->map(function ($item) use ($whsReportItems) {
                $item = (array) $item; // convert stdClass to array if needed
                $value = $whsReportItems[$item['id']] ?? null;
                if ($value === "1" || $value === 1) {
                    $item['report_value'] = "Yes";
                } elseif ($value === "0" || $value === 0) {
                    $item['report_value'] = "No";
                } elseif ($value === "2" || $value === 2) {
                    $item['report_value'] = "N/A";
                } else {
                    $item['report_value'] = null;
                }
                return $item;
            });
            $whs_signature_data = DB::table('whs_signatures')
                ->where('whs_id', $id)
                ->select('employee_id', 'signatures', 'inductance_date', 'is_site_employee')
                ->get();
            $whs_signature_data_array = [];
            foreach ($whs_signature_data as $signature) {
                $emp_company = EmpCompanyDetails::where('id', $signature->employee_id)->first();
                $emp_personal_details = EmpPersonalDetails::where('emp_id', $signature->employee_id)->first();
                $role_title = null;
                if ($emp_company && $emp_company->access_role) {
                    $role_title = Role::where('code', $emp_company->access_role)->first();
                }
                $whs_signature_data_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' => $signature->signatures,
                    'inductance_date' => $signature->inductance_date,
                    'is_site_employee' => $signature->is_site_employee
                ];
            }
            if($whs_data->report_method == 1){
                $whs_upload_report=GeneratedPdfReport::where('report_type', 'whs_report')->where('report_id', $id)->first();
            }
            else{
                $whs_upload_report=null;
            }
            // Return the compact data
            $data = [
                'whs_item' => $whs_item,
                'whs_data' => $whs_data,
                'positions_responsible' => $positions_responsible,
                'personal_attending' => $personal_attending,
                'whs_conducted_by' => $whs_conducted_by,
                'whs_hazards' => $whs_hazards,
                'report_images' => $report_images,
                'whs_signature_data' => $whs_signature_data_array,
                'uploaded_report' => $whs_upload_report,
            ];
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Report data retrieved successfully',
                'report_id' => $id,
                'report_type' => 'whs_report',
            ]);
            return $this->success($data, 'WHS Report data retrieved successfully.');
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Report data retrieval error: ' . $shortMessage,
                'report_id' => $id,
                'report_type' => 'whs_report',
                'error_type' => 'Exception error',
            ]);
            return $this->error('An error occurred while retrieving the WHS report data: ' . $e->getMessage(), 500);
        }
    }
    // PDF
    public function whsReportDownloadPdf($id)
    {
        if (!$id) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Report Download ID is required',
                'report_id' => 0,
                'report_type' => 'whs_report',
                'error_type' => 'Validation error',
            ]);
            return $this->error('Report ID is required.', 422);
        }
        try {
            // Fetch WHS report and add employee/customer checks
            $userTable = $this->getUserTable();
            $whsReport = WhsReport::find($id);
            if (!$whsReport) {
                return $this->error('WHS report not found.', 404);
            }
            if ($userTable === 'customer' && ($whsReport->customer_id !== auth()->id() || $whsReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->error('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->error('You do not have access to this report.', 403);
            }
            // Fetch related data
            $customerId = auth()->user()->customer_id ?? auth()->id();
            $workspaceId = auth()->user()->workspace_id ?? auth()->user()->current_workspace_id;
            $whs_data = DB::table('whs_reports')
                ->leftJoin('emp_personal_details as authorised_by', 'whs_reports.authorised_by', '=', 'authorised_by.id')
                ->leftJoin('projects as projects', 'whs_reports.project_id', '=', 'projects.id')
                ->leftJoin('swms as swms', 'whs_reports.swms_id', '=', 'swms.id')
                ->where('whs_reports.id', $id)
                ->where('whs_reports.customer_id', $customerId)
                ->where('whs_reports.workspace_id', $workspaceId)
                ->select(
                    'whs_reports.*',
                    'projects.title as project_title',
                    'swms.title as swms_title',
                    'swms.swms_number as swms_number',
                    'swms.revision_number as swms_revision_number',
                    'swms.version_number as version_number',
                    'authorised_by.first_name as authorised_by_first_name',
                    'authorised_by.last_name as authorised_by_or_forman_last_name'
                )->first();
            $positions_responsible = DB::table('whs_responsible')
                ->join('roles', 'whs_responsible.role_id', '=', 'roles.id')
                ->where('whs_responsible.whs_report_id', $id)
                ->select('roles.*')
                ->get();
            $personal_attending = DB::table('whs_additional_persons')
                ->join('emp_personal_details', 'whs_additional_persons.employee_id', '=', 'emp_personal_details.id')
                ->where('whs_additional_persons.whs_report_id', $id)
                ->select('emp_personal_details.*')
                ->get();
            $whs_conducted_by = DB::table('whs_conducted_by')
                ->join('emp_personal_details', 'whs_conducted_by.employee_id', '=', 'emp_personal_details.id')
                ->where('whs_conducted_by.whs_report_id', $id)
                ->select('emp_personal_details.*')
                ->get();
            $whs_hazards = DB::table('whs_report_hazards')
                ->join('roles', 'whs_report_hazards.role_id', '=', 'roles.id')
                ->where('whs_report_hazards.whs_report_id', $id)
                ->select('whs_report_hazards.*', 'roles.title as role_title')
                ->get();
            $whs_item = DB::table('whs_items')
                ->where('customer_id', $customerId)
                ->where('status', 1)
                ->get();
            $whsReportItems = WhsReportItem::where('whs_report_id', $id)->get()->keyBy('whs_items_id')->map(function ($item) {
                return $item->values;
            });
            $report_images = DB::table('whs_images')->where('whs_report_id', $id)->get();
            // Map report values into whs_item
            $whs_item = $whs_item->map(function ($item) use ($whsReportItems) {
                $item = (array) $item; // convert stdClass to array if needed
                $value = $whsReportItems[$item['id']] ?? null;
                if ($value === "1" || $value === 1) {
                    $item['report_value'] = "Yes";
                } elseif ($value === "0" || $value === 0) {
                    $item['report_value'] = "No";
                } elseif ($value === "2" || $value === 2) {
                    $item['report_value'] = "N/A";
                } else {
                    $item['report_value'] = null;
                }
                return $item;
            });
            // Render the PDF view
            $viewPath = 'WHSreport.NewWHSreport.PdfReport.whsReport';
            $html = view($viewPath, compact(
                'whs_data',
                'positions_responsible',
                'personal_attending',
                'whs_conducted_by',
                'whs_item',
                'whs_hazards',
                'report_images'
            ))->render();
            // Generate the filename
            $report_whs_number = $whs_data->number ?? 'NO_WHS';
            $report_title = $whs_data->title ?? 'No_Named';
            $report_whs_revision = $whs_data->revision_number ?? 'No_Revision';
            $filename = "{$report_title}_N{$report_whs_number}_R{$report_whs_revision}.pdf";
            // Ensure the directory exists
            $directory = public_path('WHSReportPdf');
            if (!file_exists($directory)) {
                mkdir($directory, 0777, true);
            }
            $path = $directory . '/' . $filename;
            // Check if file already exists
            if (file_exists($path)) {
                return $this->success(['download_url' => url("WHSReportPdf/{$filename}")], 'PDF already exists.');
            }
            // Generate and save the PDF
            $pdf = PDF::loadHTML($html)->setPaper('A4', 'portrait');
            $pdf->save($path);
            // Save the generated PDF record
            GeneratedPdfReport::updateOrCreate(
                [
                    'report_id' => $id,
                    'report_type' => 'whs_report',
                ],
                ['path' => url("WHSReportPdf/{$filename}")]
            );
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS PDF generated successfully',
                'report_id' => $id,
                'report_type' => 'whs_report',
            ]);
            return $this->success(['download_url' => url("WHSReportPdf/{$filename}")], 'PDF generated successfully.');
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS PDF generation error: ' . $shortMessage,
                'report_id' => $id,
                'report_type' => 'whs_report',
                'error_type' => 'Exception error',
            ]);
            return $this->error('An error occurred while generating the PDF.', 500);
        }
    }

    public function whsReportPublishReport($id)
    {
        if (!$id) {
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Report Publish ID is required',
                'report_id' => 0,
                'report_type' => 'whs_report',
                'error_type' => 'Validation error',
            ]);
            return $this->error('Report ID is required.', 422);
        }
        try {
            // Fetch WHS report and add employee/customer checks
            $userTable = $this->getUserTable();
            $whsReport = WhsReport::find($id);
            if (!$whsReport) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Report Not Found',
                    'report_id' => $id,
                    'report_type' => 'whs_report',
                    'error_type' => 'Not found error',
                ]);
                return $this->error('Report not found. Please try again.', 404);
            }
            if ($userTable === 'customer' && ($whsReport->customer_id !== auth()->id() || $whsReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->error('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->error('You do not have access to this report.', 403);
            }
            // Generate PDF if necessary
            $whsReport->is_published = $whsReport->is_published == '1' ? '0' : '1';
            $whsReport->save();
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Report status updated successfully',
                'report_id' => $id,
                'report_type' => 'whs_report',
            ]);
            return $this->success($whsReport, 'Report status updated successfully.');
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Error while publishing report: ' . $shortMessage,
                'report_id' => $id,
                'report_type' => 'whs_report',
                'error_type' => 'Exception error',
            ]);
            return $this->error('An error occurred while publishing the report.', 500);
        }
    }

    public function whsReportViewSignature($id)
    {
        if (!$id) {
            return $this->error('Report ID is required.', 422);
        }
        try {
            // Fetch WHS report and add employee/customer checks
            $userTable = $this->getUserTable();
            $whsReport = WhsReport::with('authorizedBy')->find($id);
            if (!$whsReport) {
                return $this->error('WHS report not found.', 404);
            }
            if ($userTable === 'customer' && ($whsReport->customer_id !== auth()->id() || $whsReport->workspace_id !== auth()->user()->current_workspace_id)) {
                return $this->error('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->error('You do not have access to this report.', 403);
            }
            
            // Convert to array to get formatted dates from BaseModel
            $whs_data = $whsReport->toArray();
            
            // Add the authorized by name fields
            if ($whsReport->authorizedBy) {
                $whs_data['authorised_by_first_name'] = $whsReport->authorizedBy->first_name;
                $whs_data['authorised_by_or_forman_last_name'] = $whsReport->authorizedBy->last_name;
            }
            
            // Fetch WHS signature data with role information
            $whs_signature_data = DB::table('whs_signatures')
                ->leftJoin('emp_personal_details as authorised_by', 'whs_signatures.employee_id', '=', 'authorised_by.emp_id')
                ->leftJoin('emp_company_details as emp_company_details', 'authorised_by.emp_id', '=', 'emp_company_details.id')
                ->leftJoin('roles as roles', 'emp_company_details.access_role', '=', 'roles.code')
                ->where('whs_signatures.whs_id', $id)
                ->where('roles.del', '0')
                ->select(
                    'whs_signatures.*',
                    'authorised_by.first_name as first_name',
                    'authorised_by.last_name as last_name',
                    'roles.title as role_title'
                )->get();
            
            // Convert to collection for easier manipulation
            $whs_signature_collection = collect($whs_signature_data);
            
            // Check if authorised_by employee is already in the signature data
            $authorisedByInSignatures = $whs_signature_collection->contains('employee_id', $whsReport->authorised_by);
            
            // If authorised_by is not in signatures table, add them with null signature
            if (!$authorisedByInSignatures && $whsReport->authorised_by) {
                // 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', $whsReport->authorised_by)
                    ->where('emp_company_details.customer_id', $whsReport->customer_id)
                    ->where('emp_company_details.workspace_id', $whsReport->workspace_id)
                    ->where('roles.del', '0')
                    ->select(
                        'emp_personal_details.first_name as first_name',
                        'emp_personal_details.middle_name as middle_name',
                        'emp_personal_details.last_name as last_name',
                        'roles.title as role_title'
                    )->first();
                
                if ($authorisedByDetails) {
                    // Create signature record for authorised_by with null signature
                    $authorisedBySignature = (object) [
                        'id' => null,
                        'whs_id' => $whsReport->id,
                        'employee_id' => $whsReport->authorised_by,
                        'signatures' => null, // Null indicates signature is required
                        'job_desription' => null,
                        'inductance_date' => null,
                        'created_at' => null,
                        'updated_at' => null,
                        'first_name' => $authorisedByDetails->first_name,
                        'last_name' => $authorisedByDetails->last_name,
                        'role_title' => $authorisedByDetails->role_title
                    ];
                    
                    // Add to signature collection
                    $whs_signature_collection->push($authorisedBySignature);
                }
            }
            
            // Prepare data for the response
            $whs_data['whs_signature_data'] = $whs_signature_collection->toArray();
            return $this->success($whs_data, 'WHS Report Signature data retrieved successfully.');
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'WHS Report Signature View Error: ' . $shortMessage,
                'report_id' => $id,
                'report_type' => 'whs_report',
                'error_type' => 'Exception error',
            ]);
            return $this->error('An error occurred while retrieving the WHS report signature data.', 500);
        }
    }

    public function whsHazardOBSDataIndex(Request $request)
    {
        try {
            $query = HazardObs::query();
            $query->orderBy('id', 'DESC');
            $query->with(['closedBy', 'siteData', 'HazardObsImages']);
            // Apply filters if provided
            if ($request->filled('filter')) {
                $query = $this->filters(json_decode($request->filter, true), $query);
            }
            $start = $request->input('from', 0);
            $query->offset($start)->limit(20);
            $query_result = $query->get();
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS Reports List Retrieved Successfully',
                'report_type' => 'hazard_obs'
            ]);
            return $this->withCount($query_result, 'Hazard OBS Reports List Retrieved Successfully');
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS Reports List Error: ' . $shortMessage,
                'report_type' => 'hazard_obs',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while retrieving the Hazard OBS reports list: ' . $e->getMessage(), 500);
        }
    }

    public function whsHazardOBSData(Request $request)
    {
        try {
            // Get user context
            $userTable = $this->getUserTable();
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;
            } else if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            } else {
                return $this->error('Unauthorized access.', 403);
            }
            // Get employee list with required relationships
            $emp_list = EmpCompanyDetails::where('compeleted', '1')
                ->where('approved', '1')
                ->where('status', '1')
                ->where('del', '0')
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->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', 'B-3', 'B-4', 'B-5']);
                })
                ->get();
            // Get hazard observation data
            $hazard_obs = HazardObs::where('id', $request->hazard_obs_id)
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->with('HazardObsImages')
                ->first();
            // Get sites data
            $sites = DB::table('sites')
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->where('del', '0')
                ->where(function ($query) use ($hazard_obs) {
                    $query->where('active', '1')
                        ->orWhere(function ($subQuery) use ($hazard_obs) {
                            if ($hazard_obs && isset($hazard_obs->site_id)) {
                                $subQuery->where('id', $hazard_obs->site_id)
                                    ->where('del', '0');
                            }
                        });
                })
                ->get(['id', 'title']);
            // Get and process images
            $images = DB::table('hazard_obs_images')
                ->where('hazard_obs_id', $request->hazard_obs_id)
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->get()
                ->map(function ($item) {
                    if (!empty($item->image)) {
                        $item->image_url = url($item->image);
                    } else {
                        $item->image_url = '';
                    }
                    return $item;
                });
            // Prepare response data
            $data = [
                'authorised_by_list' => $emp_list,
                'hazard_obs' => $hazard_obs,
                'sites' => $sites,
                'images' => $images
            ];
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS data retrieved successfully',
                'report_id' => $request->hazard_obs_id,
                'report_type' => 'hazard_obs'
            ]);
            return $this->success($data, 'Hazard OBS data retrieved successfully');
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS data retrieval error: ' . $shortMessage,
                'report_id' => $request->hazard_obs_id ?? 0,
                'report_type' => 'hazard_obs',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while retrieving Hazard OBS data: ' . $e->getMessage(), 500);
        }
    }

    public function whsHazardOBSStore(Request $request)
    {
        try {
            // Get user context
            $userTable = $this->getUserTable();
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;
            } else if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            } else {
                return $this->error('Unauthorized access.', 403);
            }

            // Validate request
            $validator = Validator::make($request->all(), [
                'hazard_obs_id' => 'required',
                'status' => 'required|in:opened,closed',
                'site_id' => 'required',
                'description' => 'required|string',
            ], [
                'site_id.required' => 'Site is required.',
                'status.in' => 'Status must be either opened or closed',
                'description.required' => 'Description is required'
            ]);

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

            $hazard_obs_id = $request->hazard_obs_id;

            if ($hazard_obs_id == 0) {
                // Create new record
                $HazardObs = new HazardObs();
                $HazardObs->customer_id = $auth_id;
                $HazardObs->workspace_id = $workspace_id;
                $HazardObs->closed_by = $request->closed_by_id ?? 0;
                $HazardObs->site_id = $request->site_id;
                $HazardObs->description = $request->description;
                $HazardObs->status = $request->status ?? 'opened';
                $HazardObs->save();

                // Update any temporary images
                if ($HazardObs->id) {
                    HazardObsImage::where('hazard_obs_id', 0)
                        ->where('customer_id', $auth_id)
                        ->where('workspace_id', $workspace_id)
                        ->update(['hazard_obs_id' => $HazardObs->id]);
                }

                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'New Hazard OBS record created successfully',
                    'report_id' => $HazardObs->id,
                    'report_type' => 'hazard_obs'
                ]);

                return $this->success($HazardObs, 'Hazard OBS record created successfully.');
            } else {
                // Update existing record
                $HazardObs = HazardObs::where('id', $hazard_obs_id)
                    ->where('customer_id', $auth_id)
                    ->where('workspace_id', $workspace_id)
                    ->first();

                if (!$HazardObs) {
                    return $this->error('Hazard OBS record not found or you do not have access to it.', 404);
                }

                $HazardObs->closed_by = $request->closed_by_id ?? 0;
                $HazardObs->site_id = $request->site_id;
                $HazardObs->description = $request->description;
                $HazardObs->status = $request->status ?? 'opened';
                $HazardObs->save();

                // Update any temporary images
                HazardObsImage::where('hazard_obs_id', 0)
                    ->where('customer_id', $auth_id)
                    ->where('workspace_id', $workspace_id)
                    ->update(['hazard_obs_id' => $HazardObs->id]);

                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Hazard OBS record updated successfully',
                    'report_id' => $hazard_obs_id,
                    'report_type' => 'hazard_obs'
                ]);

                return $this->success($HazardObs, 'Hazard OBS record updated successfully.');
            }
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS store error: ' . $shortMessage,
                'report_id' => $request->hazard_obs_id ?? 0,
                'report_type' => 'hazard_obs',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while saving the Hazard OBS record: ' . $e->getMessage(), 500);
        }
    }

    public function hazardOBSImageStore(Request $request)
    {
        try {
            // Get user context
            $userTable = $this->getUserTable();
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;
            } else if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            } else {
                return $this->error('Unauthorized access.', 403);
            }

            // Validate request
            $validator = Validator::make($request->all(), [
                'hazard_obs_id' => 'required',
                'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:10240',
            ], [
                'image.required' => 'Image is required',
                'image.image' => 'The file must be an image',
                'image.mimes' => 'The image must be a file of type: jpeg, png, jpg, gif, svg',
                'image.max' => 'The image may not be greater than 10MB'
            ]);

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

            // Check image count limit
            $hazard_obs_image_count = HazardObsImage::where("hazard_obs_id", $request->hazard_obs_id)
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->count();

            if ($hazard_obs_image_count >= 5) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Maximum image limit reached',
                    'report_id' => $request->hazard_obs_id,
                    'report_type' => 'hazard_obs',
                    'error_type' => 'Limit error'
                ]);
                return $this->error('You have reached maximum image upload limit of 5 per report.', 400);
            }

            if ($request->hasFile('image') && $request->file('image')->isValid()) {
                // Generate unique filename
                $filename = time() . '_' . uniqid() . '.' . $request->file('image')->getClientOriginalExtension();

                // Create directory if it doesn't exist
                $directory = public_path('uploads/hazard_obs_images');
                if (!file_exists($directory)) {
                    mkdir($directory, 0777, true);
                }

                // Move uploaded file
                $request->file('image')->move($directory, $filename);
                $imagePath = 'uploads/hazard_obs_images/' . $filename;

                // Save image record
                $image = new HazardObsImage();
                $image->image = $imagePath;
                $image->hazard_obs_id = $request->hazard_obs_id;
                $image->customer_id = $auth_id;
                $image->workspace_id = $workspace_id;
                $image->save();

                // Get all images for the hazard obs
                $images = HazardObsImage::where('hazard_obs_id', $request->hazard_obs_id)
                    ->where('customer_id', $auth_id)
                    ->where('workspace_id', $workspace_id)
                    ->get()
                    ->map(function ($item) {
                        if (!empty($item->image)) {
                            $item->image_url = url($item->image);
                        } else {
                            $item->image_url = '';
                        }
                        return $item;
                    });

                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Image uploaded successfully',
                    'report_id' => $request->hazard_obs_id,
                    'report_type' => 'hazard_obs'
                ]);

                return $this->success([
                    'image_url' => url($imagePath),
                    'images' => $images
                ], 'Image uploaded successfully');
            }

            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'No valid image uploaded',
                'report_id' => $request->hazard_obs_id,
                'report_type' => 'hazard_obs',
                'error_type' => 'Upload error'
            ]);
            return $this->error('No valid image uploaded', 400);
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Image upload error: ' . $shortMessage,
                'report_id' => $request->hazard_obs_id ?? 0,
                'report_type' => 'hazard_obs',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while uploading the image: ' . $e->getMessage(), 500);
        }
    }

    public function whsHazardOBSDelete($id)
    {
        try {
            // Get user context
            $userTable = $this->getUserTable();
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;
            } else if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            } else {
                return $this->error('Unauthorized access.', 403);
            }

            if (!$id) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Record ID Not found',
                    'report_id' => 0,
                    'report_type' => 'hazard_obs',
                    'error_type' => 'Validation error'
                ]);
                return $this->error('Record ID is required.', 422);
            }

            // Check if record exists and belongs to user
            $hazardObs = HazardObs::where('id', $id)
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->first();

            if (!$hazardObs) {
                return $this->error('Hazard OBS record not found or you do not have access to it.', 404);
            }

            // Delete associated images first
            $images = HazardObsImage::where('hazard_obs_id', $id)->get();
            foreach ($images as $image) {
                if (!empty($image->image)) {
                    $imagePath = public_path($image->image);
                    if (file_exists($imagePath)) {
                        unlink($imagePath);
                    }
                }
            }
            HazardObsImage::where('hazard_obs_id', $id)->delete();

            // Delete the hazard obs record
            $status = $hazardObs->delete();

            if ($status) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Hazard OBS record deleted successfully',
                    'report_id' => $id,
                    'report_type' => 'hazard_obs'
                ]);
                return $this->success(1, 'Hazard OBS record deleted successfully.');
            }

            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Failed to delete Hazard OBS record',
                'report_id' => $id,
                'report_type' => 'hazard_obs',
                'error_type' => 'Delete error'
            ]);
            return $this->error('Failed to delete Hazard OBS record.', 500);

        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS delete error: ' . $shortMessage,
                'report_id' => $id ?? 0,
                'report_type' => 'hazard_obs',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while deleting the Hazard OBS record: ' . $e->getMessage(), 500);
        }
    }

    public function whsHazardOBSDeleteImage($id)
    {
        try {
            // Get user context
            $userTable = $this->getUserTable();
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;
            } else if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            } else {
                return $this->error('Unauthorized access.', 403);
            }
            if (!$id) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Image ID Not found',
                    'report_id' => 0,
                    'report_type' => 'hazard_obs',
                    'error_type' => 'Validation error'
                ]);
                return $this->error('Image ID is required.', 422);
            }
            // Check if image exists and belongs to user
            $image = HazardObsImage::where('id', $id)
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->first();

            if (!$image) {
                return $this->error('Image not found or you do not have access to it.', 404);
            }
            // Delete the image file
            if (!empty($image->image)) {
                $imagePath = public_path($image->image);
                if (file_exists($imagePath)) {
                    unlink($imagePath);
                }
            }
            // Delete the image record
            $status = $image->delete();
            if ($status) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Hazard OBS image deleted successfully',
                    'report_id' => $image->hazard_obs_id,
                    'report_type' => 'hazard_obs'
                ]);
                return $this->success($id, 'Hazard OBS image deleted successfully.');
            }
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Failed to delete Hazard OBS image',
                'report_id' => $image->hazard_obs_id,
                'report_type' => 'hazard_obs',
                'error_type' => 'Delete error'
            ]);
            return $this->error('Failed to delete Hazard OBS image.', 500);

        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS image delete error: ' . $shortMessage,
                'report_id' => $id ?? 0,
                'report_type' => 'hazard_obs',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while deleting the Hazard OBS image: ' . $e->getMessage(), 500);
        }
    }
    
    public function updateHazardOBSStatus($id)
    {
        try {
            // Get user context
            $userTable = $this->getUserTable();
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;
            } else if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            } else {
                return $this->error('Unauthorized access.', 403);
            }
            if (!$id) {
                storeReportsLogs([
                    'employee_id' => auth()->user()->id,
                    'message' => 'Hazard OBS ID Not found',
                    'report_id' => 0,
                    'report_type' => 'hazard_obs',
                    'error_type' => 'Validation error'
                ]);
                return $this->error('Hazard OBS ID is required.', 422);
            }
            // Check if record exists and belongs to user
            $hazardObs = HazardObs::where('id', $id)
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->first();

            if (!$hazardObs) {
                return $this->error('Hazard OBS record not found or you do not have access to it.', 404);
            }
            // Toggle status
            $current_status = $hazardObs->status;
            $status_to_be = ($current_status === 'opened') ? 'closed' : 'opened';
            // Update status
            $hazardObs->status = $status_to_be;
            $hazardObs->save();
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => "Hazard OBS status updated from {$current_status} to {$status_to_be}",
                'report_id' => $id,
                'report_type' => 'hazard_obs'
            ]);
            return $this->success($hazardObs, "Hazard OBS status updated from {$current_status} to {$status_to_be}.");
        } catch (\Throwable $e) {
            $shortMessage = substr($e->getMessage(), 0, 200) . (strlen($e->getMessage()) > 200 ? '...' : '');
            storeReportsLogs([
                'employee_id' => auth()->user()->id,
                'message' => 'Hazard OBS status update error: ' . $shortMessage,
                'report_id' => $id ?? 0,
                'report_type' => 'hazard_obs',
                'error_type' => 'Exception error'
            ]);
            return $this->error('An error occurred while updating the Hazard OBS status: ' . $e->getMessage(), 500);
        }
    }
}
