<?php

namespace App\Http\Controllers;

use App\Models\Sites;
use Illuminate\Http\Request;
use App\Models\SiteSafetyAudit;
use App\Models\EmpCompanyDetails;
use App\Models\EmpPersonalDetails;
use App\Models\SafetyAuditDetails;
use Illuminate\Support\Facades\DB;
use App\Models\SafetyAuditReportImage;
use App\Models\SafetyAuditReportImages;
use Illuminate\Support\Facades\Validator;
use Barryvdh\DomPDF\Facade\Pdf;
use App\Models\GeneratedPdfReport;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Auth;

class SiteSafetyAuditController extends Controller
{
    public function siteSafetyIndex(Request $request)
    {
        $userTable = $this->getUserTable();
        $auth_id = 0;
        $workspace_id = 0;
        if ($userTable === "customer") {
            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;
        }
        if ($userTable === "emp") {
            $auth_id = auth()->user()->customer_id;
            $workspace_id = auth()->user()->workspace_id;
        }
        $query = SiteSafetyAudit::query();
        $query->orderBy("id", "DESC")
        ->where('customer_id',  $auth_id)
        ->where('workspace_id',  $workspace_id);
        $query->with("ClosedBy");
        $query->with("SiteData");

        if ($request->filled("filter")) {
            $query = $this->filter(json_decode($request->filter, true), $query);
        }
        $count = $query->count();
        $start = $request->input("from", 0);
        $query->offset($start)->limit(20);
        $query->orderBy("id", "desc");
        $query_result = $query->get();

        $data = [
            "site_safety_audit" => $query_result,
        ];
        return $this->success($data, 'Site safety audit list retrieved successfully');
    }

