<?php

namespace App\Http\Controllers;

use App\Models\ClassCharacteristic;
use App\Models\Item;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\ProductCharacteristicsMaster;
use App\Models\User;
use App\Models\WorkGroupMaster;
use Illuminate\Http\Request;
use Schema;
use Str;

class CharacteristicsController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        //
    }

    public function getCharacteristicsMaster(Request $request)
    {
        $expectedUser = env('API_AUTH_USER');
        $expectedPw = env('API_AUTH_PW');
        $header_auth = $request->header('Authorization');
        $expectedToken = $expectedUser.':'.$expectedPw;

        if ('Bearer '.$expectedToken != $header_auth) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid authorization token!',
            ], 403);
        }

        $plantCode = $request->header('plant-code');

        $itemCode = $request->header('item-code');

        if (! $plantCode) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant Code value can't be empty",
            ], 404);
        } elseif (! $itemCode) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item Code value can't be empty",
            ], 404);
        }

        $plant = Plant::where('code', $plantCode)->first();

        if (! $plant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant Code '{$plantCode}' not found!",
            ], 404);
        }

        $plantId = $plant->id;

        $item = Item::where('code', $itemCode)->first();

        $itemPlant = Item::where('code', $itemCode)
            ->where('plant_id', $plantId)
            ->first();

        if (! $item) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item Code '{$itemCode}' not found!",
            ], 404);
        }

        if (! $itemPlant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item Code '{$itemCode}' not found for the plant code '{$plant->code}'!",
            ], 404);
        }

        // $characteristics = ProductCharacteristicsMaster::where('plant_id', $plant->id)
        // ->where('item_id', $item->id)
        // ->first([
        //     'line_id',
        //     'machine_id',
        //     'characteristics_type',
        //     'name',
        //     'inspection_type',
        //     'upper',
        //     'lower',
        //     'middle'
        // ]);

        $characteristics = ProductCharacteristicsMaster::where('plant_id', $plant->id)
            ->where('item_id', $item->id)
            ->get([
                'line_id',
                'machine_id',
                'characteristics_type',
                'name',
                'inspection_type',
                'upper',
                'lower',
                'middle',
            ]);

        if ($characteristics->count() == 0) {
            return response()->json([
                'status_code' => 'ERROR',
                'message' => "No data found for the plant_code: {$plant->code} and item_code: {$item->code}",
            ], 404);
        }

        $items = [];

        // $response = $characteristics->toArray();

        // $line = Line::find($characteristics->line_id);
        // $lineName = $line ? $line->name : null;

        // // Remove line_id from response
        // $machineId = $characteristics->machine_id;
        // unset($response['line_id']);
        // unset($response['machine_id']);

        // $workCenter = Machine::where('id', $machineId)
        //     ->where('plant_id', $plant->id)
        //     ->where('line_id', $characteristics->line_id)
        //     ->value('work_center');

        // $workGroupMasterId = Machine::where('line_id', $characteristics->line_id)
        //     ->where('plant_id', $plant->id)
        //     ->value('work_group_master_id');

        // $groupWorkCenter = null;
        // if ($workGroupMasterId) {
        //     $groupWorkCenter = WorkGroupMaster::where('id', $workGroupMasterId)
        //         ->value('name');
        // }

        // $response  = [
        //     'line_name' => $lineName,
        //     'group_work_center' => $groupWorkCenter,
        //     'work_center' => $workCenter,
        //     'characteristics_type' => $characteristics->characteristics_type,
        //     'name' => $characteristics->name,
        //     'inspection_type' => $characteristics->inspection_type,
        //     // 'upper' => $characteristics->upper ?? 0,
        //     // 'lower' => $characteristics->lower ?? 0,
        //     // 'middle' => $characteristics->middle ?? 0,
        //     'lower' => (string)($characteristics->lower ?? 0),
        //     'middle' => (string)($characteristics->middle ?? 0),
        //     'upper' => (string)($characteristics->upper ?? 0),
        // ];

        // return response()->json($response);
        foreach ($characteristics as $char) {

            $line = Line::find($char->line_id);
            $lineName = $line ? $line->name : null;

            $workCenter = Machine::where('id', $char->machine_id)
                ->where('plant_id', $plant->id)
                ->where('line_id', $char->line_id)
                ->value('work_center');

            $workGroupMasterId = ProductCharacteristicsMaster::where('line_id', $char->line_id)
                ->where('plant_id', $plant->id)
                ->value('work_group_master_id');

            $groupWorkCenter = null;
            if ($workGroupMasterId) {
                $groupWorkCenter = WorkGroupMaster::where('id', $workGroupMasterId)
                    ->value('name');
            }

            $items[] = [
                'line_name' => $lineName,
                'group_work_center' => $groupWorkCenter,
                'work_center' => $workCenter,
                'characteristics_type' => $char->characteristics_type,
                'name' => $char->name,
                'inspection_type' => $char->inspection_type,
                'lower' => (string) ($char->lower ?? 0),
                'middle' => (string) ($char->middle ?? 0),
                'upper' => (string) ($char->upper ?? 0),
            ];
        }

        return response()->json([
            'items' => $items,
        ]);

    }

    /**
     * Store a newly created resource in storage.
     */
    // public function store(Request $request)
    // {
    //     //
    // }

    // Route::post('laser/store-test-datas', [CharacteristicsController::class, 'test'])
    public function storeLaserStatus(Request $request)
    {
        $expectedUser = env('API_AUTH_USER');
        $expectedPw = env('API_AUTH_PW');

        $header_auth = $request->header('Authorization');
        $expectedToken = $expectedUser.':'.$expectedPw;

        if ('Bearer '.$expectedToken != $header_auth) {
            return response('ERROR: Unauthorized', 403)
                ->header('Content-Type', 'text/plain');
        }

        $userName = $request->header('user-name');

        if (! $userName) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "User name can't be empty!",
            ], 404);
        } elseif ($userName == 'jothi') {
            $userName = 'Admin';
        }

        $data = $request->all();

        $plantCode = $data['plant_code'] ?? '';
        $workCenter = $data['work_center'] ?? '';
        $jobNo = $data['aufnr'] ?? '';
        $serialNumber = $data['gernr'] ?? '';
        $itemCode = $data['item_code'] ?? '';
        $characteristics = $data['characteristics'];

        if ($plantCode == null || $plantCode == '' || ! $plantCode) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant code can't be empty!",
            ], 400);
        } elseif (! is_numeric($plantCode) || Str::length($plantCode) < 4 || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) { // !ctype_digit($data['plant_code'])
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid plant code found!',
            ], 400);
        }

        if ($workCenter == null || $workCenter == '' || ! $workCenter) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center can't be empty!",
            ], 404);
        }

        $plant = Plant::where('code', $plantCode)->first();

        if (! $plant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant code '{$plantCode}' not found!",
            ], 404);
        }

        $plantId = $plant->id;

        $user = User::where('name', $userName)->first();

        $userPlant = User::where('name', $userName)->where('plant_id', $plantId)->first();

        if (! $user) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "User name '{$userName}' not found!",
            ], 403);
        } elseif (! $userPlant && ! $user->hasRole('Super Admin')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "User name '{$userName}' not found for the plant code '{$plantCode}'!",
            ], 403);
        } elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Design Manager') && ! $user->hasRole('Design Supervisor') && ! $user->hasRole('Design Employee')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User does not have rights!',
            ], 403);
        }

        $work = Machine::where('work_center', $workCenter)->first();

        if (! $work) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center '{$workCenter}' not found!",
            ], 404);
        }

        $machine = Machine::where('work_center', $workCenter)
            ->where('plant_id', $plantId)
            ->first();

        if (! $machine) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}'!",
            ], 404);
        }

        $machineId = $machine->id;

        if ($jobNo != null && $jobNo != '' && $jobNo) {
            if (Str::length($jobNo) < 7) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '$jobNo' should contain minimum 7 digits!",
                ], 400);
            } elseif (! is_numeric($jobNo)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '$jobNo' should contain only numeric values!",
                ], 400);
            }

            $job = ClassCharacteristic::where('aufnr', $jobNo)->first();

            if (! $job) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNo}' not found!",
                ], 404);
            }

            $jobPlant = ClassCharacteristic::where('aufnr', $jobNo)
                ->where('plant_id', $plantId)
                ->first();

            if (! $jobPlant) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNo}' not found for the plant code '{$plantCode}'!",
                ], 404);
            }

            $jobWorkCenter = ClassCharacteristic::where('aufnr', $jobNo)
                ->where('machine_id', $machineId)
                ->where('plant_id', $plantId)
                ->first();

            if (! $jobWorkCenter) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNo}' not found for the work center '{$workCenter}'!",
                ], 404);
            }
        }

        if ($serialNumber == null || $serialNumber == '' || ! $serialNumber) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Serial number can't be empty!",
            ], 404);
        } elseif (Str::length($serialNumber) < 9) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Serial number '{$serialNumber}' should contain minimum 9 digits!",
            ], 400);
        } elseif (! ctype_alnum($serialNumber)) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Serial number '{$serialNumber}' should contain only alpha-numeric values!",
            ], 400);
        }

        if ($itemCode == null || $itemCode == '' || ! $itemCode) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item code can't be empty!",
            ], 400);
        } elseif (Str::length($itemCode) < 6) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Item code should contain minimum 6 digits!',
            ], 400);
        } elseif (! ctype_alnum($itemCode)) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Item code should contain only alpha-numeric values!',
            ], 400);
        }

        $item = Item::where('code', $itemCode)->first();

        if (! $item) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item code '{$itemCode}' not found!",
            ], 404);
        }

        $itemPlant = Item::where('code', $itemCode)
            ->where('plant_id', $plantId)
            ->first();

        if (! $itemPlant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item code '{$itemCode}' not found for the plant code '{$plantCode}'!",
            ], 404);
        }

        $itemId = $itemPlant->id;

        $sNo = ClassCharacteristic::where('gernr', $serialNumber)->first();

        if (! $sNo) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Serial number '{$serialNumber}' not found!",
            ], 404);
        }

        $sNoPlant = ClassCharacteristic::where('gernr', $serialNumber)
            ->where('plant_id', $plantId)
            ->first();

        if (! $sNoPlant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Serial number '{$serialNumber}' not found for the plant code '{$plantCode}'!",
            ], 404);
        }

        $sNoItem = ClassCharacteristic::where('gernr', $serialNumber)
            ->where('plant_id', $plantId)
            ->where('item_id', $itemId)
            ->first();

        if (! $sNoItem) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Serial number '{$serialNumber}' not found with the item code '{$itemCode}'!",
            ], 404);
        }

        $sNoWorkCenter = ClassCharacteristic::where('gernr', $serialNumber)
            ->where('plant_id', $plantId)
            ->where('item_id', $itemId)
            ->where('machine_id', $machineId)
            ->first();

        if (! $sNoWorkCenter) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Serial number '{$serialNumber}' not found for the work center '{$workCenter}'!",
            ], 404);
        }

        if (empty($characteristics) || ! is_array($characteristics) || count($characteristics) == 0) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Characteristics can't be empty!",
            ], 404);
        }

        if ($jobNo != null && $jobNo != '' && $jobNo) {
            // $sNoJob = ClassCharacteristic::where('aufnr', $jobNo)
            //     ->where('plant_id', $plantId)
            //     ->where('gernr', $serialNumber)
            //     ->where('item_id', $itemId)
            //     ->first();
            // if (!$sNoJob) {
            //     return response()->json([
            //         'status_code' => "ERROR",
            //         'status_description' => "Serial number '{$serialNumber}' not found for the job number '$jobNo'!"
            //     ], 404);
            // }

            $sNoJob = ClassCharacteristic::where('aufnr', $jobNo)
                ->where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('gernr', $serialNumber)
                ->where('item_id', $itemId)
                ->first();

            if (! $sNoJob) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' not found for the job number '$jobNo'!",
                ], 404);
            }
        }

        $col = ['marked_by', 'man_marked_by'];
        $missingUsers = [];
        $missingUsersPlant = [];
        $missingUsersRight = [];
        foreach ($characteristics as $ch) {
            foreach ($col as $field) {
                if (! empty($ch[$field])) {
                    $markUser = $ch[$field];
                    if ($markUser == 'jothi') {
                        $markUser = 'Admin';
                    }

                    $user = User::where('name', $markUser)->first();

                    if (! $user) {
                        $missingUsers[$field] = $markUser;
                    } else {
                        $userPlant = User::where('name', $markUser)->where('plant_id', $plantId)->first();

                        if (! $userPlant && ! $user->hasRole('Super Admin')) {
                            $missingUsersPlant[$field] = $markUser;
                        } elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Design Manager') && ! $user->hasRole('Design Supervisor') && ! $user->hasRole('Design Employee')) {
                            $missingUsersRight[$field] = $markUser;
                        }
                    }
                }
            }
        }

        if (! empty($missingUsers)) {
            // return response()->json([
            //     'user_not_found' => $missingUsers
            // ], 404);
            $uniqueMissingUsers = array_unique($missingUsers);

            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Following users : '".implode(', ', $uniqueMissingUsers)."' not found!",
            ], 404);
        } elseif (! empty($missingUsersPlant)) {
            $uniqueMissingUsersPlant = array_unique($missingUsersPlant);

            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Following users : '".implode(', ', $uniqueMissingUsersPlant)."' not found for the plant code '{$plantCode}'!",
            ], 404);
        } elseif (! empty($missingUsersRight)) {
            $uniqueMissingUsersRight = array_unique($missingUsersRight);

            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Following users : '".implode(', ', $uniqueMissingUsersRight)."' does not have rights!",
            ], 404);
        }

        $updatedRows = 0;
        $isAuto = false;

        foreach ($data['characteristics'] as $char) {
            $values = [
                'mark_status' => $char['mark_status'] ?? null,
                'marked_datetime' => $char['marked_datetime'] ?? null,
                'marked_by' => ($char['marked_by'] == 'jothi') ? 'Admin' : $char['marked_by'] ?? null,
                'man_marked_status' => $char['man_marked_status'] ?? null,
                'man_marked_datetime' => $char['man_marked_datetime'] ?? null,
                'man_marked_by' => ($char['man_marked_by'] == 'jothi') ? 'Admin' : $char['man_marked_by'] ?? null,
                'motor_marked_status' => $char['motor_marked_status'] ?? null,
                'pump_marked_status' => $char['pump_marked_status'] ?? null,
                'motor_pump_pumpset_status' => $char['motor_pump_pumpset_status'] ?? null,
                'part_validation_1' => $char['part_validation_1'] ?? null,
                'part_validation_2' => $char['part_validation_2'] ?? null,
                'samlight_logged_name' => $char['samlight_logged_name'] ?? null,
                'pending_released_status' => $char['pending_released_status'] ?? null,
                'expected_time' => $char['expected_time'] ?? null,
                'updated_by' => $userName ?? null,
            ];

            if ($jobNo != null && $jobNo != '' && $jobNo) {
                $isAuto = true;
                $affected = ClassCharacteristic::where('plant_id', $plantId)
                    ->where('machine_id', $machineId)
                    ->where('aufnr', $jobNo)
                    ->where('gernr', $serialNumber)
                    ->where('item_id', $itemId)
                    ->update($values);

                $updatedRows += $affected;
            } else {
                $isAuto = false;
                $affected = ClassCharacteristic::where('plant_id', $plantId)
                    ->where('machine_id', $machineId)
                    ->where('gernr', $serialNumber)
                    ->where('item_id', $itemId)
                    ->update($values);

                $updatedRows += $affected;
            }
        }

        if ($updatedRows == 0) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => $isAuto ? "Failed to update auto marked status for the serial number '{$serialNumber}'." : "Failed to update manual marked status for the serial number '{$serialNumber}'.",
            ], 500);
        } else {
            return response()->json([
                'status_code' => 'SUCCESS',
                'status_description' => $isAuto ? "Successfully auto marked status updated for the serial number '{$serialNumber}'." : "Successfully manual marked status updated for the serial number '{$serialNumber}'.",
            ], 200);
        }
    }

    public function storeClassChar(Request $request)
    {
        $expectedUser = env('API_AUTH_USER');
        $expectedPw = env('API_AUTH_PW');

        $header_auth = $request->header('Authorization');
        $expectedToken = $expectedUser.':'.$expectedPw;

        if ('Bearer '.$expectedToken != $header_auth) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid authorization token!',
            ], 403);
        }

        $userName = $request->header('user-name');

        if (! $userName) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "User name can't be empty!",
            ], 404);
        } elseif ($userName == 'jothi') {
            $userName = 'Admin';
        }

        $data = $request->all();

        $plantCode = $data['plant_code'];
        $workCenter = $data['work_center'];
        $itemCode = $data['item_code'] ?? '';
        $jobNo = $data['aufnr'] ?? '';
        $serialNumbers = $data['serial_numbers'] ?? '';
        $characteristics = $data['characteristics'];

        if ($plantCode == null || $plantCode == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant code can't be empty!",
            ], 400);
        } elseif (! is_numeric($plantCode) || Str::length($plantCode) < 4 || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) { // !ctype_digit($data['plant_code'])
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid plant code found!',
            ], 400);
        }

        if ($workCenter == null || $workCenter == '' || ! $workCenter) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center can't be empty!",
            ], 404);
        }

        $plant = Plant::where('code', $plantCode)->first();

        if (! $plant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant '{$plantCode}' not found!",
            ], 404);
        }

        $plantId = $plant->id;

        $user = User::where('name', $userName)->first();

        $userPlant = User::where('name', $userName)->where('plant_id', $plantId)->first();

        if (! $user) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User name not found!',
            ], 403);
        } elseif (! $userPlant && ! $user->hasRole('Super Admin')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "User '{$userName}' not found for Plant '{$plantCode}'!",
            ], 403);
        } elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Design Manager') && ! $user->hasRole('Design Supervisor') && ! $user->hasRole('Design Employee')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User does not have rights!',
            ], 403);
        }

        $work = Machine::where('work_center', $workCenter)->first();

        if (! $work) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center '{$workCenter}' not found!",
            ], 404);
        }

        $machine = Machine::where('work_center', $workCenter)
            ->where('plant_id', $plantId)
            ->first();

        if (! $machine) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}'!",
            ], 404);
        }

        $machineId = $machine->id;

        $availFields = [
            'class', 'arbid', 'gamng', 'lmnga', 'zz1_cn_bill_ord', 'zmm_amps', 'zmm_brand', 'zmm_degreeofprotection', 'zmm_delivery', 'zmm_dir_rot', 'zmm_discharge', 'zmm_discharge_max', 'zmm_discharge_min', 'zmm_duty', 'zmm_eff_motor', 'zmm_eff_pump', 'zmm_frequency', 'zmm_head', 'zmm_heading', 'zmm_head_max', 'zmm_head_minimum', 'zmm_idx_eff_mtr', 'zmm_idx_eff_pump', 'zmm_kvacode', 'zmm_maxambtemp', 'zmm_mincoolingflow', 'zmm_motorseries', 'zmm_motor_model', 'zmm_outlet', 'zmm_phase', 'zmm_pressure', 'zmm_pumpflowtype', 'zmm_pumpseries', 'zmm_pump_model', 'zmm_ratedpower', 'zmm_region', 'zmm_servicefactor', 'zmm_servicefactormaximumamps', 'zmm_speed', 'zmm_suction', 'zmm_suctionxdelivery', 'zmm_supplysource', 'zmm_temperature', 'zmm_thrustload', 'zmm_volts', 'zmm_wire', 'zmm_package', 'zmm_pvarrayrating', 'zmm_isi', 'zmm_isimotor', 'zmm_isipump', 'zmm_isipumpset', 'zmm_pumpset_model', 'zmm_stages', 'zmm_headrange', 'zmm_overall_efficiency', 'zmm_connection', 'zmm_min_bore_size', 'zmm_isireference', 'zmm_category', 'zmm_submergence', 'zmm_capacitorstart', 'zmm_capacitorrun', 'zmm_inch', 'zmm_motor_type', 'zmm_dismantle_direction', 'zmm_eff_ovrall', 'zmm_bodymoc', 'zmm_rotormoc', 'zmm_dlwl', 'zmm_inputpower', 'zmm_imp_od', 'zmm_ambtemp', 'zmm_de', 'zmm_dischargerange', 'zmm_efficiency_class', 'zmm_framesize', 'zmm_impellerdiameter', 'zmm_insulationclass', 'zmm_maxflow', 'zmm_minhead', 'zmm_mtrlofconst', 'zmm_nde', 'zmm_powerfactor', 'zmm_tagno', 'zmm_year', 'zmm_laser_name', 'zmm_beenote', 'zmm_beenumber', 'zmm_beestar', 'zmm_logo_ce', 'zmm_codeclass', 'zmm_colour', 'zmm_logo_cp', 'zmm_grade', 'zmm_grwt_pset', 'zmm_grwt_cable', 'zmm_grwt_motor', 'zmm_grwt_pf', 'zmm_grwt_pump', 'zmm_isivalve', 'zmm_isi_wc', 'zmm_labelperiod', 'zmm_length', 'zmm_license_cml_no', 'zmm_mfgmonyr', 'zmm_modelyear', 'zmm_motoridentification', 'zmm_newt_pset', 'zmm_newt_cable', 'zmm_newt_motor', 'zmm_newt_pf', 'zmm_newt_pump', 'zmm_logo_nsf', 'zmm_packtype', 'zmm_panel', 'zmm_performance_factor', 'zmm_pumpidentification', 'zmm_psettype', 'zmm_size', 'zmm_eff_ttl', 'zmm_type', 'zmm_usp', 'mark_status', 'marked_datetime', 'marked_by', 'man_marked_status', 'man_marked_datetime', 'man_marked_by', 'motor_marked_status', 'pump_marked_status', 'motor_pump_pumpset_status', 'part_validation_1', 'part_validation_2', 'samlight_logged_name', 'pending_released_status', 'expected_time',
        ];

        if ($itemCode != '' && $itemCode != null && $itemCode && Str::length($itemCode) > 0) {
            $existingJob = ClassCharacteristic::where('plant_id', $plantId)
                // ->where('machine_id', $machineId)
                ->where('aufnr', $jobNo)
                ->first();

            if ($existingJob) {
                $curMachine = Machine::where('id', $existingJob->machine_id)->first();

                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Duplicate job number '{$jobNo}' found for the plant code '{$plantCode}' and work center '$curMachine->work_center'!",
                ], 404);
            }

            if (Str::length($itemCode) < 6) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'Item Code should contain minimum 6 digits!',
                ], 400);
            } elseif (! ctype_alnum($itemCode)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'Item Code should contain alpha-numeric values!',
                ], 400);
            }

            $item = Item::where('code', $itemCode)->first();

            if (! $item) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item Code '{$itemCode}' not found!",
                ], 404);
            }

            $itemPlant = Item::where('code', $itemCode)
                ->where('plant_id', $plantId)
                ->first();

            if (! $itemPlant) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item Code '{$itemCode}' not found for the plant code '{$plantCode}'!",
                ], 404);
            }

            $itemId = $itemPlant->id;

            if (empty($serialNumbers) || ! is_array($serialNumbers) || count($serialNumbers) == 0) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial numbers can't be empty!",
                ], 404);
            }

            if (empty($characteristics) || ! is_array($characteristics) || count($characteristics) == 0) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Characteristics can't be empty!",
                ], 404);
            }

            $columns = Schema::getColumnListing((new ClassCharacteristic)->getTable());

            $invalidFields = [];

            foreach ($request->input('characteristics', []) as $char) {
                $inputKeys = array_keys($char);

                $unexpected = array_diff($inputKeys, $columns);

                if (! empty($unexpected)) {
                    $invalidFields = array_merge($invalidFields, $unexpected);
                }
            }

            if (! empty($invalidFields)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Unknown Column names found '".implode(', ', $invalidFields)."'.",
                ], 404);
            }

            $col = ['marked_by', 'man_marked_by'];
            $missingUsers = [];
            $missingUsersPlant = [];
            $missingUsersRight = [];
            foreach ($characteristics as $ch) {
                foreach ($col as $field) {
                    if (! empty($ch[$field])) {
                        $markUser = $ch[$field];
                        if ($markUser == 'jothi') {
                            $markUser = 'Admin';
                        }

                        $user = User::where('name', $markUser)->first();

                        if (! $user) {
                            $missingUsers[$field] = $markUser;
                        } else {
                            $userPlant = User::where('name', $markUser)->where('plant_id', $plantId)->first();

                            if (! $userPlant && ! $user->hasRole('Super Admin')) {
                                $missingUsersPlant[$field] = $markUser;
                            } elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Design Manager') && ! $user->hasRole('Design Supervisor') && ! $user->hasRole('Design Employee')) {
                                $missingUsersRight[$field] = $markUser;
                            }
                        }
                    }
                }
            }

            if (! empty($missingUsers)) {
                // return response()->json([
                //     'user_not_found' => $missingUsers
                // ], 404);
                $uniqueMissingUsers = array_unique($missingUsers);

                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Following users : '".implode(', ', $uniqueMissingUsers)."' not found!",
                ], 404);
            } elseif (! empty($missingUsersPlant)) {
                $uniqueMissingUsersPlant = array_unique($missingUsersPlant);

                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Following users : '".implode(', ', $uniqueMissingUsersPlant)."' not found for the plant code '{$plantCode}'!",
                ], 404);
            } elseif (! empty($missingUsersRight)) {
                $uniqueMissingUsersRight = array_unique($missingUsersRight);

                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Following users : '".implode(', ', $uniqueMissingUsersRight)."' does not have rights!",
                ], 404);
            }

            $dupSerials = [];
            foreach ($serialNumbers as $serial) {
                try {
                    $existing = ClassCharacteristic::where('plant_id', $plantId)
                        // ->where('item_id', $itemId)
                        ->where('gernr', $serial)
                        ->first();

                    if ($existing) {
                        $dupSerials[] = $serial;
                    }
                } catch (\Exception $e) {
                    return response()->json([
                        'status_code' => 'ERROR',
                        'status_description' => "Error occurred while inserting new master characteristics for the serial number '$serial', {$e->getMessage()}",
                        // 'char_data' => $char
                    ], 500);
                }
            }

            if (! empty($dupSerials)) {
                $uniqueDupSerials = array_unique($dupSerials);

                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Following serial number(s) already exist in cloud : '".implode(', ', $uniqueDupSerials)."'!",
                ], 404);
            }

            $isInsert = false;

            foreach ($serialNumbers as $serial) {
                foreach ($characteristics as $char) {
                    try {
                        $insertData = [
                            'plant_id' => $plantId,
                            'machine_id' => $machineId,
                            'aufnr' => $jobNo,
                            'item_id' => $itemId,
                            'gernr' => $serial,
                        ];

                        foreach ($availFields as $field) {
                            if (in_array($field, $columns)) {
                                $insertData[$field] = $char[$field] ?? null;
                            }
                        }

                        $insertData['marked_by'] = ($char['marked_by'] == 'jothi') ? 'Admin' : $char['marked_by'] ?? null;
                        $insertData['man_marked_by'] = ($char['man_marked_by'] == 'jothi') ? 'Admin' : $char['man_marked_by'] ?? null;

                        $existing = ClassCharacteristic::where('plant_id', $plantId)
                            ->where('item_id', $itemId)
                            ->where('gernr', $serial)
                            ->first();

                        if ($existing) {
                            // $insertData['updated_by'] = $userName ?? null;
                            // $existing->update($insertData);
                            return response()->json([
                                'status_code' => 'ERROR',
                                'status_description' => "Duplicate serial number '$serial' found while inserting new master characteristics for the job number '$jobNo'.",
                            ], 404);
                        } else {
                            $isInsert = true;
                            $insertData['created_by'] = $userName ?? null;
                            ClassCharacteristic::create($insertData);
                        }
                    } catch (\Exception $e) {
                        return response()->json([
                            'status_code' => 'ERROR',
                            'status_description' => "Error occurred while inserting new master characteristics for the serial number '$serial', {$e->getMessage()}",
                            // 'char_data' => $char
                        ], 500);
                    }
                }
            }

            return response()->json([
                'status_code' => 'SUCCESS',
                'status_description' => $isInsert ? "Successfully inserted new master characteristics for the job number '$jobNo'." : "Failed to insert new master characteristics for the job number '$jobNo'.",
            ], 200);
        } else {
            $hasNewSno = false;

            $columns = Schema::getColumnListing((new ClassCharacteristic)->getTable());

            $invalidFields = [];

            foreach ($request->input('characteristics', []) as $char) {
                $inputKeys = array_keys($char);

                $unexpected = array_diff($inputKeys, $columns);

                if (! empty($unexpected)) {
                    $invalidFields = array_merge($invalidFields, $unexpected);
                }
            }

            if (! empty($invalidFields)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Unknown Column names found '".implode(', ', $invalidFields)."'.",
                ], 404);
            }

            $existingJob = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('aufnr', $jobNo)
                ->first();

            if (! $existingJob) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNo}' not found for the plant code '{$plantCode}' and work center '{$workCenter}'!",
                ], 404);
            }

            $itemId = $existingJob->item_id;

            if (empty($serialNumbers) || ! is_array($serialNumbers) || count($serialNumbers) == 0) {
                $hasNewSno = false;
                // return response()->json([
                //     'status_code' => "ERROR",
                //     'status_description' => "Serial numbers can't be empty!"
                // ], 404);
            } else {
                $hasNewSno = true;

                $col = ['marked_by', 'man_marked_by'];
                $missingUsers = [];
                $missingUsersPlant = [];
                $missingUsersRight = [];
                foreach ($characteristics as $ch) {
                    foreach ($col as $field) {
                        if (! empty($ch[$field])) {
                            $markUser = $ch[$field];
                            if ($markUser == 'jothi') {
                                $markUser = 'Admin';
                            }

                            $user = User::where('name', $markUser)->first();

                            if (! $user) {
                                $missingUsers[$field] = $markUser;
                            } else {
                                $userPlant = User::where('name', $markUser)->where('plant_id', $plantId)->first();

                                if (! $userPlant && ! $user->hasRole('Super Admin')) {
                                    $missingUsersPlant[$field] = $markUser;
                                } elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Design Manager') && ! $user->hasRole('Design Supervisor') && ! $user->hasRole('Design Employee')) {
                                    $missingUsersRight[$field] = $markUser;
                                }
                            }
                        }
                    }
                }

                if (! empty($missingUsers)) {
                    // return response()->json([
                    //     'user_not_found' => $missingUsers
                    // ], 404);
                    $uniqueMissingUsers = array_unique($missingUsers);

                    return response()->json([
                        'status_code' => 'ERROR',
                        'status_description' => "Following users : '".implode(', ', $uniqueMissingUsers)."' not found!",
                    ], 404);
                } elseif (! empty($missingUsersPlant)) {
                    $uniqueMissingUsersPlant = array_unique($missingUsersPlant);

                    return response()->json([
                        'status_code' => 'ERROR',
                        'status_description' => "Following users : '".implode(', ', $uniqueMissingUsersPlant)."' not found for the plant code '{$plantCode}'!",
                    ], 404);
                } elseif (! empty($missingUsersRight)) {
                    $uniqueMissingUsersRight = array_unique($missingUsersRight);

                    return response()->json([
                        'status_code' => 'ERROR',
                        'status_description' => "Following users : '".implode(', ', $uniqueMissingUsersRight)."' does not have rights!",
                    ], 404);
                }

                $dupSerials = [];
                foreach ($serialNumbers as $serial) {
                    try {
                        $existing = ClassCharacteristic::where('plant_id', $plantId)
                            // ->where('item_id', $itemId)
                            ->where('gernr', $serial)
                            ->first();

                        if ($existing) {
                            $dupSerials[] = $serial;
                        }
                    } catch (\Exception $e) {
                        return response()->json([
                            'status_code' => 'ERROR',
                            'status_description' => "Error occurred while inserting new master characteristics for the serial number '$serial', {$e->getMessage()}",
                            // 'char_data' => $char
                        ], 500);
                    }
                }

                if (! empty($dupSerials)) {
                    $uniqueDupSerials = array_unique($dupSerials);

                    return response()->json([
                        'status_code' => 'ERROR',
                        'status_description' => "Following serial number(s) already exist in cloud : '".implode(', ', $uniqueDupSerials)."'!",
                    ], 404);
                }
            }

            if (empty($characteristics) || ! is_array($characteristics) || count($characteristics) == 0) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Characteristics can't be empty!",
                ], 404);
            }

            $masterFields = [
                'class', 'arbid', 'gamng', 'lmnga', 'zz1_cn_bill_ord', 'zmm_amps', 'zmm_brand', 'zmm_degreeofprotection', 'zmm_delivery', 'zmm_dir_rot', 'zmm_discharge', 'zmm_discharge_max', 'zmm_discharge_min', 'zmm_duty', 'zmm_eff_motor', 'zmm_eff_pump', 'zmm_frequency', 'zmm_head', 'zmm_heading', 'zmm_head_max', 'zmm_head_minimum', 'zmm_idx_eff_mtr', 'zmm_idx_eff_pump', 'zmm_kvacode', 'zmm_maxambtemp', 'zmm_mincoolingflow', 'zmm_motorseries', 'zmm_motor_model', 'zmm_outlet', 'zmm_phase', 'zmm_pressure', 'zmm_pumpflowtype', 'zmm_pumpseries', 'zmm_pump_model', 'zmm_ratedpower', 'zmm_region', 'zmm_servicefactor', 'zmm_servicefactormaximumamps', 'zmm_speed', 'zmm_suction', 'zmm_suctionxdelivery', 'zmm_supplysource', 'zmm_temperature', 'zmm_thrustload', 'zmm_volts', 'zmm_wire', 'zmm_package', 'zmm_pvarrayrating', 'zmm_isi', 'zmm_isimotor', 'zmm_isipump', 'zmm_isipumpset', 'zmm_pumpset_model', 'zmm_stages', 'zmm_headrange', 'zmm_overall_efficiency', 'zmm_connection', 'zmm_min_bore_size', 'zmm_isireference', 'zmm_category', 'zmm_submergence', 'zmm_capacitorstart', 'zmm_capacitorrun', 'zmm_inch', 'zmm_motor_type', 'zmm_dismantle_direction', 'zmm_eff_ovrall', 'zmm_bodymoc', 'zmm_rotormoc', 'zmm_dlwl', 'zmm_inputpower', 'zmm_imp_od', 'zmm_ambtemp', 'zmm_de', 'zmm_dischargerange', 'zmm_efficiency_class', 'zmm_framesize', 'zmm_impellerdiameter', 'zmm_insulationclass', 'zmm_maxflow', 'zmm_minhead', 'zmm_mtrlofconst', 'zmm_nde', 'zmm_powerfactor', 'zmm_tagno', 'zmm_year', 'zmm_laser_name',
            ];

            $isInsertOrUpdate = false;

            foreach ($characteristics as $char) {
                try {
                    $insertData = [
                        'plant_id' => $plantId,
                        'machine_id' => $machineId,
                        'aufnr' => $jobNo,
                    ];

                    foreach ($masterFields as $field) {
                        if (in_array($field, $columns)) {
                            $insertData[$field] = $char[$field] ?? null;
                        }
                    }

                    $existing = ClassCharacteristic::where('plant_id', $plantId)
                        ->where('machine_id', $machineId)
                        ->where('aufnr', $jobNo);

                    if ($existing) {
                        $isInsertOrUpdate = true;
                        $insertData['updated_by'] = $userName ?? null;
                        $existing->update($insertData);
                    } else {
                        return response()->json([
                            'status_code' => 'ERROR',
                            'status_description' => "Job number '$jobNo' not found to update exist master characteristics!",
                        ], 404);
                    }
                } catch (\Exception $e) {
                    return response()->json([
                        'status_code' => 'ERROR',
                        'status_description' => "Error occurred while updating exist master characteristics for the job number '$jobNo', {$e->getMessage()}",
                        // 'char_data' => $char
                    ], 404);
                }
            }

            if ($hasNewSno) {
                $itemId = $existingJob->item_id;

                foreach ($serialNumbers as $serial) {
                    foreach ($characteristics as $char) {
                        try {
                            $insertData = [
                                'plant_id' => $plantId,
                                'aufnr' => $jobNo,
                                'machine_id' => $machineId,
                                'item_id' => $itemId,
                                'gernr' => $serial,
                            ];

                            foreach ($availFields as $field) {
                                if (in_array($field, $columns)) {
                                    $insertData[$field] = $char[$field] ?? null;
                                }
                            }

                            $insertData['marked_by'] = ($char['marked_by'] == 'jothi') ? 'Admin' : $char['marked_by'] ?? null;
                            $insertData['man_marked_by'] = ($char['man_marked_by'] == 'jothi') ? 'Admin' : $char['man_marked_by'] ?? null;

                            $existing = ClassCharacteristic::where('plant_id', $plantId)
                                ->where('item_id', $itemId)
                                ->where('gernr', $serial)
                                ->first();

                            if ($existing) {
                                return response()->json([
                                    'status_code' => 'ERROR',
                                    'status_description' => "Duplicate serial number '$serial' found in job number '$existing->aufnr'!",
                                ], 404);
                            } else {
                                $isInsertOrUpdate = true;
                                $insertData['created_by'] = $userName ?? null;
                                ClassCharacteristic::create($insertData);
                            }
                        } catch (\Exception $e) {
                            return response()->json([
                                'status_code' => 'ERROR',
                                'status_description' => "Error occurred while inserting new master characteristics for the serial number '$serial', {$e->getMessage()}",
                                // 'char_data' => $char
                            ], 500);
                        }
                    }
                }
            }

            return response()->json([
                'status_code' => 'SUCCESS',
                'status_description' => $isInsertOrUpdate ? "Successfully updated master characteristics for the job number '$jobNo'." : "Failed to update master characteristics for the job number '$jobNo'.",
            ], 200);
        }

    }

    public function getClassChar(Request $request)
    {
        $expectedUser = env('API_AUTH_USER');
        $expectedPw = env('API_AUTH_PW');
        $header_auth = $request->header('Authorization');
        $expectedToken = $expectedUser.':'.$expectedPw;

        if ('Bearer '.$expectedToken != $header_auth) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid authorization token!',
            ], 403);
        }

        $userName = $request->header('user-name');

        $plantCode = $request->header('plant-code');

        $workCenter = $request->header('work-center');

        $jobNumber = $request->header('job-number');

        $itemCode = $request->header('item-code');

        $serialNumber = $request->header('serial-number');

        if (! $userName) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "User Name can't be empty!",
            ], 404);
        } elseif ($userName == 'jothi') {
            $userName = 'Admin';
        }

        if (! $plantCode || $plantCode == null || $plantCode == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant code can't be empty!",
            ], 400);
        } elseif (! is_numeric($plantCode) || Str::length($plantCode) < 4 || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) { // !ctype_digit($data['plant_code'])
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid plant code found!',
            ], 400);
        }

        if (! $workCenter || $workCenter == null || $workCenter == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work Center can't be empty!",
            ], 404);
        }

        $plant = Plant::where('code', $plantCode)->first();

        if (! $plant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant Code '{$plantCode}' not found!",
            ], 404);
        }

        $plantId = $plant->id;

        $user = User::where('name', $userName)->first();

        $userPlant = User::where('name', $userName)->where('plant_id', $plantId)->first();

        if (! $user) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User Name not found!',
            ], 403);
        } elseif (! $userPlant && ! $user->hasRole('Super Admin')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User Name not found for the plant!',
            ], 403);
        } elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Design Manager') && ! $user->hasRole('Design Supervisor') && ! $user->hasRole('Design Employee')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User does not have rights!',
            ], 403);
        }

        $work = Machine::where('work_center', $workCenter)->first();

        if (! $work) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work Center '{$workCenter}' not found!",
            ], 404);
        }

        $machine = Machine::where('work_center', $workCenter)
            ->where('plant_id', $plantId)
            ->first();

        if (! $machine) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work Center '{$workCenter}' not found for the plant code '{$plantCode}'!",
            ], 404);
        }

        $machineId = $machine->id;

        if (($itemCode == '' || $itemCode == null) && ($serialNumber == '' || $serialNumber == null)) {
            if (! $jobNumber) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number can't be empty",
                ], 404);
            } elseif (Str::length($jobNumber) < 7) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' should contain minimum 7 digits!",
                ], 400);
            } elseif (! is_numeric($jobNumber)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' should contain only numeric values!",
                ], 400);
            }

            $job = ClassCharacteristic::where('aufnr', $jobNumber)->first();

            if (! $job) {
                return response()->json([
                    'status_code' => 'SUCCESS',
                    'status_description' => "Job number '{$jobNumber}' not found!",
                ], 400);
            }

            $jobPlant = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->first();

            if (! $jobPlant) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found for the plant code '{$plantCode}'!",
                ], 400);
            }

            $jobWorkCenter = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->first();

            if (! $jobWorkCenter) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found for the work center '{$workCenter}'!",
                ], 400);
            }

            $columnsToShow = ['mark_status', 'marked_datetime', 'marked_by', 'man_marked_status', 'man_marked_datetime', 'man_marked_by', 'motor_marked_status', 'pump_marked_status', 'motor_pump_pumpset_status', 'part_validation_1', 'part_validation_2', 'samlight_logged_name', 'pending_released_status', 'expected_time'];

            $characteristicsColumns = ['class', 'arbid', 'gamng', 'lmnga', 'zz1_cn_bill_ord', 'zmm_amps', 'zmm_brand', 'zmm_degreeofprotection', 'zmm_delivery', 'zmm_dir_rot', 'zmm_discharge', 'zmm_discharge_max', 'zmm_discharge_min', 'zmm_duty', 'zmm_eff_motor', 'zmm_eff_pump', 'zmm_frequency', 'zmm_head', 'zmm_heading', 'zmm_head_max', 'zmm_head_minimum', 'zmm_idx_eff_mtr', 'zmm_idx_eff_pump', 'zmm_kvacode', 'zmm_maxambtemp', 'zmm_mincoolingflow', 'zmm_motorseries', 'zmm_motor_model', 'zmm_outlet', 'zmm_phase', 'zmm_pressure', 'zmm_pumpflowtype', 'zmm_pumpseries', 'zmm_pump_model', 'zmm_ratedpower', 'zmm_region', 'zmm_servicefactor', 'zmm_servicefactormaximumamps', 'zmm_speed', 'zmm_suction', 'zmm_suctionxdelivery', 'zmm_supplysource', 'zmm_temperature', 'zmm_thrustload', 'zmm_volts', 'zmm_wire', 'zmm_package', 'zmm_pvarrayrating', 'zmm_isi', 'zmm_isimotor', 'zmm_isipump', 'zmm_isipumpset', 'zmm_pumpset_model', 'zmm_stages', 'zmm_headrange', 'zmm_overall_efficiency', 'zmm_connection', 'zmm_min_bore_size', 'zmm_isireference', 'zmm_category', 'zmm_submergence', 'zmm_capacitorstart', 'zmm_capacitorrun', 'zmm_inch', 'zmm_motor_type', 'zmm_dismantle_direction', 'zmm_eff_ovrall', 'zmm_bodymoc', 'zmm_rotormoc', 'zmm_dlwl', 'zmm_inputpower', 'zmm_imp_od', 'zmm_ambtemp', 'zmm_de', 'zmm_dischargerange', 'zmm_efficiency_class', 'zmm_framesize', 'zmm_impellerdiameter', 'zmm_insulationclass', 'zmm_maxflow', 'zmm_minhead', 'zmm_mtrlofconst', 'zmm_nde', 'zmm_powerfactor', 'zmm_tagno', 'zmm_year', 'zmm_laser_name'];

            $characteristicsData = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                // ->get();
                ->distinct()
                ->get($characteristicsColumns);

            if ($characteristicsData->isEmpty()) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'No characteristics data found for the provided Plant, Work Center, and Job Number!',
                ], 400);
            }

            $serials = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('aufnr', $jobNumber)
                ->orderBy('gernr')
                // ->get(array_merge(['gernr'], $columnsToShow));
                ->get(array_merge(['gernr', 'item_id'], $columnsToShow));

            $itemId = $serials->first()->item_id;

            $itemcode = Item::where('id', $itemId)->value('code') ?? '';

            $markedSerials = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('aufnr', $jobNumber)
                ->get(['gernr', 'mark_status']);

            $allMarked = $markedSerials->every(function ($serial) {
                return strtolower($serial->mark_status) == 'marked';
            });

            if ($allMarked) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'All serial numbers are already marked.',
                ], 400);
            }

            $serialNumbers = $serials->map(function ($serial) use ($columnsToShow) {
                $otherData = [];
                foreach ($columnsToShow as $col) {
                    $otherData[$col] = (string) $serial->$col ?? '';
                }

                $otherData['marked_by'] = ($otherData['marked_by'] == 'Admin') ? 'jothi' : $otherData['marked_by'] ?? '';
                $otherData['man_marked_by'] = ($otherData['man_marked_by'] == 'Admin') ? 'jothi' : $otherData['man_marked_by'] ?? '';

                // $otherData['pending_released_status'] = (string)$otherData['pending_released_status'] ?? '';
                return array_merge(['gernr' => $serial->gernr], $otherData);
            });

            $characteristics = $characteristicsData->map(function ($char) use ($characteristicsColumns) {
                $data = [];
                foreach ($characteristicsColumns as $col) {
                    $data[$col] = $char->$col ?? '';
                }

                return $data;
            });

            $response = [
                'item_code' => $itemcode,
                'serial_numbers' => $serialNumbers,
                'characteristics' => $characteristics,
            ];

            return response()->json($response);

        } elseif (($itemCode != '' && $itemCode != null) || ($serialNumber != '' && $serialNumber != null)) {
            if (Str::length($serialNumber) < 9) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' should contain minimum 9 digits!",
                ], 400);
            } elseif (! ctype_alnum($serialNumber)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' should contain only alpha-numeric values!",
                ], 400);
            }

            if (Str::length($itemCode) < 6) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'Item code should contain minimum 6 digits!',
                ], 400);
            } elseif (! ctype_alnum($itemCode)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item code '{$itemCode}' should contain only alpha-numeric values!",
                ], 400);
            }

            $item = Item::where('code', $itemCode)->first();

            if (! $item) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item code '{$itemCode}' not found!",
                ], 404);
            }

            $itemPlant = Item::where('code', $itemCode)
                ->where('plant_id', $plantId)
                ->first();

            if (! $itemPlant) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item code '{$itemCode}' not found for the plant code '{$plantCode}'!",
                ], 404);
            }

            $itemId = $itemPlant->id; // Item::where('code', $itemCode)->where('plant_id', $plantId)->value('id');

            $serialExists = ClassCharacteristic::where('gernr', $serialNumber)->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' not found!",
                ], 404);
            }

            $serialExists = ClassCharacteristic::where('plant_id', $plantId)
                ->where('gernr', $serialNumber)
                ->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' not found for plant code '{$plantCode}'!",
                ], 404);
            }

            $serialExists = ClassCharacteristic::where('plant_id', $plantId)
                ->where('gernr', $serialNumber)
                ->where('item_id', $itemId)
                ->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' with item code '{$itemCode}' not found for plant code '{$plantCode}'!",
                ], 404);
            }

            $serialExists = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('gernr', $serialNumber)
                ->where('item_id', $itemId)
                ->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' with item code '{$itemCode}' not found for work center '{$workCenter}'!",
                ], 404);
            }

            if ($serialExists->mark_status != 'Marked' && $serialExists->mark_status != 'marked') {
                // "Serial number '{$serialNumber}' is not marked yet.<br>Please proceed with marking first.";
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' does not marked in AUTO mode! Please, close MANUAL window and proceed with AUTO mode to start laser marking..!",
                ], 404);
            }

            $characteristicsData = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('gernr', $serialNumber)
                ->where('item_id', $itemId)
                ->get();

            $remFields = [
                'id', 'plant_id', 'machine_id', 'item_id', 'gernr', 'zmm_beenote', 'zmm_beenumber', 'zmm_beestar', 'zmm_logo_ce', 'zmm_codeclass', 'zmm_colour', 'zmm_logo_cp', 'zmm_grade', 'zmm_grwt_pset', 'zmm_grwt_cable', 'zmm_grwt_motor', 'zmm_grwt_pf', 'zmm_grwt_pump', 'zmm_isivalve', 'zmm_isi_wc', 'zmm_labelperiod', 'zmm_length', 'zmm_license_cml_no', 'zmm_mfgmonyr', 'zmm_modelyear', 'zmm_motoridentification', 'zmm_newt_pset', 'zmm_newt_cable', 'zmm_newt_motor', 'zmm_newt_pf', 'zmm_newt_pump', 'zmm_logo_nsf', 'zmm_packtype', 'zmm_panel', 'zmm_performance_factor', 'zmm_pumpidentification', 'zmm_psettype', 'zmm_size', 'zmm_eff_ttl', 'zmm_type', 'zmm_usp', 'created_at', 'updated_at', 'created_by', 'updated_by', 'deleted_at',
            ];

            $filteredData = $characteristicsData->map(function ($char) use ($remFields) {
                $charArray = $char->toArray();

                // Unset only the columns present in $manFields
                foreach ($remFields as $field) {
                    unset($charArray[$field]);
                }
                // unset(
                //     $charArray['id'],
                //     $charArray['plant_id']
                // );

                $charArray['pending_released_status'] = (string) $charArray['pending_released_status'] ?? '';

                $charArray['marked_by'] = ($charArray['marked_by'] == 'Admin') ? 'jothi' : $charArray['marked_by'] ?? '';
                $charArray['man_marked_by'] = ($charArray['man_marked_by'] == 'Admin') ? 'jothi' : $charArray['man_marked_by'] ?? '';

                foreach ($charArray as $key => $value) {
                    if ($value instanceof \Carbon\Carbon) {
                        $charArray[$key] = $value->timezone('Asia/Kolkata')->format('Y-m-d H:i:s');
                    } elseif (is_string($value) && preg_match('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$/', $value)) {
                        $charArray[$key] = \Carbon\Carbon::parse($value)
                            ->timezone('Asia/Kolkata')
                            ->format('Y-m-d H:i:s');
                    } elseif (is_null($value)) {
                        $charArray[$key] = '';
                    }
                }

                return $charArray;
            });

            // $response = [
            //     'characteristics2' => $filteredData
            // ];
            // return response()->json($response);
            return response()->json([
                'characteristics' => $filteredData,
            ], 200);
        }
    }

    public function checkClassChar(Request $request)
    {
        $expectedUser = env('API_AUTH_USER');
        $expectedPw = env('API_AUTH_PW');
        $header_auth = $request->header('Authorization');
        $expectedToken = $expectedUser.':'.$expectedPw;

        if ('Bearer '.$expectedToken != $header_auth) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid authorization token!',
            ], 403);
        }

        $userName = $request->header('user-name');

        $plantCode = $request->header('plant-code');

        $workCenter = $request->header('work-center');

        $jobNumber = $request->header('job-number');

        $itemCode = $request->header('item-code');

        $serialNumber = $request->header('serial-number');

        if (! $userName) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "User Name can't be empty!",
            ], 404);
        } elseif ($userName == 'jothi') {
            $userName = 'Admin';
        }

        if (! $plantCode || $plantCode == null || $plantCode == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant code can't be empty!",
            ], 400);
        } elseif (! is_numeric($plantCode) || Str::length($plantCode) < 4 || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) { // !ctype_digit($data['plant_code'])
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid plant code found!',
            ], 400);
        }

        if (! $workCenter || $workCenter == null || $workCenter == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work Center can't be empty!",
            ], 404);
        }

        $plant = Plant::where('code', $plantCode)->first();

        if (! $plant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant Code '{$plantCode}' not found!",
            ], 404);
        }

        $plantId = $plant->id;

        $user = User::where('name', $userName)->first();

        $userPlant = User::where('name', $userName)->where('plant_id', $plantId)->first();

        if (! $user) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User Name not found!',
            ], 403);
        } elseif (! $userPlant && ! $user->hasRole('Super Admin')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User Name not found for the plant!',
            ], 403);
        } elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Design Manager') && ! $user->hasRole('Design Supervisor') && ! $user->hasRole('Design Employee')) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'User does not have rights!',
            ], 403);
        }

        $work = Machine::where('work_center', $workCenter)->first();

        if (! $work) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work Center '{$workCenter}' not found!",
            ], 404);
        }

        $machine = Machine::where('work_center', $workCenter)
            ->where('plant_id', $plantId)
            ->first();

        if (! $machine) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work Center '{$workCenter}' not found for the plant code '{$plantCode}'!",
            ], 404);
        }

        $machineId = $machine->id;

        if (($itemCode == '' || $itemCode == null) && ($serialNumber == '' || $serialNumber == null)) {
            if (! $jobNumber) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number can't be empty",
                ], 404);
            } elseif (Str::length($jobNumber) < 7) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' should contain minimum 7 digits!",
                ], 400);
            } elseif (! is_numeric($jobNumber)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' should contain only numeric values!",
                ], 400);
            }

            $job = ClassCharacteristic::where('aufnr', $jobNumber)->first();

            if (! $job) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found!",
                ], 400);
            }

            $jobPlant = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->first();

            if (! $jobPlant) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found for the plant code '{$plantCode}'!",
                ], 400);
            }

            $jobWorkCenter = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->first();

            if (! $jobWorkCenter) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found for the work center '{$workCenter}'!",
                ], 400);
            }

            // $columnsToShow = ['mark_status','marked_datetime','marked_by','man_marked_status','man_marked_datetime','man_marked_by','motor_marked_status','pump_marked_status','motor_pump_pumpset_status','part_validation_1','part_validation_2','samlight_logged_name','pending_released_status','expected_time'];

            $characteristicsColumns = ['class', 'arbid', 'gamng', 'lmnga', 'zz1_cn_bill_ord', 'zmm_amps', 'zmm_brand', 'zmm_degreeofprotection', 'zmm_delivery', 'zmm_dir_rot', 'zmm_discharge', 'zmm_discharge_max', 'zmm_discharge_min', 'zmm_duty', 'zmm_eff_motor', 'zmm_eff_pump', 'zmm_frequency', 'zmm_head', 'zmm_heading', 'zmm_head_max', 'zmm_head_minimum', 'zmm_idx_eff_mtr', 'zmm_idx_eff_pump', 'zmm_kvacode', 'zmm_maxambtemp', 'zmm_mincoolingflow', 'zmm_motorseries', 'zmm_motor_model', 'zmm_outlet', 'zmm_phase', 'zmm_pressure', 'zmm_pumpflowtype', 'zmm_pumpseries', 'zmm_pump_model', 'zmm_ratedpower', 'zmm_region', 'zmm_servicefactor', 'zmm_servicefactormaximumamps', 'zmm_speed', 'zmm_suction', 'zmm_suctionxdelivery', 'zmm_supplysource', 'zmm_temperature', 'zmm_thrustload', 'zmm_volts', 'zmm_wire', 'zmm_package', 'zmm_pvarrayrating', 'zmm_isi', 'zmm_isimotor', 'zmm_isipump', 'zmm_isipumpset', 'zmm_pumpset_model', 'zmm_stages', 'zmm_headrange', 'zmm_overall_efficiency', 'zmm_connection', 'zmm_min_bore_size', 'zmm_isireference', 'zmm_category', 'zmm_submergence', 'zmm_capacitorstart', 'zmm_capacitorrun', 'zmm_inch', 'zmm_motor_type', 'zmm_dismantle_direction', 'zmm_eff_ovrall', 'zmm_bodymoc', 'zmm_rotormoc', 'zmm_dlwl', 'zmm_inputpower', 'zmm_imp_od', 'zmm_ambtemp', 'zmm_de', 'zmm_dischargerange', 'zmm_efficiency_class', 'zmm_framesize', 'zmm_impellerdiameter', 'zmm_insulationclass', 'zmm_maxflow', 'zmm_minhead', 'zmm_mtrlofconst', 'zmm_nde', 'zmm_powerfactor', 'zmm_tagno', 'zmm_year', 'zmm_laser_name'];

            $characteristicsData = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                // ->get();
                ->distinct()
                ->get($characteristicsColumns);

            if ($characteristicsData->isEmpty()) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'No characteristics data found for the provided Plant, Work Center, and Job Number!',
                ], 400);
            }

            // $serials = ClassCharacteristic::where('plant_id', $plantId)
            //     ->where('machine_id', $machineId)
            //     ->where('aufnr', $jobNumber)
            //     ->orderBy('gernr')
            //     //->get(array_merge(['gernr'], $columnsToShow));
            //     ->get(array_merge(['gernr', 'item_id'], $columnsToShow));

            // $itemId = $serials->first()->item_id;
            // $itemcode = Item::where('id', $itemId)->value('code') ?? '';

            $markedSerials = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('aufnr', $jobNumber)
                ->get(['gernr', 'mark_status']);

            $allMarked = $markedSerials->every(function ($serial) {
                return strtolower($serial->mark_status) == 'marked';
            });

            if ($allMarked) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'All serial numbers are already marked!',
                ], 400);
            } else {
                return response()->json([
                    'status_code' => 'SUCCESS',
                    'status_description' => 'Has some pending serial numbers to mark.',
                ], 200);
            }
        } elseif ((($itemCode != '' && $itemCode != null) || ($serialNumber != '' && $serialNumber != null)) && $jobNumber != '' && $jobNumber != null) {
            // return response()->json([
            //     'status_code' => "ERROR",
            //     'status_description' => "Item Code or Serial Number should be empty while checking job number characteristics!"
            // ], 400);
            if (! $jobNumber) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number can't be empty",
                ], 404);
            } elseif (Str::length($jobNumber) < 7) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' should contain minimum 7 digits!",
                ], 400);
            } elseif (! is_numeric($jobNumber)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' should contain only numeric values!",
                ], 400);
            }

            if (Str::length($serialNumber) < 9) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' should contain minimum 9 digits!",
                ], 400);
            } elseif (! ctype_alnum($serialNumber)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' should contain only alpha-numeric values!",
                ], 400);
            }

            if (Str::length($itemCode) < 6) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'Item code should contain minimum 6 digits!',
                ], 400);
            } elseif (! ctype_alnum($itemCode)) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item code '{$itemCode}' should contain only alpha-numeric values!",
                ], 400);
            }

            $job = ClassCharacteristic::where('aufnr', $jobNumber)->first();

            if (! $job) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found!",
                ], 400);
            }

            $jobPlant = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->first();

            if (! $jobPlant) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found for the plant code '{$plantCode}'!",
                ], 400);
            }

            $jobWorkCenter = ClassCharacteristic::where('aufnr', $jobNumber)
                ->where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->first();

            if (! $jobWorkCenter) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Job number '{$jobNumber}' not found for the work center '{$workCenter}'!",
                ], 400);
            }

            $item = Item::where('code', $itemCode)->first();

            if (! $item) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item code '{$itemCode}' not found!",
                ], 404);
            }

            $itemPlant = Item::where('code', $itemCode)
                ->where('plant_id', $plantId)
                ->first();

            if (! $itemPlant) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Item code '{$itemCode}' not found for the plant code '{$plantCode}'!",
                ], 404);
            }

            $itemId = $itemPlant->id; // Item::where('code', $itemCode)->where('plant_id', $plantId)->value('id');

            $serialExists = ClassCharacteristic::where('gernr', $serialNumber)->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' not found!",
                ], 404);
            }

            $serialExists = ClassCharacteristic::where('plant_id', $plantId)
                ->where('gernr', $serialNumber)
                ->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' not found for plant code '{$plantCode}'!",
                ], 404);
            }

            $serialExists = ClassCharacteristic::where('plant_id', $plantId)
                ->where('gernr', $serialNumber)
                ->where('item_id', $itemId)
                ->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' with item code '{$itemCode}' not found for plant code '{$plantCode}'!",
                ], 404);
            }

            $serialExists = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('gernr', $serialNumber)
                ->where('item_id', $itemId)
                ->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' with item code '{$itemCode}' not found for work center '{$workCenter}'!",
                ], 404);
            }

            $serialExists = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('aufnr', $jobNumber)
                ->where('gernr', $serialNumber)
                ->where('item_id', $itemId)
                ->first();

            if (! $serialExists) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => "Serial number '{$serialNumber}' with item code '{$itemCode}' not found for job number '{$jobNumber}'!",
                ], 404);
            }

            $markedSerials = ClassCharacteristic::where('plant_id', $plantId)
                ->where('machine_id', $machineId)
                ->where('aufnr', $jobNumber)
                ->get(['gernr', 'mark_status']);

            $allMarked = $markedSerials->every(function ($serial) {
                return strtolower($serial->mark_status) == 'marked';
            });

            if ($allMarked) {
                return response()->json([
                    'status_code' => 'ERROR',
                    'status_description' => 'All serial numbers are already marked!',
                ], 400);
            }

            // if ($serialExists->mark_status != 'Marked' && $serialExists->mark_status != 'marked')
            // {
            //     return response()->json([
            //         'status_code' => "ERROR",
            //         'status_description' => "Serial number '{$serialNumber}' does not marked in AUTO mode! Please, close MANUAL window and proceed with AUTO mode to start laser marking..!",
            //     ], 404);
            // }

            // $columnsToShow = ['mark_status','marked_datetime','marked_by','man_marked_status','man_marked_datetime','man_marked_by','motor_marked_status','pump_marked_status','motor_pump_pumpset_status','part_validation_1','part_validation_2','samlight_logged_name','pending_released_status','expected_time'];

            // $characteristicsColumns = ['class','arbid','gamng','lmnga','zz1_cn_bill_ord','zmm_amps','zmm_brand','zmm_degreeofprotection','zmm_delivery','zmm_dir_rot','zmm_discharge','zmm_discharge_max','zmm_discharge_min','zmm_duty','zmm_eff_motor','zmm_eff_pump','zmm_frequency','zmm_head','zmm_heading','zmm_head_max','zmm_head_minimum','zmm_idx_eff_mtr','zmm_idx_eff_pump','zmm_kvacode','zmm_maxambtemp','zmm_mincoolingflow','zmm_motorseries','zmm_motor_model','zmm_outlet','zmm_phase','zmm_pressure','zmm_pumpflowtype','zmm_pumpseries','zmm_pump_model','zmm_ratedpower','zmm_region','zmm_servicefactor','zmm_servicefactormaximumamps','zmm_speed','zmm_suction','zmm_suctionxdelivery','zmm_supplysource','zmm_temperature','zmm_thrustload','zmm_volts','zmm_wire','zmm_package','zmm_pvarrayrating','zmm_isi','zmm_isimotor','zmm_isipump','zmm_isipumpset','zmm_pumpset_model','zmm_stages','zmm_headrange','zmm_overall_efficiency','zmm_connection','zmm_min_bore_size','zmm_isireference','zmm_category','zmm_submergence','zmm_capacitorstart','zmm_capacitorrun','zmm_inch','zmm_motor_type','zmm_dismantle_direction','zmm_eff_ovrall','zmm_bodymoc','zmm_rotormoc','zmm_dlwl','zmm_inputpower','zmm_imp_od','zmm_ambtemp','zmm_de','zmm_dischargerange','zmm_efficiency_class','zmm_framesize','zmm_impellerdiameter','zmm_insulationclass','zmm_maxflow','zmm_minhead','zmm_mtrlofconst','zmm_nde','zmm_powerfactor','zmm_tagno','zmm_year','zmm_laser_name'];

            // $characteristicsData = ClassCharacteristic::where('aufnr', $jobNumber)
            //     ->where('plant_id', $plantId)
            //     ->where('machine_id', $machineId)
            //     //->get();
            //     ->distinct()
            //     ->get($characteristicsColumns);

            // if ($characteristicsData->isEmpty()) {
            //     return response()->json([
            //         'status_code' => "ERROR",
            //         'status_description' => 'No characteristics data found for the provided Plant, Work Center, and Job Number!'
            //     ], 400);
            // }

            return response()->json([
                'MARK_STATUS' => $serialExists->mark_status ?? '',
                'MARKED_DATETIME' => $serialExists->marked_datetime,
                'MARKED_BY' => $serialExists->marked_by,
                'MAN_MARKED_STATUS' => $serialExists->man_marked_status,
                'MAN_MARKED_DATETIME' => $serialExists->man_marked_datetime ?? '',
                'MAN_MARKED_BY' => $serialExists->man_marked_by ?? '',
                'MOTOR_MARKED_STATUS' => $serialExists->motor_marked_status ?? '',
                'PUMP_MARKED_STATUS' => $serialExists->pump_marked_status ?? '',
                'MOTOR_PUMP_PUMPSET_STATUS' => $serialExists->motor_pump_pumpset_status ?? '',
            ], 200);
        }
    }

    public function getCharMaster(Request $request)
    {

        $expectedUser = env('API_AUTH_USER');
        $expectedPw = env('API_AUTH_PW');
        $header_auth = $request->header('Authorization');
        $expectedToken = $expectedUser.':'.$expectedPw;

        if ('Bearer '.$expectedToken != $header_auth) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid authorization token!',
            ], 403);
        }

        $plantCode = $request->header('plant-code');
        $itemCode = $request->header('item-code');
        $lineName = $request->header('line-name');
        $workCenter = $request->header('work-center');

        if ($plantCode == null || $plantCode == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Plant code can't be empty!",
            ], 400);
        } elseif (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid plant code found!',
            ], 400);
        } elseif ($itemCode == null || $itemCode == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item Code can't be empty!",
            ], 400);
        } elseif (Str::length($itemCode) < 6 || ! ctype_alnum($itemCode)) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Invalid item code found!',
            ], 400);
        } elseif ($lineName == null || $lineName == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Line name can't be empty!",
            ], 400);
        } elseif ($workCenter == null || $workCenter == '') {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center can't be empty!",
            ], 400);
        }

        $plant = Plant::where('code', $plantCode)->first();

        if (! $plant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Plant not found!',
            ], 400);
        }

        $plantId = $plant->id;

        $item = Item::where('code', $itemCode)->first();

        if (! $item) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Item Code not found in item table!',
            ], 404);
        }

        $item = Item::where('plant_id', $plantId)->where('code', $itemCode)->first();

        if (! $item) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Item Code not found in item table for the plant : '$plant->name'!",
            ], 404);
        }

        $line = Line::where('name', $lineName)->first();

        if (! $line) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Line not found in lines table!',
            ], 404);
        }

        $lineAgaPlant = Line::where('plant_id', $plantId)->where('name', $lineName)->first();

        if (! $lineAgaPlant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Line Name not found in lines table for the plant : '$plant->name'!",
            ], 404);
        }

        $work = Machine::where('work_center', $workCenter)->first();

        if (! $work) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => 'Work Center not found in machines table!',
            ], 404);
        }

        $workAgaPlant = Machine::where('plant_id', $plantId)->where('work_center', $workCenter)->first();

        if (! $workAgaPlant) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Work center not found in machines table for the plant : '$plant->name'!",
            ], 404);
        }

        // $description = $item ? $item->description : '';

        // $uom = $item ? $item->uom : '';

        // $category = $item ? $item->category : '';

        $charMaster = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('item_id', $item->id)
            ->where('line_id', $lineAgaPlant->id)->where('machine_id', $workAgaPlant->id)
            ->first();

        if (! $charMaster) {
            return response()->json([
                'status_code' => 'ERROR',
                'status_description' => "Characteristics not found in product master table for the plant : '$plant->name'!",
            ], 404);
        }

        $workGroup = WorkGroupMaster::find($charMaster->work_group_master_id);
        $workGroupName = $workGroup?->name ?? '';

        $output = [
            'work_group_master' => $workGroupName ?? '',
            'name' => $charMaster?->name ?? '',
            'inspection_type' => $charMaster?->inspection_type ?? '',
            'characteristics_type' => $charMaster?->characteristics_type ?? '',
            'upper' => (string) $charMaster?->upper ?? '',
            'lower' => (string) $charMaster?->lower ?? '',
            'middle' => (string) $charMaster?->middle ?? '',
        ];

        return response()->json($output, 200);
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}
