<?php

namespace Workdo\MobileServiceManagement\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

use Workdo\MobileServiceManagement\DataTables\MobileServiceRequestDataTable;

use Workdo\MobileServiceManagement\Entities\MobileServiceRequest;
use Workdo\MobileServiceManagement\Entities\MobileServiceTrackingStatus;
use Workdo\MobileServiceManagement\Entities\MobileServiceLiveTracking;
use Workdo\MobileServiceManagement\Entities\AssignTechnician;
use Workdo\MobileServiceManagement\Entities\MobileService;
use Workdo\MobileServiceManagement\Entities\MobileServiceBrand;

use Workdo\MobileServiceManagement\Events\CreateMobileServiceRequest;
use Workdo\MobileServiceManagement\Events\UpdateMobileServiceRequest;
use Workdo\MobileServiceManagement\Events\UpdateMobileServiceLiveTrackingData;
use Workdo\MobileServiceManagement\Events\DestroyMobileServiceRequest;
use Workdo\MobileServiceManagement\Events\DestroyMobileServiceLiveTrackingData;
use Workdo\MobileServiceManagement\Events\DestroyMobileServiceAssignTechnicianData;
use Workdo\MobileServiceManagement\Events\EndMobileServiceRequest;
use Workdo\MobileServiceManagement\Events\UpdateMobileServiceAssignTechnicianData;

class MobileServiceRequestController extends Controller
{
    public function index(MobileServiceRequestDataTable $dataTable, Request $request)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest manage')) {
            return $dataTable->render('mobile-service-management::service-request.index');
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function create()
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest create')) {
            $allServices = MobileService::where('created_by', creatorId())
                ->where('workspace', getActiveWorkSpace())
                ->where('is_active', true)
                ->get();

            $brands = MobileServiceBrand::where('created_by', creatorId())
                ->where('workspace', getActiveWorkSpace())
                ->get();
            return view('mobile-service-management::service-request.create', compact('allServices', 'brands'));
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function store(Request $request)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest create')) {
            $validator = Validator::make($request->all(), [
                'customer_name'     => 'required|string',
                'email'             => 'required|email',
                'mobile_no'         => 'required|string',
                'address'           => 'nullable|string',
                'mobile_service_id' => 'required',
                'device_brand'      => 'required|exists:mobile_service_brands,id',
                'mobile_model'      => 'required|string',
                'priority'          => 'required|in:standard,priority,emergency',
                'description'       => 'required|string',
            ]);

            if ($validator->fails()) {
                $messages = $validator->getMessageBag();
                return redirect()->back()->with('error', $messages->first());
            }

            $url = null;
            if ($request->file('attachments')) {
                $uploadedPaths = [];
                foreach ($request->file('attachments') as $index => $file) {
                    $ext             = $file->getClientOriginalExtension();
                    $fileNameToStore = time() . '_' . $index . '.' . $ext;
                    $path            = multi_upload_file($file, 'attachment', $fileNameToStore, 'mobileservice/');
                    if ($path['flag'] == 1) {
                        $uploadedPaths[] = $path['url'];
                    }
                }
                $url = !empty($uploadedPaths) ? implode(',', $uploadedPaths) : null;
            }

            if (Auth::user()->type == 'company') {
                $isApproveStatus = 1;
                $createdbyId     = creatorId();
            } else {
                $isApproveStatus = null;
                $createdbyId     = Auth::user()->id;
            }

            $serviceReqData                      = new MobileServiceRequest();
            $serviceReqData->service_id          = time();
            $serviceReqData->customer_name       = $request->customer_name;
            $serviceReqData->email               = $request->email;
            $serviceReqData->mobile_no           = $request->mobile_no;
            $serviceReqData->address             = $request->address;
            $serviceReqData->mobile_service_id   = $request->mobile_service_id;
            $serviceReqData->device_brand        = $request->device_brand;
            $serviceReqData->mobile_model        = $request->mobile_model;
            $serviceReqData->priority            = $request->priority;
            $serviceReqData->description         = $request->description;
            $serviceReqData->special_requests    = $request->special_requests;
            $serviceReqData->attachment          = $url;
            $serviceReqData->tracking_status     = 'pending';
            $serviceReqData->tracking_status_log = 'pending';
            $serviceReqData->is_approve          = $isApproveStatus;
            $serviceReqData->workspace_id        = getActiveWorkSpace();
            $serviceReqData->created_by          = $createdbyId;
            $serviceReqData->save();