    public function filter($filters, $query)
    {
        foreach ($filters as $filterName => $filterValue) {
            if ($filterValue != null || $filterValue != "") {
                switch ($filterName) {
                    case "closed_by":
                        $filterValue = explode(" ", $filterValue);
                        if (count($filterValue) == 1) {
                            $query->whereHas("ClosedBy", function (
                                $subquery
                            ) use ($filterValue) {
                                $subquery->where(
                                    "first_name",
                                    "like",
                                    "%" . $filterValue[0] . "%"
                                );
                            });
                        }
                        if (count($filterValue) == 2) {
                            $query->whereHas("ClosedBy", function (
                                $subquery
                            ) use ($filterValue) {
                                $subquery->where(
                                    "first_name",
                                    "like",
                                    "%" . $filterValue[0] . "%"
                                );
                                $subquery->where(
                                    "last_name",
                                    "like",
                                    "%" . $filterValue[1] . "%"
                                );
                            });
                        }
                        if (count($filterValue) == 3) {
                            $query->whereHas("ClosedBy", function (
                                $subquery
                            ) use ($filterValue) {
                                $subquery->where(
                                    "first_name",
                                    "like",
                                    "%" . $filterValue[0] . "%"
                                );
                                $subquery->where(
                                    "middle_name",
                                    "like",
                                    "%" . $filterValue[1] . "%"
                                );
                                $subquery->where(
                                    "last_name",
                                    "like",
                                    "%" . $filterValue[2] . "%"
                                );
                            });
                        }
                        break;
                    case "job_number":
                        $query->where(
                            "job_number",
                            "like",
                            "%" . $filterValue . "%"
                        );
                        break;
                    case "start_date":
                        $query->where(
                            "start_date",
                            "like",
                            "%" . $filterValue . "%"
                        );
                        break;
                    case "site":
                        $query->whereHas("SiteData", function ($subquery) use (
                            $filterValue
                        ) {
                            $subquery->where(
                                "title",
                                "like",
                                "%" . $filterValue . "%"
                            );
                        });
                        break;
                }
            }
        }
        return $query;
    }
    public function siteSafetyAudit()
    {
        return view("SiteSafetyAudit.site-safety-audit-list");
    }
    public function siteSafetyAuditCreate()
    {
        SafetyAuditDetails::whereNull('safety_audit_id')->delete();
        SafetyAuditReportImage::whereNull('safety_audit_details_id')->delete();

        return view("SiteSafetyAudit.newSiteSafetyAudit.new-report");
    }
    public function siteSafetyAuditStepData(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "site_safety_audit" => "required",
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        try {
            $validatedData = $validator->validated();

            $site_safety_audit = SiteSafetyAudit::where(
                "id",
                $request->site_safety_audit
            )->first();

            $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")
                ->get();

            $authorised_by_list = $emp_list;
            $data["sites"] = DB::table("sites")
                ->where("active", "1")
                ->where("del", 0)
                ->get(["id", "title"]);

            $data["site_safety_audit"] = $site_safety_audit;
            $data["authorised_by_list"] = $authorised_by_list;

            return $this->success($data, 'Site safety audit list retrieved successfully');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function siteSafetyAuditStepSave(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "site_safety_audit" => "required",
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        try {
            $validatedData = $validator->validated();

            $userTable = $this->getUserTable();
            $auth_id = 0;
            $workspace_id = 0;
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;
            }
            if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
            }

            $data = [
                "job_number" => $request->job_number,
                "site_id" => $request->site_id,
                "closed_by" => $request->closed_by,
                "opened_by" => $request->opened_by,
                "start_date" => $request->start_date,
                "start_time" => $request->start_time,
                "end_time" => $request->end_time,
                "general_notes" => $request->general_notes,
                "customer_id" => $auth_id,
                "workspace_id" => $workspace_id,
            ];

            $site = Sites::where('id', $request->site_id)->first();
            $data['site_name'] = $site ? $site->title : 'Unknown';

            $users=[$request->closed_by,$request->opened_by];

            $userEmails = [];
            foreach ($users as $userId) {
                $userDetails = EmpCompanyDetails::where('id', $userId)->first();

                if ($userDetails && $userDetails->employee_email) {
                    $userEmails[] = [
                        'id' => $userId,
                        'email' => $userDetails->employee_email
                    ];
                }
            }

            foreach ($userEmails as $userInfo) {
                $openedByUser = EmpPersonalDetails::where('emp_id', $data['opened_by'])->first();
                $closedByUser = EmpPersonalDetails::where('emp_id', $data['closed_by'])->first();
                
                $opened_by_name = $openedByUser ? $openedByUser->first_name.' '.$openedByUser->middle_name.' '.$openedByUser->last_name : 'Unknown';
                $closed_by_name = $closedByUser ? $closedByUser->first_name.' '.$closedByUser->middle_name.' '.$closedByUser->last_name : 'Unknown';
                $data['opened_by_name']=$opened_by_name;
                $data['closed_by_name']=$closed_by_name;
                $params = [
                    'subject' => 'Site Safety Audit Notification | ' . env("APP_NAME"),
                    'to' => $userInfo['email'],
                    'blade' => view('Emails/site_safety_audit', [
                        'data' => $data,
                    ])->render()
                ];
                
                $emailSent = $this->SendInstantEmail($params);
            }
           
            unset($data['closed_by_name'],$data['opened_by_name'],$data['site_name']);

            $siteSafetyAudit = SiteSafetyAudit::updateOrCreate(
                ["id" => $request->site_safety_audit],
                $data
            );
            if ($siteSafetyAudit) {
                SafetyAuditReportImage::where("safety_audit_id", 0)->update([
                    "safety_audit_id" => $siteSafetyAudit->id,
                    "customer_id" => $auth_id,
                    "workspace_id" => $workspace_id,
                ]);

                SafetyAuditDetails::where("safety_audit_id", 0)->update([
                    "safety_audit_id" => $siteSafetyAudit->id,
                    "customer_id" => $auth_id,
                    "workspace_id" => $workspace_id,
                ]);
                SafetyAuditReportImage::Where("unsigned_images", 1)->update([
                    "unsigned_images" => 0,
                ]);
                if (is_string($request->card_data)) {
                    $cardData = json_decode($request->card_data, true);
                } else {
                    $cardData = $request->card_data;
                }
                if (is_array($cardData)) {
                    foreach ($cardData as $card) {
                        $safetyAuditDetail = SafetyAuditDetails::find(
                            $card["id"]
                        );

                        if ($safetyAuditDetail) {
                            $safetyAuditDetail->update([
                                "safety_audit_id" => $siteSafetyAudit->id,
                                "hazard_identified_details" =>
                                    $card["hazard_identified_details"],
                                "action_taken_details" =>
                                    $card["action_taken_details"],
                                "customer_id" => $auth_id,
                                "workspace_id" => $workspace_id,
                            ]);
                        }
                    }
                }
            }
            return $this->success($siteSafetyAudit->id, 'Saved Successfully');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function siteSafetyAuditImageStore(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "site_safety_audit" => "required",
            "image" => "required|image|mimes:jpeg,png,jpg,gif,svg|max:10248",
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $userTable = $this->getUserTable();
        $auth_id = 0;
        $workspace_id = 0;
        if ($userTable === "customer") {
            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;
        }
        if ($userTable === "emp") {
            $auth_id = auth()->user()->customer_id;
            $workspace_id = auth()->user()->workspace_id;
        }

        if ($request->hasFile("image") && $request->file("image")->isValid()) {
            $cardId = $request->cardId ?? 0;
            $site_safety_audit = $request->site_safety_audit ?? 0;

            $imagePath = $request->file('image')->store('upload/safety_audit_images', 'public');

            $image = new SafetyAuditReportImage();
            $image->image = $imagePath;
            $image->safety_audit_details_id = $cardId;
            $image->safety_audit_id = $site_safety_audit;
            $image->unsigned_images = 1;
            $image->customer_id = $auth_id;
            $image->workspace_id = $workspace_id;
            $image->save();

            $images = SafetyAuditReportImage::where(
                "safety_audit_id",
                $request->site_safety_audit
            )
                ->where("id", $image->id ?? 0)
                ->get();

            $image_url = $image;

            return $this->success($image_url, 'Image uploaded successfully!');

        } else {
            return $this->error('No valid image uploaded.');
        }
    }

    public function saveAuditDetails(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "site_safety_audit" => "required",
            "actionDetails" => "required",
            "hazardDetails" => "required",
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $userTable = $this->getUserTable();
        $auth_id = 0;
        $workspace_id = 0;
        if ($userTable === "customer") {
            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;
        }
        if ($userTable === "emp") {
            $auth_id = auth()->user()->customer_id;
            $workspace_id = auth()->user()->workspace_id;
        }

        $site_safety_audit_id = $request->site_safety_audit;
        $actionDetails = $request->actionDetails;
        $hazardDetails = $request->hazardDetails;
        $cardId = $request->cardId;
        $id = $request->id ?? 0;

        if (empty($actionDetails) || empty($hazardDetails)) {
            return $this->error('Action details and hazard details are required.');
        }

        $auditDetailsOld = SafetyAuditDetails::where("id", $id)
            ->where("safety_audit_id", $site_safety_audit_id)
            ->where("hazard_identified_details", $hazardDetails)
            ->where("action_taken_details", $actionDetails)
            ->first();

        if ($auditDetailsOld) {
            $auditDetailsOld->safety_audit_id = $site_safety_audit_id;
            $auditDetailsOld->hazard_identified_details = $hazardDetails;
            $auditDetailsOld->action_taken_details = $actionDetails;
            $auditDetailsOld->customer_id = $auth_id;
            $auditDetailsOld->workspace_id = $workspace_id;
            $auditDetailsOld->save();

            return $this->success($auditDetailsOld->id, 'Record Updated Successfully.');
        } else {
            $auditDetailsNew = new SafetyAuditDetails();
            $auditDetailsNew->safety_audit_id = $site_safety_audit_id;
            $auditDetailsNew->hazard_identified_details = $hazardDetails;
            $auditDetailsNew->action_taken_details = $actionDetails;
            $auditDetailsNew->customer_id = $auth_id;
            $auditDetailsNew->workspace_id = $workspace_id;
            $auditDetailsNew->save();

            SafetyAuditReportImage::whereNull("safety_audit_details_id")
                ->orWhere("safety_audit_details_id", 0)
                ->orWhere("unsigned_images", 1)
                ->update([
                    "safety_audit_details_id" => $auditDetailsNew->id ?? 0,
                    "unsigned_images" => 0,
                    "customer_id" => $auth_id,
                    "workspace_id" => $workspace_id,
                ]);

            return $this->success($auditDetailsNew->id, 'Record Saved Successfully!!');
        }
    }
    public function siteSafetyDelete($id)
    {
        if ($id) {
            SiteSafetyAudit::where("id", $id)->delete();
            SafetyAuditDetails::where("safety_audit_id", $id)->update([
                "delete" => "1",
            ]);
            SafetyAuditReportImage::where("safety_audit_id", $id)->update([
                "delete" => "1",
            ]);
            return $this->success($id, 'Report deleted successfully.');
        } else {
            return $this->error('Report Delete Failed.');
        }
    }

    public function getAuditDetails(Request $request)
    {
        $safety_audit_report = $request->site_safety_audit;

        $auditDetails = SafetyAuditDetails::where(
            "safety_audit_id",
            $safety_audit_report
        )
            ->where("delete", "0")
            ->with([
                "images" => function ($query) use ($safety_audit_report) {
                    $query
                        ->where("safety_audit_id", $safety_audit_report)
                        ->where("delete", "0");
                },
            ])
            ->get();
            $auditDetails = $auditDetails->map(function ($item) {
                if ($item->images->isNotEmpty()) {
                    $item->images = $item->images->map(function ($image) {
                        $image->signed_image_url = $image->image;
                        return $image;
                    });
                } else {
                    $item->images = [];
                }
            
                return $item;
            });
                    
            $data = [
                'cards' => $auditDetails->map(function ($detail) {
                    return [
                        "id" => $detail->id,
                        "hazard_identified_details" => $detail->hazard_identified_details,
                        "action_taken_details" => $detail->action_taken_details,
                        "images" => $detail->images,
                    ];
                })
            ];
            return $this->success($data, 'Site safety audit list retrieved successfully');
    }

    public function siteSafetyAuditImageDelete(Request $request)
    {
        if ($request->image_id) {
            SafetyAuditReportImage::where("id", $request->image_id)->update([
                "delete" => "1",
            ]);

            return $this->success($request->image_id, 'Image deleted successfully.');

        } else {
            return $this->error('Image Delete Failed.');
        }
    }
    public function siteSafetyAuditCardDelete(Request $request)
    {
        if ($request->cardId) {
            $cardIds = $request->get("cardId");
            $cardIds = (int) $cardIds;

            SafetyAuditDetails::where("id", $cardIds)->update([
                "delete" => "1",
            ]);
            SafetyAuditReportImage::where(
                "safety_audit_details_id",
                $cardIds
            )->update(["delete" => "1"]);

            return $this->success($request->cardId, 'Card deleted successfully.');
        } else {
            return $this->error('Card Delete Failed.');
        }
    }

    public function site_safty_audit_pdf($id)
    {
        $userTable = $this->getUserTable();
        $auth_id = 0;
        $workspace_id = 0;
        if ($userTable === "customer") {
            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;
        }
        if ($userTable === "emp") {
            $auth_id = auth()->user()->customer_id;
            $workspace_id = auth()->user()->workspace_id;
        }

        $siteSafetyAudit = SiteSafetyAudit::with([
            'safetyAuditDetails' => function($query) {
                $query->where('delete', '0')->orderBy('id', 'asc');
            }, 
            'safetyAuditReportImages' => function($query) {
                $query->where('delete', '0')->orderBy('id', 'asc');
            }
        ])
        ->where('customer_id', $auth_id)
        ->where('workspace_id', $workspace_id)
        ->findOrFail($id);

        $site = Sites::where('id', $siteSafetyAudit->site_id)->first();
        $site_name = $site ? $site->title : 'Unknown';

        $openedByUser = EmpPersonalDetails::where('emp_id', $siteSafetyAudit->opened_by)->first();
        $closedByUser = EmpPersonalDetails::where('emp_id', $siteSafetyAudit->closed_by)->first();
        $data = [
            'siteSafetyAudit' => $siteSafetyAudit,
            'open_by' => trim(($openedByUser->first_name ?? '') . ' ' . ($openedByUser->middle_name ?? '') . ' ' . ($openedByUser->last_name ?? '')),
            'close_by' => trim(($closedByUser->first_name ?? '') . ' ' . ($closedByUser->middle_name ?? '') . ' ' . ($closedByUser->last_name ?? '')),
            'site_name' => $site_name,
            'safety_audit_details' => $siteSafetyAudit->safetyAuditDetails->map(function($detail) {
                $images = $detail->safetyAuditReportImages ?? collect([]);
                return [
                    'id' => $detail->id,
                    'hazard_identified_details' => $detail->hazard_identified_details,
                    'action_taken_details' => $detail->action_taken_details,
                    'images' => $images->map(function($image) {
                        return [
                            'id' => $image->id,
                            'image_url' => $image->image,
                            'signed_image_url' => $image->image
                        ];
                    })->toArray()
                ];
            })->toArray()
        ];

        return $this->success($data, 'Site safety audit data retrieved successfully');
    }
}
