<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\CsvImportTrait;
use App\Http\Requests\MassDestroyServiceComplaintRequest;
use App\Http\Requests\StoreServiceComplaintRequest;
use App\Http\Requests\UpdateServiceComplaintRequest;
use App\Models\Asset;
use App\Models\ContactCompany;
use App\Models\ContactContact;
use App\Models\FusionType;
use App\Models\ServiceComplaint;
use App\Models\ChecklistReport;
use App\Models\Team;
use App\Models\User;
use App\Models\Product;
use App\Models\UserSignature;
use Barryvdh\DomPDF\PDF as DomPDFPDF;
use PDF;
use Gate;
use GuzzleHttp\Psr7\Uri;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
use Yajra\DataTables\Facades\DataTables;

class ServiceComplaintController extends Controller
{
    use CsvImportTrait;

    public function index(Request $request)
    {
        abort_if(Gate::denies('service_complaint_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        //gettng user role
        foreach (Auth::user()->roles as $role){
            $userrole=$role->id;
            $userrolename=$role->name;
        }

        if ($request->ajax()) {
            if(auth()->user()->roles->contains('title', 'Engineer')){
                $query = ServiceComplaint::with(['client', 'location', 'asset', 'service_type', 'visit_type', 'status', 'enginner_assigned', 'supervisor_assigned', 'team'])->select(sprintf('%s.*', (new ServiceComplaint)->table))->where('enginner_assigned_id',Auth::user()->id);
            }else {
                $query = ServiceComplaint::with(['client', 'location', 'asset', 'service_type', 'visit_type', 'status', 'enginner_assigned', 'supervisor_assigned', 'team'])->select(sprintf('%s.*', (new ServiceComplaint)->table));
            }


            $table = Datatables::of($query);

            $table->addColumn('placeholder', '&nbsp;');
            $table->addColumn('actions', '&nbsp;');

            $table->editColumn('actions', function ($row) {
                $viewGate      = 'service_complaint_show';
                $editGate      = 'service_complaint_edit';
                $deleteGate    = 'service_complaint_delete';
                $crudRoutePart = 'service-complaints';

                return view('partials.datatablesActions', compact(
                    'viewGate',
                    'editGate',
                    'deleteGate',
                    'crudRoutePart',
                    'row'
                ));
            });

            $table->editColumn('id', function ($row) {
                return $row->id ? $row->id : '';
            });
            $table->addColumn('client_company_name', function ($row) {
                return $row->client ? $row->client->company_name : '';
            });

            $table->addColumn('location_location', function ($row) {
                return $row->location ? $row->location->location : '';
            });

            $table->editColumn('location.location', function ($row) {
                return $row->location ? (is_string($row->location) ? $row->location : $row->location->location) : '';
            });
            $table->addColumn('asset_air_compressor_serial_no', function ($row) {
                return $row->asset ? $row->asset->air_compressor_serial_no : '';
            });

            $table->editColumn('asset.airdryer_serial_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->airdryer_serial_no) : '';
            });
            $table->editColumn('asset.filter_serial_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->filter_serial_no) : '';
            });
            $table->editColumn('asset.eco_drain_serial_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->eco_drain_serial_no) : '';
            });
            $table->editColumn('asset.air_receiver_serial_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->air_receiver_serial_no) : '';
            });
            $table->editColumn('asset.air_compressor_part_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->air_compressor_part_no) : '';
            });
            $table->editColumn('asset.air_dryer_part_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->air_dryer_part_no) : '';
            });
            $table->editColumn('asset.filter_part_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->filter_part_no) : '';
            });
            $table->editColumn('asset.eco_drain_part_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->eco_drain_part_no) : '';
            });
            $table->editColumn('asset.air_reciever_part_no', function ($row) {
                return $row->asset ? (is_string($row->asset) ? $row->asset : $row->asset->air_reciever_part_no) : '';
            });
            $table->addColumn('service_type_name', function ($row) {
                return $row->service_type ? $row->service_type->name : '';
            });

            $table->addColumn('visit_type_name', function ($row) {
                return $row->visit_type ? $row->visit_type->name : '';
            });

            $table->addColumn('status_name', function ($row) {
                return $row->status ? $row->status->name : '';
            });

            $table->addColumn('enginner_assigned_name', function ($row) {
                return $row->enginner_assigned ? $row->enginner_assigned->name : '';
            });

            $table->addColumn('supervisor_assigned_name', function ($row) {
                return $row->supervisor_assigned ? $row->supervisor_assigned->name : '';
            });

            $table->rawColumns(['actions', 'placeholder', 'client', 'location', 'asset', 'service_type', 'visit_type', 'status', 'enginner_assigned', 'supervisor_assigned']);

            return $table->make(true);
        }

        $contact_companies = ContactCompany::get();
        $contact_contacts  = ContactContact::get();
        $assets            = Asset::get();
        $fusion_types      = FusionType::where('fusioncategory_id',9)->get();
        $service_types      = FusionType::where('fusioncategory_id',2)->get();
        $service_visit      = FusionType::where('fusioncategory_id',3)->get();
        $work_status      = FusionType::where('fusioncategory_id',9)->get();
        // If user is an engineer, only get their complaints
        if (auth()->user()->roles->contains('title', 'Engineer')) {
            $users = User::where('id', auth()->id())->get();
        } else {
            $users = User::get();
        }
        $teams             = Team::get();

        return view('admin.serviceComplaints.index', compact('work_status','service_visit','service_types','contact_companies', 'contact_contacts', 'assets', 'fusion_types', 'users', 'teams'));
    }

    public function create()
    {
        abort_if(Gate::denies('service_complaint_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $clients = ContactCompany::all()
            ->map(function ($company) {
                $locations_name = ContactContact::where('company_id', $company->id)
                    ->pluck('location')
                    ->filter()
                    ->implode(', ');

                $displayName = $company->company_name;
                if (!empty($locations_name)) {
                    $displayName .= ' - ' . $locations_name;
                }

                return [$company->id => $displayName];
            })
            ->collapse()
            ->prepend(trans('global.pleaseSelect'), '')
            ->toArray();

        // Fix the client array to match the HTML structure
        // The first option should have empty value with "Please select" text
        // The second option (index 0) should have value "1" instead of empty
        if (array_key_exists(0, $clients)) {
            $firstCompany = $clients[0];
            unset($clients[0]);

            // Reindex the remaining clients to start from 2
            $reindexedClients = [];
            $index = 1;
            foreach ($clients as $id => $name) {
                $reindexedClients[$index] = $name;
                $index++;
            }

            // Create the final array with proper structure
            $clients = ['' => trans('global.pleaseSelect'), '1' => $firstCompany] + $reindexedClients;
        }

        $locations = ContactContact::pluck('location', 'id')->prepend(trans('global.pleaseSelect'), '');

        $assets = Asset::pluck('air_compressor_serial_no', 'id')->prepend(trans('global.pleaseSelect'), '');

        $service_types = FusionType::where('fusioncategory_id',2)->where('id', '!=', 9)->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $visit_types = FusionType::where('fusioncategory_id',3)->where('id', '!=', 14)->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $statuses = FusionType::where('fusioncategory_id',9)->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        //User::whereHas('roles', function($q){$q->where('title', '!=','Slade Industries Technician');}


        $enginner_assigneds = User::whereHas(
            'roles', function($q){
                $q->where('title','Engineer');
            })
            ->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $supervisor_assigneds = User::whereHas(
            'roles', function($q){
                $q->where('title','Supervisor');
            })
            ->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $teams = Team::pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        return view('admin.serviceComplaints.create', compact('assets', 'clients', 'enginner_assigneds', 'locations', 'service_types', 'statuses', 'supervisor_assigneds', 'teams', 'visit_types'));
    }

    public function store(StoreServiceComplaintRequest $request)
    {
        // Handle multiple asset IDs from checkboxes
        $data = $request->all();

        // Process the asset_id array and concatenate values into complaint with # separator
        if (isset($data['asset_id']) && is_array($data['asset_id'])) {
            // Concatenate all asset IDs to the complaint with # separator
            $assetString = implode('#', $data['asset_id']);
            $data['complaint'] = $data['complaint'] . ' #' . $assetString;

            // Extract the first asset ID for the asset_id field
            if (!empty($data['asset_id'][0])) {
                $firstAsset = $data['asset_id'][0];
                // Extract the numeric ID after the underscore
                $parts = explode('_', $firstAsset);
                if (count($parts) > 1) {
                    $data['asset_id'] = $parts[1];
                }
            }
        }

        //dd($data);
        // Check if asset_id is an array (from radio button)


        $serviceComplaint = ServiceComplaint::create($data);

        checklistReport::create(['complaint_id'=>$serviceComplaint->id,'checklist_name_id'=>539]);
        return redirect()->route('admin.service-complaints.index');
    }

    public function edit(ServiceComplaint $serviceComplaint)
    {
        abort_if(Gate::denies('service_complaint_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $clients = ContactCompany::pluck('company_name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $locations = ContactContact::pluck('location', 'id')->prepend(trans('global.pleaseSelect'), '');

        // Get assets filtered by the service complaint's client ID
        $clientId = $serviceComplaint->client_id;
        $assetId = $serviceComplaint->asset_id; // Get the current asset ID for pre-selection
        $assets = Asset::select(
                'assets.id',
                'assets.air_compressor_id',
                'assets.air_compressor_serial_no',
                'assets.air_compressor_part_no',
                'assets.airdryer_id',
                'assets.airdryer_serial_no',
                'assets.air_dryer_part_no',
                'assets.filter_id',
                'assets.filter_serial_no',
                'assets.filter_part_no',
                'assets.eco_drain_id',
                'assets.eco_drain_serial_no',
                'assets.eco_drain_part_no',
                'assets.air_receiver_id',
                'assets.air_receiver_serial_no',
                'assets.air_reciever_part_no',
                'ac.name as air_compressor_name',
                'ad.name as air_dryer_name',
                'f.name as filter_name',
                'ed.name as eco_drain_name',
                'ar.name as air_receiver_name'
            )
            ->leftJoin('products as ac', 'assets.air_compressor_id', '=', 'ac.id')
            ->leftJoin('products as ad', 'assets.airdryer_id', '=', 'ad.id')
            ->leftJoin('products as f', 'assets.filter_id', '=', 'f.id')
            ->leftJoin('products as ed', 'assets.eco_drain_id', '=', 'ed.id')
            ->leftJoin('products as ar', 'assets.air_receiver_id', '=', 'ar.id')
            ->where('assets.client_id', $clientId)
            ->get()
            ->mapWithKeys(function ($asset) {
                $displayText = '';

                if ($asset->air_compressor_id && $asset->air_compressor_name) {
                    $displayText .= $asset->air_compressor_name . ' (SN: ' . $asset->air_compressor_serial_no . ', PN: ' . $asset->air_compressor_part_no . ')';
                }
                if ($asset->airdryer_id && $asset->air_dryer_name) {
                    $displayText .= ($displayText ? ' | ' : '') . $asset->air_dryer_name . ' (SN: ' . $asset->airdryer_serial_no . ', PN: ' . $asset->air_dryer_part_no . ')';
                }
                if ($asset->filter_id && $asset->filter_name) {
                    $displayText .= ($displayText ? ' | ' : '') . $asset->filter_name . ' (SN: ' . $asset->filter_serial_no . ', PN: ' . $asset->filter_part_no . ')';
                }
                if ($asset->eco_drain_id && $asset->eco_drain_name) {
                    $displayText .= ($displayText ? ' | ' : '') . $asset->eco_drain_name . ' (SN: ' . $asset->eco_drain_serial_no . ', PN: ' . $asset->eco_drain_part_no . ')';
                }
                if ($asset->air_receiver_id && $asset->air_receiver_name) {
                    $displayText .= ($displayText ? ' | ' : '') . $asset->air_receiver_name . ' (SN: ' . $asset->air_receiver_serial_no . ', PN: ' . $asset->air_reciever_part_no . ')';
                }

                // If no components were found, use a generic label
                if (empty($displayText)) {
                    $displayText = 'Asset #' . $asset->id . ' (No components)';
                }

                return [$asset->id => $displayText];
            })
            ->prepend(trans('global.pleaseSelect'), '');

        $service_types = FusionType::where('fusioncategory_id',2)->where('id', '!=', 9)->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $visit_types = FusionType::where('fusioncategory_id',3)->where('id', '!=', 14)->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $statuses = FusionType::where('fusioncategory_id',9)->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $enginner_assigneds = User::whereHas(
            'roles', function($q){
                $q->where('title','Engineer');
            })
            ->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $supervisor_assigneds =$commissioned_engineers = User::whereHas(
            'roles', function($q){
                $q->where('title','Supervisor');
            })
            ->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $teams = Team::pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');

        $serviceComplaint->load('client', 'location', 'asset', 'service_type', 'visit_type', 'status', 'enginner_assigned', 'supervisor_assigned', 'team');

        return view('admin.serviceComplaints.edit', compact('assets', 'clients', 'enginner_assigneds', 'locations', 'serviceComplaint', 'service_types', 'statuses', 'supervisor_assigneds', 'teams', 'visit_types'));
    }

    public function update(UpdateServiceComplaintRequest $request, ServiceComplaint $serviceComplaint)
    {
        $serviceComplaint->update($request->all());

        return redirect()->route('admin.service-complaints.index');
    }

    public function show(ServiceComplaint $serviceComplaint)
    {
        abort_if(Gate::denies('service_complaint_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $serviceComplaint->load('client', 'location', 'asset', 'service_type', 'visit_type', 'status', 'enginner_assigned', 'supervisor_assigned', 'team', 'complaintChecklistReports');

        // Parse the complaint field to extract asset IDs
        $complaint = $serviceComplaint->complaint;
        $assetIds = [];

        // Extract asset IDs from complaint text using regex

        // If no matches found or to ensure we catch all formats, try an alternative pattern
        if (empty($matches)) {
            preg_match_all('/(compressor|filter|dryer|ecodrain|receiver)_(\d+)/', $complaint, $matches, PREG_SET_ORDER);

        } else {
            // Also search for non-hashtag enclosed asset IDs
            preg_match_all('/(?<!#)(compressor|filter|dryer|ecodrain|receiver)_(\d+)(?!#)/', $complaint, $additionalMatches, PREG_SET_ORDER);
            $matches = array_merge($matches, $additionalMatches);
        }

        //dd($matches);

        // Track which asset types we've processed to avoid duplicates
        $processedAssetTypes = [];
        foreach ($matches as $match) {
            $assetType = $match[1];
            $assetId = $match[2];

            // Only process each asset type once with its specific ID
            $assetTypeKey = $assetType . '_' . $assetId;

            if (!in_array($assetTypeKey, $processedAssetTypes)) {
                $processedAssetTypes[] = $assetTypeKey;

                // Load the specific asset by ID
                $asset = Asset::find($assetId);
                if ($asset) {
                    // Set the asset for this specific type
                    switch ($assetType) {
                        case 'compressor':
                            $serviceComplaint->asset = $asset;
                            $serviceComplaint->air_compressor_name = $asset->air_compressor ? $asset->air_compressor->name : 'N/A';
                            break;
                        case 'filter':
                            $serviceComplaint->filter_asset = $asset;
                            $serviceComplaint->filter_name = $asset->filter ? $asset->filter->name : 'N/A';
                            break;
                        case 'dryer':
                            $serviceComplaint->dryer_asset = $asset;
                            $serviceComplaint->air_dryer_name = $asset->airdryer ? $asset->airdryer->name : 'N/A';
                            break;
                        case 'ecodrain':
                            $serviceComplaint->ecodrain_asset = $asset;
                            $serviceComplaint->eco_drain_name = $asset->eco_drain ? $asset->eco_drain->name : 'N/A';
                            break;
                        case 'receiver':
                            $serviceComplaint->receiver_asset = $asset;
                            $serviceComplaint->air_receiver_name = $asset->air_receiver ? $asset->air_receiver->name : 'N/A';
                            break;
                    }
                }
            }

            $assetIds[] = $assetId;
        }
        //dd(($asset));
        // If no specific assets were found in the complaint, load all asset attributes
        if (empty($assetIds)) {
            $serviceComplaint->air_compressor_name = $serviceComplaint->getAirCompressorNameAttribute();
            $serviceComplaint->air_dryer_name = $serviceComplaint->getAirDryerNameAttribute();
            $serviceComplaint->filter_name = $serviceComplaint->getFilterNameAttribute();
            $serviceComplaint->eco_drain_name = $serviceComplaint->getEcoDrainNameAttribute();
            $serviceComplaint->air_receiver_name = $serviceComplaint->getAirReceiverNameAttribute();
        }

        return view('admin.serviceComplaints.show', compact('serviceComplaint'));
    }


    public function destroy(ServiceComplaint $serviceComplaint)
    {
        abort_if(Gate::denies('service_complaint_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $serviceComplaint->delete();

        return back();
    }

    public function massDestroy(MassDestroyServiceComplaintRequest $request)
    {
        $serviceComplaints = ServiceComplaint::find(request('ids'));

        foreach ($serviceComplaints as $serviceComplaint) {
            $serviceComplaint->delete();
        }

        return response(null, Response::HTTP_NO_CONTENT);
    }



    //Create PDF

    public function createcomplaintpdf(Request $request, ServiceComplaint $serviceComplaint)
    {

        abort_if(Gate::denies('service_complaint_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        //$cid = $request->Complaintid;


        $serviceComplaint=$serviceComplaint->find($request->Complaintid)->load('client', 'location', 'asset', 'service_type', 'visit_type', 'status', 'enginner_assigned', 'supervisor_assigned', 'team', 'complaintChecklistReports');

        //From Show Function

// Parse the complaint field to extract asset IDs
$complaint = $serviceComplaint->complaint;
$assetIds = [];

// Extract asset IDs from complaint text using regex

// If no matches found or to ensure we catch all formats, try an alternative pattern
if (empty($matches)) {
    preg_match_all('/(compressor|filter|dryer|ecodrain|receiver)_(\d+)/', $complaint, $matches, PREG_SET_ORDER);

} else {
    // Also search for non-hashtag enclosed asset IDs
    preg_match_all('/(?<!#)(compressor|filter|dryer|ecodrain|receiver)_(\d+)(?!#)/', $complaint, $additionalMatches, PREG_SET_ORDER);
    $matches = array_merge($matches, $additionalMatches);
}

//dd($matches);

// Track which asset types we've processed to avoid duplicates
$processedAssetTypes = [];
foreach ($matches as $match) {
    $assetType = $match[1];
    $assetId = $match[2];

    // Only process each asset type once with its specific ID
    $assetTypeKey = $assetType . '_' . $assetId;
    if (!in_array($assetTypeKey, $processedAssetTypes)) {
        $processedAssetTypes[] = $assetTypeKey;

        // Load the specific asset by ID
        $asset = Asset::find($assetId);
        if ($asset) {
            // Set the asset for this specific type
            switch ($assetType) {
                case 'compressor':
                    $serviceComplaint->asset = $asset;
                    $serviceComplaint->air_compressor_name = $asset->air_compressor ? $asset->air_compressor->name : 'N/A';
                    break;
                case 'filter':
                    $serviceComplaint->filter_asset = $asset;
                    $serviceComplaint->filter_name = $asset->filter ? $asset->filter->name : 'N/A';
                    break;
                case 'dryer':
                    $serviceComplaint->dryer_asset = $asset;
                    $serviceComplaint->air_dryer_name = $asset->airdryer ? $asset->airdryer->name : 'N/A';
                    break;
                case 'ecodrain':
                    $serviceComplaint->ecodrain_asset = $asset;
                    $serviceComplaint->eco_drain_name = $asset->eco_drain ? $asset->eco_drain->name : 'N/A';
                    break;
                case 'receiver':
                    $serviceComplaint->receiver_asset = $asset;
                    $serviceComplaint->air_receiver_name = $asset->air_receiver ? $asset->air_receiver->name : 'N/A';
                    break;
            }
        }
    }

    $assetIds[] = $assetId;
}

// If no specific assets were found in the complaint, load all asset attributes
if (empty($assetIds)) {
    $serviceComplaint->air_compressor_name = $serviceComplaint->getAirCompressorNameAttribute();
    $serviceComplaint->air_dryer_name = $serviceComplaint->getAirDryerNameAttribute();
    $serviceComplaint->filter_name = $serviceComplaint->getFilterNameAttribute();
    $serviceComplaint->eco_drain_name = $serviceComplaint->getEcoDrainNameAttribute();
    $serviceComplaint->air_receiver_name = $serviceComplaint->getAirReceiverNameAttribute();
}


        //From Show Function



        $user_sign=UserSignature::where('user_id',$serviceComplaint->enginner_assigned->id)->pluck('temp');
        $_dompdf_warnings = array();
        $_dompdf_show_warnings = true;
        //view('admin.hacs.Subsystems.tags.pdf', compact('hac'));
        PDF::setOptions(['debugCss'=> true,'debugPng'=> true,'defaultFont' => 'Open Sans','isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true ,'chroot' => public_path()]);

        $pdf = PDF::loadView('admin.serviceComplaints.createcomplaintpdf',compact('user_sign','serviceComplaint'))->setOptions(['defaultFont' => 'sans-serif']);

        // set filename
        $filename= 'FSR_'. $serviceComplaint->id . '_' . $serviceComplaint->client->company_name . '_' . date('d-m-Y-h-s');

        //To Download PDF on Browser, comment it if you want to check the PDF rendering on Browser
        return $pdf->download($filename.'.pdf');

        //To check the redendring of the PDF on Browser


        return view('admin.serviceComplaints.createcomplaintpdf', compact('user_sign','serviceComplaint'));
    }


}