            $company_settings = getCompanyAllSetting();
            if (!empty($company_settings['New Mobile Service Request']) && $company_settings['New Mobile Service Request'] == true) {
                $workspace   = \App\Models\WorkSpace::where('id', getActiveWorkSpace())->where('created_by', creatorId())->first();
                $trackingUrl = route('mobileservice.frontend.index', ['workspaceSlug' => $workspace->slug]). '#tracking';
                $link        = '<a href="' . $trackingUrl . '">Click here to track your courier</a>';

                $uArr = [
                    'service_id'   => $serviceReqData->service_id,
                    'tracking_url' => $link,
                ];

                try {
                    $resp = \App\Models\EmailTemplate::sendEmailTemplate('New Mobile Service Request', [$serviceReqData->email], $uArr);
                } catch (\Exception $e) {
                    $resp['error'] = $e->getMessage();
                }
            }

            event(new CreateMobileServiceRequest($request, $serviceReqData));

            return redirect()->route('mobileservice.service-request.index')->with('success', __('The service request has been created successfully'));
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function show(Request $request, $serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest show')) {
            $serviceId = decrypt($serviceId);

            $serviceReqData = MobileServiceRequest::where('service_id', $serviceId)
                ->where('workspace_id', getActiveWorkSpace())
                ->with('getServiceCreatedName', 'getServiceTrackingStatus', 'getAssignTechnician.getTechnicianDetails')
                ->first();

            if ($serviceReqData) {
                $trackingStatusLog = explode(',', $serviceReqData->tracking_status_log);
                $trackingStatus    = MobileServiceTrackingStatus::where('created_by', creatorId())
                    ->where('workspace', getActiveWorkSpace())
                    ->whereNotIn('id', $trackingStatusLog)
                    ->orderby('order', 'asc')
                    ->limit(1)
                    ->get();

                $currentTrackingStatus = MobileServiceLiveTracking::where('service_id', $serviceId)->pluck('date', 'tracking_status_id');

                $allTrackingStatus = MobileServiceTrackingStatus::where('workspace', getActiveWorkSpace())
                    ->where('created_by', creatorId())
                    ->orderby('order', 'asc')
                    ->get();

                return view('mobile-service-management::service-request.show', compact('serviceReqData', 'trackingStatus', 'allTrackingStatus', 'currentTrackingStatus'));
            } else {
                return redirect()->back()->with('error', __('Service request not found.'));
            }
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function edit(Request $request, $serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest edit')) {
            $serviceId = decrypt($serviceId);

            $serviceReqData = MobileServiceRequest::where('service_id', $serviceId)->where('workspace_id', getActiveWorkSpace())->first();

            if ($serviceReqData) {
                $trackingStatusLog = explode(',', $serviceReqData->tracking_status_log);
                $trackingStatus    = MobileServiceTrackingStatus::where('created_by', creatorId())
                    ->where('workspace', getActiveWorkSpace())
                    ->whereNotIn('id', $trackingStatusLog)
                    ->orderby('order', 'asc')
                    ->limit(1)
                    ->get();

                $allServices = MobileService::where('created_by', creatorId())
                    ->where('workspace', getActiveWorkSpace())
                    ->where('is_active', true)
                    ->get();

                $brands = MobileServiceBrand::where('created_by', creatorId())
                    ->where('workspace', getActiveWorkSpace())
                    ->get();

                return view('mobile-service-management::service-request.edit', compact('serviceReqData', 'trackingStatus', 'allServices', 'brands'));
            } else {
                return redirect()->back()->with('error', __('Service request not found.'));
            }
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function update(Request $request, $serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest edit')) {
            $validator = Validator::make($request->all(), [
                'customer_name'     => 'required|string',
                'mobile_no'         => 'required|string',
                'email'             => 'required|email',
                'priority'          => 'required|in:standard,priority,emergency',
                'mobile_service_id' => 'required',
                'device_brand'      => 'required|exists:mobile_service_brands,id',
                'mobile_model'      => 'required|string',
                'description'       => 'required|string',
            ]);

            if ($validator->fails()) {
                $messages = $validator->getMessageBag();
                return redirect()->back()->with('error', $messages->first());
            }

            $serviceId      = decrypt($serviceId);
            $serviceReqData = MobileServiceRequest::where('service_id', $serviceId)
                ->where('workspace_id', getActiveWorkSpace())
                ->first();

            if ($serviceReqData) {
                $serviceReqData->customer_name     = $request->customer_name;
                $serviceReqData->mobile_no         = $request->mobile_no;
                $serviceReqData->email             = $request->email;
                $serviceReqData->address           = $request->address;
                $serviceReqData->mobile_service_id = $request->mobile_service_id;
                $serviceReqData->device_brand      = $request->device_brand;
                $serviceReqData->mobile_model      = $request->mobile_model;
                $serviceReqData->priority          = $request->priority;
                $serviceReqData->description       = $request->description;
                $serviceReqData->special_requests  = $request->special_requests;

                if ($request->file('attachments')) {
                    $uploadedPaths = [];
                    foreach ($request->file('attachments') as $index => $file) {
                        $ext             = $file->getClientOriginalExtension();
                        $fileNameToStore = time() . '_' . $index . '.' . $ext;
                        $path            = multi_upload_file($file, 'attachment', $fileNameToStore, 'mobileservice/');
                        if ($path['flag'] == 1) {
                            $uploadedPaths[] = $path['url'];
                        }
                    }

                    if (!empty($uploadedPaths)) {
                        $newAttachments = implode(',', $uploadedPaths);
                        if (!empty($serviceReqData->attachment)) {
                            $serviceReqData->attachment = $serviceReqData->attachment . ',' . $newAttachments;
                        } else {
                            $serviceReqData->attachment = $newAttachments;
                        }
                    }
                }

                if (Auth::user()->isAbleTo('mobileservice_servicerequest livetracking manage')) {
                    if ($request->has('tracking_status')) {
                        $serviceReqData->tracking_status = $request->tracking_status;
                        if ($serviceReqData->tracking_status_log == 'pending') {
                            $serviceReqData->tracking_status_log = $request->tracking_status;
                        } else {
                            $serviceReqData->tracking_status_log = $serviceReqData->tracking_status_log . ',' . $request->tracking_status;
                        }

                        if ($request->tracking_status != null) {
                            $liveTrackingData                     = new MobileServiceLiveTracking;
                            $liveTrackingData->service_id         = $serviceId;
                            $liveTrackingData->tracking_status_id = $request->tracking_status;
                            $liveTrackingData->date               = now();
                            $liveTrackingData->workspace_id       = getActiveWorkSpace();
                            $liveTrackingData->created_by         = creatorId();
                            $liveTrackingData->save();

                            event(new UpdateMobileServiceLiveTrackingData($serviceReqData, $liveTrackingData));
                        }
                    }
                }
                $serviceReqData->save();

                event(new UpdateMobileServiceRequest($request, $serviceReqData));

                return redirect()->route('mobileservice.service-request.index')->with('success', __('The service request details are updated successfully'));
            } else {
                return redirect()->back()->with('error', __('Service request not found.'));
            }
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function destroy($serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest delete')) {
            $serviceId      = decrypt($serviceId);
            $serviceReqData = MobileServiceRequest::where('service_id', $serviceId)
                ->where('workspace_id', getActiveWorkSpace())
                ->first();

            if ($serviceReqData) {
                event(new DestroyMobileServiceRequest($serviceReqData));

                // Delete multiple attachments
                if (!empty($serviceReqData->attachment)) {
                    $attachments = explode(',', $serviceReqData->attachment);
                    foreach ($attachments as $attachment) {
                        if (!empty($attachment) && check_file($attachment)) {
                            delete_file($attachment);
                        }
                    }
                }

                // delete data from live tracking table
                $liveTrackingData = MobileServiceLiveTracking::where('service_id', $serviceId)->get();
                if (count($liveTrackingData) > 0) {
                    event(new DestroyMobileServiceLiveTrackingData($liveTrackingData));
                    foreach ($liveTrackingData as $data) {
                        $data->delete();
                    }
                }

                // delete data from assign_technicians table
                $assignTechnicianData = AssignTechnician::where('service_id', $serviceId)->first();
                if ($assignTechnicianData) {
                    event(new DestroyMobileServiceAssignTechnicianData($assignTechnicianData));
                    $assignTechnicianData->delete();
                }

                // delete request
                $serviceReqData->delete();

                return redirect()->back()->with('success', __('The service request has been deleted'));
            } else {
                return redirect()->back()->with('error', __('Service request not found.'));
            }
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function destroyAttachment(Request $request, $serviceId)
    {
        $serviceReqData = MobileServiceRequest::where('service_id', $serviceId)->where('workspace_id', getActiveWorkSpace())->first();
        if ($serviceReqData) {
            $fileToDelete = $request->input('file');

            if (!empty($fileToDelete) && check_file($fileToDelete)) {
                delete_file($fileToDelete);

                $attachments                = explode(',', $serviceReqData->attachment);
                $attachments                = array_filter($attachments, fn($file) => $file !== $fileToDelete);
                $serviceReqData->attachment = implode(',', $attachments);
                $serviceReqData->save();

                return response()->json([
                    'success' => true,
                    'message' => __('Attachment deleted successfully')
                ]);

            } else {
                return response()->json([
                    'success' => false,
                    'message' => __('Attachment not found.')
                ]);
            }
        } else {
            return response()->json([
                'success' => false,
                'message' => __('Service request not found.')
            ]);
        }
    }

    public function updateTrackingStatus(Request $request, $serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest livetracking manage')) {
            $validator = Validator::make($request->all(), [
                'tracking_status' => 'required|exists:mobile_service_tracking_statuses,id'
            ]);

            if ($validator->fails()) {
                $messages = $validator->getMessageBag();
                return redirect()->back()->with('error', $messages->first());
            }

            $serviceId      = decrypt($serviceId);
            $serviceReqData = MobileServiceRequest::where('service_id', $serviceId)
                ->where('workspace_id', getActiveWorkSpace())
                ->first();

            if ($serviceReqData) {
                $serviceReqData->tracking_status = $request->tracking_status;
                if ($serviceReqData->tracking_status_log == 'pending') {
                    $serviceReqData->tracking_status_log = $request->tracking_status;
                } else {
                    $serviceReqData->tracking_status_log = $serviceReqData->tracking_status_log . ',' . $request->tracking_status;
                }
                $serviceReqData->save();

                $liveTrackingData                     = new MobileServiceLiveTracking;
                $liveTrackingData->service_id         = $serviceId;
                $liveTrackingData->tracking_status_id = $request->tracking_status;
                $liveTrackingData->date               = now();
                $liveTrackingData->workspace_id       = getActiveWorkSpace();
                $liveTrackingData->created_by         = creatorId();
                $liveTrackingData->save();

                event(new UpdateMobileServiceLiveTrackingData($serviceReqData, $liveTrackingData));

                return redirect()->back()->with('success', __('The tracking status has been updated successfully'));
            } else {
                return redirect()->back()->with('error', __('Service request not found.'));
            }
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function endRequest($serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest end')) {
            $serviceId      = decrypt($serviceId);
            $serviceReqData = MobileServiceRequest::where('service_id', $serviceId)
                ->where('workspace_id', getActiveWorkSpace())
                ->first();

            if ($serviceReqData) {
                $serviceReqData->is_repair_end = 1;
                $serviceReqData->save();

                event(new EndMobileServiceRequest($serviceReqData));

                return redirect()->route('mobileservice.service-request.index')->with('success', __('The service request has been ended successfully'));
            } else {
                return redirect()->back()->with('error', __('Service request not found.'));
            }
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }

    public function assignTechnicianCreate($serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest technician assign')) {
            $serviceId = decrypt($serviceId);

            $technicians = \App\Models\User::where('workspace_id', '=', getActiveWorkSpace())
                ->where('created_by', '=', creatorId())
                ->emp()
                ->pluck('name', 'id');
            $technicians->prepend(__('Select Technician'), '');

            return view('mobile-service-management::service-request.technician-assign', compact('serviceId', 'technicians'));
        } else {
            return response()->json(['error' => __('Permission denied.')], 401);
        }
    }

    public function assignTechnicianStore(Request $request, $serviceId)
    {
        if (Auth::user()->isAbleTo('mobileservice_servicerequest technician assign')) {
            $validator = Validator::make($request->all(), [
                'technician_id'  => 'required|exists:users,id',
                'estimated_date' => 'required|date',
            ]);

            if ($validator->fails()) {
                $messages = $validator->getMessageBag();
                return redirect()->back()->with('error', $messages->first());
            }

            $serviceId = decrypt($serviceId);

            $assignTechnicianData = AssignTechnician::updateOrInsert(
                ['service_id' => $serviceId],
                [
                    'service_id'      => $serviceId,
                    'technician_id'   => $request->technician_id,
                    'completion_date' => $request->estimated_date,
                    'workspace_id'    => getActiveWorkSpace(),
                    'created_by'      => creatorId(),
                ]
            );

            $mobileServiceReq = MobileServiceRequest::where('service_id', $serviceId)->where('workspace_id', getActiveWorkSpace())->first();
            $mobileServiceReq->is_technician_asign = 1;
            $mobileServiceReq->save();

            event(new UpdateMobileServiceAssignTechnicianData($mobileServiceReq, $assignTechnicianData));

            return redirect()->route('mobileservice.service-request.index')->with('success', __('The technician has been assigned successfully'));
        } else {
            return redirect()->back()->with('error', __('Permission denied.'));
        }
    }
}
