<?php

namespace Modules\Internal\Services;

use App\Exceptions\ImportRowException;
use App\Helpers\Helper;
use App\Models\Corporate;
use App\Models\CorporateEmployee;
use App\Models\CorporateDivision;
use App\Models\CorporatePolicy;
use App\Models\CorporatePlan;
use App\Models\Member;
use App\Models\MemberPolicy;
use App\Models\MemberPlan;
use App\Models\Person;
use App\Models\Plan;
use App\Models\OLDLMS\User;
use App\Models\OLDLMS\UserDetail;
use App\Models\OLDLMS\UserInsurance;
use App\Models\OLDLMS\UserInsuranceDetail;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Box\Spout\Common\Entity\Row;
use Carbon\Carbon;
use DateTime;
use DB;

class MemberEnrollmentService
{
    public $doc_headers_to_field_map = [
        "Record Mode"                                                               => "record_mode",
        "Record Type"                                                               => "record_type",
        "Payor ID"                                                                  => "payor_id",
        "Member ID"                                                                 => "member_id",
        "Mapping ID"                                                                => "principal_id",
        "LinkSehat Member ID"                                                         => "halodoc_member_id",
        "Corporate ID"                                                              => "corporate_id",
        "NIK"                                                                       => "nik",
        "Division"                                                                  => "division_name",
        "Branch Code"                                                               => "branch_code",
        "Bank Info"                                                                 => "banks_info",
        "Language"                                                                  => "language",
        "Type of work"                                                              => "type_of_work",
        "Race"                                                                      => "race",
        "Policy Number"                                                             => "policy_number",
        // "Policy No."                                                                => "policy_number",
        "Marital Status"                                                            => "marital_status",
        "Relationship"                                                              => "relationship_with_principal",
        "Member's Effective Date"                                                   => "member_effective_date",
        "Member's Expiry Date"                                                      => "member_expiry_date",
        "Faskes FKTP  (First Level Provider) or Individual preferred provider"      => "faskes_fktp",
        "Faskes FKRTL (Next Level Provider) or Individual group preferred provider" => "faskes_fkrtl",
        "The Right Classes Room of  BPJS Participants"                              => "bpjs_class",
        "Name of Faskes"                                                            => "faskes_name",
        "Rule_BPJSK ('Y' or 'N')"                                                   => "bpjsk",
        "Rule BPJSK"                                                                => "bpjsk",
        "Agent Code / intermediary code"                                            => "agent_code",
        "Member Name"                                                               => "name",
        "Address1"                                                                  => "address1",
        // "Address 1"                                                                 => "address1",
        "Address2"                                                                  => "address2",
        "Address3"                                                                  => "address3",
        "Address4"                                                                  => "address4",
        "City"                                                                      => "city",
        "State"                                                                     => "state",
        "Post Code"                                                                 => "post_code",
        "Telephone - Mobile"                                                        => "telephone_mobile",
        "Telephone – Mobile"                                                        => "telephone_mobile",
        "Telephone - mobile"                                                        => "telephone_mobile",
        "Telephone – Res"                                                           => "telephone_res",
        "Telephone Res"                                                             => "telephone_res",
        "Telephone - Res"                                                           => "telephone_res",
        "Telephone – Office"                                                        => "telephone_office",
        "Telephone - Office"                                                        => "telephone_office",
        "NRIC"                                                                      => "nric",
        "Passport No"                                                               => "passport_number",
        "Passport Country"                                                          => "passport_country",
        "Email"                                                                     => "email",
        "Identification Code"                                                       => "identification_code",
        "Date of Birth"                                                             => "date_of_birth",
        "Sex"                                                                       => "sex",
        "Internal Use"                                                              => "internal_use",
        "Plan-ID"                                                                   => "plan_id",
        "Employment-Status"                                                         => "employment_status",
        "Internal Use"                                                              => "internal_use_1",
        "Internal Use"                                                              => "internal_use_2",
        "Internal Use"                                                              => "internal_use_3",
        "Date Terminated"                                                           => "date_terminated",
        "Pre Existing"                                                              => "pre_existing",
        "BPJS ID"                                                                   => "bpjs_id",
        "Endorsement Date"                                                          => "endorsement_date",
        "Remarks"                                                                   => "remarks",
        "Internal Use"                                                              => "internal_use_4",
        "Member Since"                                                              => "member_since",
        "Internal Use"                                                              => "internal_use_5",
        "Policy In Force"                                                           => "policy_in_force",
        "Member Suspended"                                                          => "member_suspended",
        "Activation Date"                                                           => "activation_date",
        "Internal Use"                                                              => "internal_use_6",
        "Date Terminated"                                                           => "date_terminated",
        "StartNoClaim"                                                              => "start_no_claim",
        "EndNoClaim"                                                                => "end_no_claim",
        "Option Mode"                                                               => "option_mode",
        "Policy Inforce"                                                            => "policy_in_force",
        "Renewal activation date"                                                   => "renewal_activation_date",
        // "Renewal Activation Date"                                                   => "renewal_activation_date",
        "Ingestion Code"                                                            => "ingestion_code", // TODO I think this should not be here because if user uploading result then ingestion code and status will be filled
        "Ingestion Status"                                                          => "ingestion_status",
    ];

    public $field_to_doc_headers_map = [
        "record_mode"                       => "Record Mode",
        "record_type"                       => "Record Type",
        "payor_id"                          => "Payor ID",
        "member_id"                         => "Member ID",
        "principal_id"                      => "Mapping ID",
        "halodoc_member_id"                 => "LinkSehat Member ID",
        "corporate_id"                      => "Corporate ID",
        "nik"                               => "NIK",
        "division_name"                     => "Division",
        "branch_code"                       => "Branch Code",
        "banks_info"                        => "Bank Info",
        "language"                          => "Language",
        "type_of_work"                      => "Type of work",
        "race"                              => "Race",
        "policy_number"                     => "Policy Number",
        // "policy_number"                     => "Policy No.",
        "marital_status"                    => "Marital Status",
        "relationship_with_principal"       => "Relationship",
        "member_effective_date"             => "Member's Effective Date",
        "member_expiry_date"                => "Member's Expiry Date",
        "faskes_fktp"                       => "Faskes FKTP  (First Level Provider) or Individual preferred provider",
        "faskes_fkrtl"                      => "Faskes FKRTL (Next Level Provider) or Individual group preferred provider",
        "bpjs_class"                        => "The Right Classes Room of  BPJS Participants",
        "faskes_name"                       => "Name of Faskes",
        "bpjsk"                             => "Rule BPJSK",
        "agent_code"                        => "Agent Code / intermediary code",
        "name"                              => "Member Name",
        "address1"                          => "Address1",
        // "address1"                          => "Address 1",
        "address2"                          => "Address2",
        "address3"                          => "Address3",
        "address4"                          => "Address4",
        "city"                              => "City",
        "state"                             => "State",
        "post_code"                         => "Post Code",
        "telephone_mobile"                  => "Telephone - Mobile",
        "telephone_res"                     => "Telephone - Res",
        "telephone_office"                  => "Telephone - Office",
        "nric"                              => "NRIC",
        "passport_number"                   => "Passport No",
        "passport_country"                  => "Passport Country",
        "email"                             => "Email",
        "identification_code"               => "Identification Code",
        "date_of_birth"                     => "Date of Birth",
        "sex"                               => "Sex",
        "internal_use"                      => "Internal Use",
        "plan_id"                           => "Plan-ID",
        "employment_status"                 => "Employment-Status",
        "internal_use_1"                    => "Internal Use",
        "internal_use_2"                    => "Internal Use",
        "internal_use_3"                    => "Internal Use",
        "date_terminated"                   => "Date Terminated",
        "pre_existing"                      => "Pre Existing",
        "bpjs_id"                           => "BPJS ID",
        "endorsement_date"                  => "Endorsement Date",
        "remarks"                           => "Remarks",
        "internal_use_4"                    => "Internal Use",
        "member_since"                      => "Member Since",
        "internal_use_5"                    => "Internal Use",
        "policy_inforce"                    => "Policy Inforce",
        "policy_in_force"                   => "Policy In Force",
        "member_suspended"                  => "Member Suspended",
        "activation_date"                   => "Activation Date",
        "internal_use_6"                    => "Internal Use",
        "start_no_claim"                    => "StartNoClaim",
        "end_no_claim"                      => "EndNoClaim",
        "option_mode"                       => "Option Mode",
        // "renewal_activation_date"           => "Renewal Activation Date",
        "ingestion_code"                    => "Ingestion Code",
        "ingestion_status"                  => "Ingestion Status",
    ];

    public $result_doc_headers = [
        "Record Mode",
        "Record Type",
        "Payor ID",
        "Member ID",
        "Mapping ID",
        "LinkSehat Member ID",
        "Corporate ID",
        "NIK",
        "Division",
        "Branch Code",
        "Bank Info",
        "Language",
        "Type of work",
        "Race",
        "Policy Number",
        // "Policy No.",
        "Marital Status",
        "Relationship",
        "Member's Effective Date",
        "Member's Expiry Date",
        "Faskes FKTP  (First Level Provider) or Individual preferred provider",
        "Faskes FKRTL (Next Level Provider) or Individual group preferred provider",
        "The Right Classes Room of  BPJS Participants",
        "Name of Faskes",
        "Rule BPJSK",
        "Internal Use",
        "Member Name",
        "Address1",
        // "Address 1",
        "Address2",
        "Address3",
        "Address4",
        "City",
        "State",
        "Post Code",
        "Telephone - Mobile",
        "Telephone - Res",
        "Telephone - Office",
        "NRIC",
        "Passport No",
        "Passport Country",
        "Email",
        "Identification Code",
        "Date of Birth",
        "Sex",
        "Internal Use",
        "Plan-ID",
        "Employment-Status",
        "Internal Use",
        "Internal Use",
        "Internal Use",
        "Date Terminated",
        "Pre Existing",
        "BPJS ID",
        "Endorsement Date",
        "Remarks",
        "Internal Use",
        "Member Since",
        "Internal Use",
        "Policy Inforce",
        "Member Suspended",
        "Activation Date",
        "Internal Use",
        "StartNoClaim",
        "EndNoClaim",
        "Option Mode",
        // "Renewal Activation Date",
        "Ingestion Code",
        "Ingestion Status",
    ];

    public $listing_doc_headers = [
        "Record Mode",
        "Record Type",
        "Payor ID",
        "Member ID",
        "Mapping ID",
        "LinkSehat Member ID",
        "Corporate ID",
        "NIK",
        "Division",
        "Branch Code",
        "Bank Info",
        "Language",
        "Type of work",
        "Race",
        "Policy Number",
        // "Policy No.",
        "Marital Status",
        "Relationship",
        "Member's Effective Date",
        "Member's Expiry Date",
        "Faskes FKTP  (First Level Provider) or Individual preferred provider",
        "Faskes FKRTL (Next Level Provider) or Individual group preferred provider",
        "The Right Classes Room of  BPJS Participants",
        "Name of Faskes",
        "Rule BPJSK",
        "Internal Use",
        "Member Name",
        "Address1",
        // "Address 1",
        "Address2",
        "Address3",
        "Address4",
        "City",
        "State",
        "Post Code",
        "Telephone - Mobile",
        "Telephone - Res",
        "Telephone - Office",
        "NRIC",
        "Passport No",
        "Passport Country",
        "Email",
        "Identification Code",
        "Date of Birth",
        "Sex",
        "Internal Use",
        "Plan-ID",
        "Employment-Status",
        "Internal Use",
        "Internal Use",
        "Internal Use",
        "Date Terminated",
        "Pre Existing",
        "BPJS ID",
        "Endorsement Date",
        "Remarks",
        "Internal Use",
        "Member Since",
        "Internal Use",
        "Policy Inforce",
        "Member Suspended",
        "Activation Date",
        "Internal Use",
        "StartNoClaim",
        "EndNoClaim",
        "Option Mode",
        // "Renewal Activation Date",
        // "Ingestion Code",
        // "Ingestion Status",
    ];

    public $doc_headers_send_email = [
        "Name",
        "Email",
        "Message"
    ];

    public function __construct(Member $member)
    {
        app()->setLocale('en');
        $this->member = $member;
    }

    public function dateParser($date_from_row) {

        if ($date_from_row instanceof DateTime) {
            return $date_from_row->format('Y-m-d');
        } else if ($date_from_row != null) {
            if (strtotime($date_from_row)){
                return date('Y-m-d', strtotime($date_from_row));
            } else {
            //    throw new ImportRowException(__('Format Date Invalid'), 0, null, $date_from_row);
                return null;
            }
        } else {
            // throw new ImportRowException(__('Format Date Invalid'), 0, null, $date_from_row);
            return null;
        }
    }

    public function validateDate($dateString, $dateFormat = 'Ymd'){
        $date = DateTime::createFromFormat($dateFormat, $dateString);
        if ($date && ($date->format($dateFormat) == $dateString)) {
           return true;
        } else {
           return false;
        }
    }

    protected function validateRow($row)
    {
        $title =[
            'member_effective_date' => 'Member Effective Date',
            'member_expiry_date' => 'Member Expired Date',
            'activation_date' => 'Activation Date',
            'date_of_birth' => 'Date of Birth',
            'date_terminated' => 'Date Terminated',

        ];

        if (empty($row['record_type'])) {
            throw new ImportRowException(__('enrollment.RECORD_TYPE_REQUIRED'), 0, null, $row);
        }

        if (empty($row['payor_id'])) {
            throw new ImportRowException(__('enrollment.PAYOR_ID_REQUIRED'), 0, null, $row);
        }

        if (empty($row['member_id'])) {
            throw new ImportRowException(__('enrollment.MEMBER_ID_REQUIRED'), 0, null, $row);
        }

        if (empty($row['plan_id'])) {
            throw new ImportRowException(__('Plan ID Required'), 0, null, $row);
        }

        if ($row['record_type'] == 'P') {
            if (!empty($row['principal_id'])) {
                throw new ImportRowException(__('enrollment.PRINCIPAL_ID_NOT_REQUIRED'), 0, null, $row);
            }

            if (empty($row['corporate_id'])) {
                throw new ImportRowException(__('enrollment.CORPORATE_ID_REQUIRED'), 0, null, $row);
            }
        }

        if ($row['record_type'] == 'D') {
            $member = Member::query()
            ->where('member_id', $row['principal_id'])
            // ->whereHas('employeds', function ($query) use ($corporate) {
            //     $query->where('corporate_id', $corporate->id);
            // })
            ->first();

            if(empty($member)){
                // throw new ImportRowException(__('enrollment.PRINCIPAL_NOT_IN_MEMBER_ID'), 0, null, $row);
            } else {
                // if ($member['record_type'] != 'P'){
                //     throw new ImportRowException(__('enrollment.PRINCIPAL_ID_NOT_SAME_MEMBER_ID'), 0, null, $row);
                // }
            }
            if (empty($row['principal_id'])) {
                throw new ImportRowException(__('enrollment.PRINCIPAL_ID_REQUIRED'), 0, null, $row);
            }
            // if (empty($row['relationship_with_principal'])){
            //     throw new ImportRowException(__('enrollment.RELATIONSHIP_WITH_PRICIPAL_REQUIRED'), 0, null, $row);
            // }
            // if (!empty($row['relationship_with_principal']) && !in_array($row['relationship_with_principal'], ['H', 'W', 'D', 'S'])){
            //     throw new ImportRowException(__('enrollment.RELATIONSHIP_WITH_PRICIPAL_NOT_VALID'), 0, null, $row);
            // }


        }

        // TODO RECORD BCA ONLY
        if ($row['record_type'] == 'D' && !empty($row['branch_code'])) {
            throw new ImportRowException(__('enrollment.BRANCH_CODE_NOT_REQUIRED'), 0, null, $row);
        }

        // TODO BANK VALIDATION
        // if ($row['record_type'] == 'D' && !empty($row['branch_code'])) {
        //     throw new ImportRowException(__('enrollment.BRANCH_CODE_NOT_REQUIRED'), 0, null, $row);
        // }

        // if (!empty($row['language']) && !in_array($row['language'], ['M', 'E', 'C', 'I', 'O'])) {
        //     throw new ImportRowException(__('enrollment.INVALID_LANGUAGE'), 0, null, $row);
        // }

        // if (!empty($row['type_of_work']) && !in_array($row['type_of_work'], ['0', '1', '2', '3'])) {
        //     throw new ImportRowException(__('enrollment.INVALID_TYPE_OF_WORK'), 0, null, $row);
        // }

        // if (!empty($row['race']) && !in_array($row['race'], ['M', 'C', 'I', 'O'])) {
        //     throw new ImportRowException(__('enrollment.INVALID_RACE'), 0, null, $row);
        // }

        if (empty($row['policy_number'])) {
            throw new ImportRowException(__('enrollment.POLICY_NUMBER_REQUIRED'), 0, null, $row);
        }

        // if (!empty($row['marital_status']) && !in_array($row['marital_status'], ['S', 'M', 'D'])) {
        //     throw new ImportRowException(__('enrollment.INVALID_MARITAL_STATUS'), 0, null, $row);
        // }

        // TODO EFFECTIVE DATE VALIDATION
        if (empty($row['member_effective_date'])) {
            throw new ImportRowException(__('enrollment.MEMBER_EFFECTIVE_REQUIRED'), 0, null, $row);
        }
        // if(!$this->validateDate($row['member_effective_date'])){
        //     throw new ImportRowException(__('enrollment.INVALID_DATE', [
        //         'title' => $title['member_effective_date']
        //     ]), 0, null, $row);
        // }

        if (empty($row['member_expiry_date'])) {
            throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_REQUIRED'), 0, null, $row);
        }
        // if(!$this->validateDate($row['member_expiry_date'])){
        //     throw new ImportRowException(__('enrollment.INVALID_DATE', [
        //         'title' => $title['member_expiry_date']
        //     ]), 0, null, $row);
        // }

        // TODO EFFECTIVE DATE VALIDATION
        // if (empty($row['activation_date'])) {
        //     throw new ImportRowException(__('enrollment.ACTIVATION_DATE_REQUIRED'), 0, null, $row);
        // }
        // if(!empty($row['activation_date'])){
        //     if(!$this->validateDate($row['activation_date'])){
        //         throw new ImportRowException(__('enrollment.INVALID_DATE', [
        //             'title' => $title['activation_date']
        //         ]), 0, null, $row);
        //     }
        // }
        // TODO FKTP VALIDATION
        // TODO FKRTL VALIDATION

        // if (!empty($row['marital_status']) && !in_array($row['marital_status'], ['S', 'M', 'D'])) {
        //     throw new ImportRowException(__('enrollment.INVALID_MARITAL_STATUS'), 0, null, $row);
        // }

        if (empty($row['name'])) {
            throw new ImportRowException(__('enrollment.NAME_REQUIRED'), 0, null, $row);
        }

        // if (!Helper::validatePhoneNumber($row['telephone_mobile'])){
        //     throw new ImportRowException(__('enrollment.PHONE_INVALID'), 0, null, $row);
        // }

        // if (
        //     !empty($row['telephone_mobile'])
        //     && !(substr($row['telephone_mobile'], 0, 4) == '+628' || substr($row['telephone_mobile'], 0, 3) == '628')
        // ) {
        //     throw new ImportRowException(__('enrollment.PHONE_INVALID'), 0, null, $row);
        // }

        // if (
        //     !empty($row['email'])
        //     && !filter_var($row['email'], FILTER_VALIDATE_EMAIL)
        // ) {
        //     throw new ImportRowException(__('enrollment.EMAIL_INVALID'), 0, null, $row);
        // }

        // if (empty($row['date_of_birth'])) {
        //     throw new ImportRowException(__('enrollment.DATE_OF_BIRTH_REQUIRED'), 0, null, $row);
        // }
        // if(!$this->validateDate($row['date_of_birth'])){
        //     throw new ImportRowException(__('enrollment.INVALID_DATE', [
        //         'title' => $title['date_of_birth']
        //     ]), 0, null, $row);
        // }

        // if (empty($row['date_terminated'])) {
        //     throw new ImportRowException(__('enrollment.DATE_OF_TERMINATED'), 0, null, $row);
        // }
        // if (!empty($row['date_terminated'])) {
        //     if(!$this->validateDate($row['date_terminated'])){
        //         throw new ImportRowException(__('enrollment.INVALID_DATE', [
        //             'title' => $title['date_terminated']
        //         ]), 0, null, $row);
        //     }
        // }
        // TODO DOB FORMAT VALIDATION

        // if (empty($row['sex'])) {
        //     throw new ImportRowException(__('enrollment.SEX_REQUIRED'), 0, null, $row);
        // }

        // if (!in_array($row['sex'], ['F', 'M'])){
        //     throw new ImportRowException(__('enrollment.SEX_CODE_NOT_VALID'), 0, null, $row);
        // }
    }


    public function handleImportRow(Corporate $corporate, $row)
    {
        try {
            $activation_date = NULL;
            if (!empty($row['activation_date'])){
                $activation_date = $row['activation_date'];
            }
            $date_terminated = NULL;
            if(!empty($row['date_terminated'])){
                $date_terminated = $row['date_terminated'];
            }

            $member_data = [
                "name" => $row['name'] ?? null,
                "member_id" => $row['member_id'] ?? null,
                "payor_id" => $row['payor_id'] ?? null,
                "nik" => $row['nik'] ?? null,
                // "birth_date" => $row['date_of_birth'] ? date("Y-m-d",$row['date_of_birth']) : null,
                "birth_date" => $this->dateParser($row['date_of_birth']),
                "gender" => Helper::genderNormalization($row['sex']),
                "language" => $row['language'] ?? null,
                "race" => $row['race'] ?? null,
                "marital_status" => $row['marital_status'] ?? null,
                "record_type" => $row['record_type'] ?? null,
                "record_mode" => $row['record_mode'] ?? null,
                "principal_id" => $row['principal_id'] ?? null,
                "relation_with_principal" => $row['relationship_with_principal'] ?? null,
                "bpjs_class" => $row['bpjs_class'] ?? null,
                "nric" => $row['nric'] ?? null,
                "email" => $row['email'] ?? null,
                "bank_info" => $row['banks_info'] ?? null,
                "agent_code" => $row['agent_code'] ?? null,
                "address1" => $row['address1'] ?? null,
                "address2" => $row['address2'] ?? null,
                "address3" => $row['address3'] ?? null,
                "address4" => $row['address4'] ?? null,
                "city" => $row['city'] ?? null,
                "state" => $row['state'] ?? null,
                "postal_code" => $row['post_code'] ?? null,
                "passport_no" => $row['passport_number'] ?? null,
                "passport_country" => $row['passport_country'] ?? null,
                "identification_code" => $row['identification_code'] ?? null,
                "pre_existing" => $row['pre_existing'] ?? null,
                "bpjs_id" => $row['bpjs_id'] ?? null,
                "endorsement_date" => $row['endorsement_date'] ?? null,
                "remarks" => $row['remarks'] ?? null,
                "policy_in_force" => $row['policy_in_force'] ?? null,
                "start_no_claim" => $row['start_no_claim'] ?? null,
                "end_no_claim" => $row['end_no_claim'] ?? null,
                "plan_id" => $row['plan_id'] ?? null,

                "members_effective_date" => $row['member_effective_date'] ?? null,
                "members_expire_date" => $row['member_expiry_date'] ?? null,
                "activation_date" => $activation_date,
                "terminated_date" => $date_terminated,

                "telephone_mobile" => $row['telephone_mobile'] ?? null,
                "telephone_res" => $row['telephone_res'] ?? null,
                "telephone_office" => $row['telephone_office'] ?? null,
                "suspended" => $row['member_suspended'] ?? null,

                "active" => $row['employment_status'] == 'INACTIVE' ? 0 : 1,

                "employee_status" => $row['employment_status']
            ];
            // $this->validateRow($row);
            if (!isset($corporate->currentPolicy) || $corporate->currentPolicy->code != $row['policy_number']) {
                throw new ImportRowException(__('enrollment.POLICY_NUMBER_NOT_MATCH', [
                    'policy_id' => $row['policy_number']
                ]), 0, null, $row);
            }

            // validasi member efektif date range date in periode date coroporate
            // $member_effective_date = date("Y-m-d", strtotime($row['member_effective_date']));
            // $date_terminated = date("Y-m-d", strtotime($row['date_terminated']));

            $member_effective_date = $this->dateParser($row['member_effective_date']);
            $date_terminated = $this->dateParser($row['date_terminated']);


            if(!empty($row['activation_date'])){
                // $activation_date = date("Y-m-d", strtotime($row['activation_date']));
                // if (($activation_date == $date_terminated) && ($activation_date == $member_effective_date)) {
                //     throw new ImportRowException(__('enrollment.MORE_THAN', [
                //         'date_param' => 'Activation Date',
                //         'date' => $activation_date,
                //         'date_param2' => 'Member Effective Date',
                //         'start' => $activation_date
                //     ]), 0, null, $row);
                // }
            }
            if (!empty($row['date_terminated'])){
                // $date_terminated = date("Y-m-d", strtotime($row['date_terminated']));
                // if($date_terminated){
                //     if ($date_terminated <= $member_effective_date && ($date_terminated != $member_effective_date)) {
                //         throw new ImportRowException(__('enrollment.MORE_THAN', [
                //             'date_param' => 'Date Terminated Date',
                //             'date' => $date_terminated,
                //             'date_param2' => 'Member Effective Date',
                //             'start' => $member_effective_date
                //         ]), 0, null, $row);
                //     }
                // }
            }
            // validasi member expried date range date in periode date coroporate
            // $members_expire_date = date("Y-m-d", strtotime($row['member_expiry_date']));
            // validasi member expried date must less date member effective
            // $members_expire_date = date("Y-m-d", strtotime($row['member_expiry_date']));
            // $members_expire_date = date("Y-m-d", strtotime($row['member_expiry_date']));

            // if ($member_effective_date <= $corporate->currentPolicy->start && ($member_effective_date != $corporate->currentPolicy->start)) {
            //     throw new ImportRowException(__('enrollment.MORE_THAN', [
            //         'date_param' => 'Member Effective Date',
            //         'date' => $member_effective_date,
            //         'date_param2' => 'Start Period Date',
            //         'start' => $corporate->currentPolicy->start
            //     ]), 0, null, $row);
            // }

            // if ($member_effective_date >= $corporate->currentPolicy->end && ($member_effective_date != $corporate->currentPolicy->end)) {
            //     throw new ImportRowException(__('enrollment.LESS_THAN', [
            //         'date_param' => 'Member Effective Date',
            //         'date' => $member_effective_date,
            //         'date_param2' => 'End Period Date',
            //         'end' => $corporate->currentPolicy->end
            //     ]), 0, null, $row);
            // }

            // if ($member_effective_date >= $corporate->currentPolicy->end && ($member_effective_date != $corporate->currentPolicy->end)) {
            //     throw new ImportRowException(__('enrollment.LESS_THAN', [
            //         'date_param' => 'Member Effective Date',
            //         'date' => $member_effective_date,
            //         'date_param2' => 'End Period Date',
            //         'end' => $corporate->currentPolicy->end
            //     ]), 0, null, $row);
            // }
            // if ($members_expire_date <= $corporate->currentPolicy->start && ($members_expire_date != $corporate->currentPolicy->start) ) {
            //     throw new ImportRowException(__('enrollment.MORE_THAN', [
            //         'date_param' => 'Member Expired Date',
            //         'date' => $members_expire_date,
            //         'date_param2' => 'Start Period Date',
            //         'start' => $corporate->currentPolicy->start
            //     ]), 0, null, $row);
            // }

            // if ($members_expire_date >= $corporate->currentPolicy->end && ($members_expire_date != $corporate->currentPolicy->end)) {
            //     throw new ImportRowException(__('enrollment.LESS_THAN', [
            //         'date_param' => 'Member Expired Date',
            //         'date' => $members_expire_date,
            //         'date_param2' => 'END Period Date',
            //         'end' => $corporate->currentPolicy->end
            //     ]), 0, null, $row);
            // }


            // if ($members_expire_date <= $member_effective_date && ($members_expire_date != $member_effective_date)) {
            //     throw new ImportRowException(__('enrollment.MORE_THAN', [
            //         'date_param' => 'Member Expired Date',
            //         'date' => $members_expire_date,
            //         'date_param2' => 'Member Effective Date',
            //         'start' => $member_effective_date
            //     ]), 0, null, $row);
            // }


            if($corporate->code != $row['corporate_id']){
                throw new ImportRowException(__('enrollment.CORPORATE_CODE_NOT_MATCH', [
                    'corporate_id' => $row['corporate_id']
                ]), 0, null, $row);
            }

            switch ($row['record_mode']) {
                case "1": // New Member
                    $this->validateRow($row);
                    $member = Member::query()
                        ->where('member_id', $row['member_id'])
                        // ->whereHas('employeds', function ($query) use ($corporate) {
                        //     $query->where('corporate_id', $corporate->id);
                        // })
                        ->first();
                    // Validate If Exist Member
                    if ($member) {
                        $person = Person::updateOrCreate(
                            [
                                'id' => $member->person_id
                            ],
                            [
                                'name' => $row['name'] ?? null,
                                'birth_date' => $this->dateParser($row['date_of_birth']) ?? null,
                                'gender' => Helper::genderNormalization($row['sex']),
                                'language' => $row['language'] ?? null,
                                'race' => $row['race'] ?? null,
                                'phone' => $row['telephone_mobile'] ?? null
                            ]
                        );
                        $member->person_id = $person->id;
                        $member->save();
                        throw new ImportRowException(__('enrollment.MEMBER_UNIQUE', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    } else {
                        $member = new Member();
                    }

                    $memberPolicy = $member->policies()
                        ->where('policy_id', $row['policy_number'])
                        ->first();

                    if ($memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    // Validate If Plan Exist
                    // TODO validate corporate plan
                    $plans = explode(",",$row['plan_id']);
                    if (count($plans) > 0) {
                        foreach($plans as $d){
                            $plan = Plan::query()
                                        ->where('code', $d)
                                        ->where('corporate_id', $corporate->id)
                                        ->first();
                            if (!$plan) {
                                throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
                            }
                        }
                    } else {
                        $plan = Plan::query()
                            ->where('code', $row['plan_id'])
                            ->where('corporate_id', $corporate->id)
                            ->first();
                        if (!$plan) {
                            throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
                        }
                    }

                    try {
                        DB::beginTransaction();
                        $member->fill($member_data);
                        if ($member->save()) {
                            $person = Person::create([
                                'name' => $row['name'],
                                'birth_date' => $this->dateParser($row['date_of_birth']) ?? null,
                                'gender' => Helper::genderNormalization($row['sex']) ?? '-',
                                'language' => $row['language'] ?? null,
                                'race' => $row['race'] ?? null,
                                'phone' => $row['telephone_mobile'],
                            ]);

                            $member->person_id = $person->id;
                            $member->save();

                            $memberPolicy = new MemberPolicy();
                            $memberPolicy->fill([
                                'member_id' => $member->member_id,
                                'policy_id' => $row['policy_number'],
                                'start' => $this->dateParser($row['member_effective_date']),
                                'end' => $this->dateParser($row['member_expiry_date']),
                                'status' => 'active'
                            ]);

                            $memberPolicy->save();

                            if (!empty($row['division_name'])) {
                                $division_id = CorporateDivision::query()->where('code', $row['division_name'])->pluck('id')->first();

                                if (empty($division_id)) {
                                    $division = CorporateDivision::query()->updateOrCreate(['name' => $row['division_name'], 'code' => $row['division_name']], [
                                        'corporate_id' => $corporate->id,
                                        'name' => $row['division_name'],
                                        'code' => $row['division_name'],
                                    ]);

                                    $division_id = $division->id;
                                }
                            }
                            // Bisa disini penyebab data dobel
                            $member->employeds()->create([
                                'corporate_id' => $corporate->id,
                                'branch_code' => $row['branch_code'],
                                'division_id' => $division_id ?? null,
                                'nik' => $row['nik'],
                                'status' => $row['employment_status']
                            ]);
                            // Bisa disini penyebab data dobel

                            $plans = explode(",",$row['plan_id']);
                            if (count($plans) > 0) {
                                foreach($plans as $d){
                                    $plan = Plan::query()
                                                ->where('code', $d)
                                                ->where('corporate_id', $corporate->id)
                                                ->first();
                                    if (!$plan) {
                                        throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
                                    }
                                    $member->memberPlans()->create([
                                        'plan_id' => $plan->id,
                                        'status' => 'active',
                                        'start' => $this->dateParser($row['member_effective_date']),
                                        'end' => $this->dateParser($row['member_expiry_date']),
                                    ]);
                                }
                            } else {
                                $plan = Plan::query()
                                    ->where('code', $row['plan_id'])
                                    ->where('corporate_id', $corporate->id)
                                    ->first();
                                if (!$plan) {
                                    throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
                                }
                                $member->memberPlans()->create([
                                    'plan_id' => $plan->id,
                                    'status' => 'active',
                                    'start' => $this->dateParser($row['member_effective_date']),
                                    'end' => $this->dateParser($row['member_expiry_date']),
                                ]);
                            }

                        }
                        DB::commit();
                    } catch (\Exception $e) {
                        DB::rollback();
                        throw new ImportRowException($e->getMessage(), $e->getCode(), $e, $row);
                    }
                    break;
                case "2": // Member Information Update (Without Replacement Card)

                    $this->validateRow($row);
                    $member = Member::query()
                        ->where('member_id', $row['member_id'])
                        ->first();

                    // // Validate If Exist Member
                    if (!$member) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_FOUND', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }


                    $person = Person::updateOrCreate(
                        [
                            'id' => $member->person_id
                        ],
                        [
                            'name' => $row['name'] ?? null,
                            'birth_date' => $this->dateParser($row['date_of_birth']),
                            'gender' => Helper::genderPerson($row['sex']),
                            'language' => $row['language'] ?? null,
                            'race' => $row['race'] ?? null,
                            'phone' => $row['telephone_mobile']
                        ]
                    );

                    $member->person_id = $person->id;

                    $member->name = $row['name'];
                    $member->employee_status = $row['employment_status'];
                    $member->gender = Helper::genderPerson($row['sex']);
                    $member->relation_with_principal = $row['relationship_with_principal'];
                    $member->marital_status = $row['marital_status'];
                    $member->birth_date = $this->dateParser($row['date_of_birth']);

                    $member->save();
                    try {
                        DB::beginTransaction();
                        $memberPolicy = MemberPolicy::query()
                            ->where('policy_id', $row['policy_number'])
                            ->where('member_id', $row['member_id'])
                            ->with('member')
                            ->first();

                        // Pengecekan jika ada perubahan di plan
                        // $plan = Plan::query()
                        //     ->where('code', $row['plan_id'])
                        //     ->first();
                        // if ($plan){
                        //     $memberPlan = MemberPlan::query()
                        //         ->where('member_id', $member->id)
                        //         ->first();
                        //     $memberPlan->plan_id = $plan->id;
                        //     $memberPlan->save();
                        // }

                        // // Pengecekan jika ada perubahan di plan
                        // $plan = Plan::query()
                        //     ->where('code', $row['plan_id'])
                        //     ->first();
                        // if ($plan){
                        //     $memberPlan = MemberPlan::query()
                        //         ->where('member_id', $member->id)
                        //         ->first();
                        //     $memberPlan->plan_id = $plan->id;
                        //     $memberPlan->save();
                        // }

                        // Hapus Member plan terkait
                        $delete = MemberPlan::where('member_id', $member->id)->delete();
                        //Update plan

                        if (!empty($row['division_name'])) {
                            $division_id = CorporateDivision::query()->where('code', $row['division_name'])->pluck('id')->first();

                            if (empty($division_id)) {
                                $division = CorporateDivision::query()->updateOrCreate(['name' => $row['division_name'], 'code' => $row['division_name']], [
                                    'corporate_id' => $corporate->id,
                                    'name' => $row['division_name'],
                                    'code' => $row['division_name'],
                                ]);

                                $division_id = $division->id;
                            }

                            // Bisa disini penyebab data dobel
                            $member->employeds()->updateOrCreate([
                                'member_id' =>  $member->id
                            ],[
                                'corporate_id' => $corporate->id,
                                'branch_code' => $row['branch_code'],
                                'division_id' => $division_id ?? null,
                                'nik' => $row['nik'],
                                'status' => $row['employment_status']
                            ]);
                            // Bisa disini penyebab data dobel
                        }


                        $plans = explode(",",$row['plan_id']);
                        if (count($plans) > 0) {
                            foreach($plans as $d){
                                $plan = Plan::query()
                                            ->where('code', $d)
                                            ->where('corporate_id', $corporate->id)
                                            ->first();
                                if (!$plan) {
                                    throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
                                }
                                $member->memberPlans()->updateOrCreate([
                                    'member_id' => $member->id,
                                    'plan_id' => $plan->id,
                                ],
                                [
                                    'plan_id' => $plan->id,
                                    'status' => 'active',
                                    'start' => $this->dateParser($row['member_effective_date']),
                                    'end' => $this->dateParser($row['member_expiry_date']),
                                ]);
                            }
                        } else {
                            $plan = Plan::query()
                                ->where('code', $row['plan_id'])
                                ->where('corporate_id', $corporate->id)
                                ->first();
                            if (!$plan) {
                                throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
                            }
                            $member->memberPlans()->updateOrCreate([
                                'member_id' => $member->id,
                                'plan_id' => $plan->id,
                            ],
                            [
                                'plan_id' => $plan->id,
                                'status' => 'active',
                                'start' => $this->dateParser($row['member_effective_date']),
                                'end' => $this->dateParser($row['member_expiry_date']),
                            ]);
                        }
                        // end update plan

                        // Update jika ada perubahaan di ASO maka akan teriflek ke LMS juga
                        $userInsuranceLms = UserInsurance::query()
                            ->where('sNoPolis', $row['member_id'])
                            ->first();
                        if ($userInsuranceLms){
                            $userInsuranceLms->sNamaPeserta = $row['name'];
                            $userInsuranceLms->dStartDate = $row['member_effective_date'];
                            $userInsuranceLms->dExpireDate = $row['member_expiry_date'];
                            $nIDUser = $userInsuranceLms->nIDUser;

                            UserInsurance::updateOrCreate(
                                ['nIDUser' => $nIDUser],
                                [
                                    'sNamaPeserta' => $row['name'],
                                    'dStartDate'   => $row['member_effective_date'],
                                    'dExpireDate' =>  $row['member_expiry_date'],
                                    'dTanggalLahir' =>  $row['date_of_birth'] ? $this->dateParser($row['date_of_birth']) : null,
                                    // 'nNoKTP' => $row['nric'] ?? ,
                                ]
                            );
                            /* Lihat ID Marital status di table tm_status_pernikahan Linksehat */
                            if ($row['relationship_with_principal'] == 'H'){
                                $sMartialStatus= 6;
                                $nIDHubunganKeluarga = 3;
                            } else if ($row['relationship_with_principal'] == 'W'){
                                $sMartialStatus = 7;
                                $nIDHubunganKeluarga = 4;
                            } else if ($row['relationship_with_principal'] == 'S'){
                                $sMartialStatus = 4;
                                $nIDHubunganKeluarga = 5;
                            } else if ($row['relationship_with_principal'] == 'D'){
                                $sMartialStatus = 5;
                                $nIDHubunganKeluarga = 5;
                            } else {
                                $sMartialStatus = 0;
                                $nIDHubunganKeluarga = 0;
                            }


                            if($row['sex'] == 'M'){
                                $nIDJenisKelamin = 1;
                            } else {
                                $nIDJenisKelamin = 2;
                            };
                            // $ip_address = $CI->_prepare_ip($CI->input->ip_address());
                            $name = explode(" ", $row['name']);
                            // First name
                            $first_name = isset($name[0]) ? $name[0] : '';
                            // Middle name
                            $middle_name = isset($name[1]) ? $name[1] : '';
                            // Last name
                            $last_name = '';
                            if (count($name) > 2) {
                                $last_name = implode(" ", array_slice($name, 2));
                            }
                            $userLms = User::updateOrCreate(
                                [
                                    'nID' => $nIDUser // Kondisi untuk mencari data dengan 'nID' yang sesuai dengan $nIDUser
                                ],
                                [
                                    'sFirstName' => $first_name,
                                    'sLastName' =>  $middle_name . ' ' .$last_name, // Ubah ini dengan variabel yang sesuai dengan nama belakang (last name)
                                    'sPhone' => $row['telephone_mobile'],
                                    'sEmail' => str_replace(' ', '', $row['email']),
                                    'nIDHubunganKeluarga' => $nIDHubunganKeluarga !== 0 ? $nIDHubunganKeluarga : null,
                                    'dUpdateOn' => date('Y-m-d H:i:s'),
                                ]
                            );

                            $userLmsDetail = UserDetail::updateOrCreate(
                                [
                                    'nIDUser' => $nIDUser
                                ],
                                [
                                    'nIDUser' => $nIDUser,
                                    // 'dTanggalLahir' => $row['date_of_birth'],
                                    'dTanggalLahir' => $this->dateParser($row['date_of_birth']),
                                    'dCreateOn' => date('Y-m-d H:i:s'),
                                    'sMartialStatus' => $sMartialStatus != 0 ? $sMartialStatus : null,
                                    'nIDJenisKelamin' => $nIDJenisKelamin,
                                    'sCreateBy' => $nIDUser,
                                    'sKTP' => $row['nric'] ?? null,
                                ]
                            );

                        }

                        if (!$memberPolicy) {
                            throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                                'member_id' => $row['member_id'],
                                'policy_id' => $row['policy_number']
                            ]), 0, null, $row);
                        }

                        if ($memberPolicy->status != 'active') {
                            throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                                'member_id' => $row['member_id'],
                                'policy_id' => $row['policy_number']
                            ]), 0, null, $row);
                        }

                        $memberPolicy->member->fill($member_data);
                        if (!$memberPolicy->member->isDirty()) {
                            throw new ImportRowException(__('enrollment.MEMBER_NO_CHANGE'), 0, null, $row);
                        }

                        $memberPolicy->member->save();
                        $member->save();
                        // update informasi person
                        $person = Person::query()
                            ->where('id', $member->person_id)
                            ->first();
                        $person->fill($member_data);
                        $person->save();

                        DB::commit();
                    } catch (\Exception $e) {
                        DB::rollback();
                        throw new ImportRowException($e->getMessage(), $e->getCode(), $e, $row);
                    }

                    break;
                case "3": // Member Deletion
                    $member = Member::query()
                        ->where('member_id', $row['member_id'])
                        ->first();

                    // Validate If Exist Member
                    if (!$member) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_FOUND', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }
                    $this->validateRow($row);

                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $row['policy_number'])
                        ->where('member_id', $row['member_id'])
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($memberPolicy->status != 'active') {
                        throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    $member = $memberPolicy->member;
                    $member->active = false;

                    $member->save();
                    break;
                case "5": // Member Renewal Policy (without card)
                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $row['policy_number'])
                        ->where('member_id', $row['member_id'])
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($memberPolicy->status != 'active') {
                        throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }


                    if ($this->dateParser($row['member_effective_date']) > $this->dateParser($row['member_expiry_date'])) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
                    }

                    if (
                        Carbon::parse($memberPolicy->end) > $this->dateParser($row['member_expiry_date'])
                        || $memberPolicy->end > $this->dateParser($row['member_expiry_date'])
                    ) {
                        throw new ImportRowException(__('enrollment.MEMBER_RENEWAL_STILL_ACTIVE'), 0, null, $row);
                    }

                    $memberPolicy->fill([
                        'start' => $row['member_expiry_date'],
                        'end' => $row['member_expiry_date']
                    ]);

                    if (!$memberPolicy->isDirty()) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
                    }

                    $memberPolicy->save();

                    break;
                case "6": // Member Renewal Policy (with card)
                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $row['policy_number'])
                        ->where('member_id', $row['member_id'])
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($memberPolicy->status != 'active') {
                        throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($this->dateParser($row['member_effective_date']) > $this->dateParser($row['member_expiry_date'])) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
                    }

                    if (
                        Carbon::parse($memberPolicy->end) > $this->dateParser($row['member_expiry_date'])
                        || $memberPolicy->end > $this->dateParser($row['member_expiry_date'])
                    ) {
                        throw new ImportRowException(__('enrollment.MEMBER_RENEWAL_STILL_ACTIVE'), 0, null, $row);
                    }

                    $memberPolicy->fill([
                        'start' => $row['member_expiry_date'],
                        'end' => $row['member_expiry_date']
                    ]);

                    if (!$memberPolicy->isDirty()) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
                    }

                    $memberPolicy->save();

                    break;
                case "7": // Requesting to Change the Unique Data of the Member

                    // if (empty($row["option_mode"])) {
                    //     throw new ImportRowException(__('enrollment.OPTION_MODE_INVALID_FORMAT', [
                    //         'member_id' => $row['member_id'],
                    //         'policy_id' => $row['policy_number']
                    //     ]), 0, null, $row);
                    // }

                    // // Read Option Mode
                    // $option_mode = explode('!', $row['option_mode']);
                    // $corp_code = $option_mode[1] ?? null;
                    // $policy_number = $option_mode[2] ?? null;
                    // $member_id = $option_mode[3] ?? null;
                    // // Validate
                    // if ( !in_array($option_mode[0], ['P', 'D']) || empty($corp_code) || empty($policy_number) || empty($member_id) ) {
                    //     throw new ImportRowException(__('enrollment.OPTION_MODE_INVALID_FORMAT', [
                    //         'member_id' => $row['member_id'],
                    //         'policy_id' => $row['policy_number']
                    //     ]), 0, null, $row);
                    // }
                    $record_type = explode('>', $row['record_type']);
                    $record_type_old = $record_type[0] ?? null;
                    $record_type_new = $record_type[1] ?? null;
                    $corp_code = explode('>', $row['corporate_id']);
                    $corp_code_old = $corp_code[0] ?? null;
                    $corp_code_new = $corp_code[1] ?? null;
                    $policy_number = explode('>', $row['policy_number']);
                    $policy_number_old = $policy_number[0] ?? null;
                    $policy_number_new = $policy_number[1] ?? null;
                    $member_id = explode('>', $row['member_id']);
                    $member_id_old = $member_id[0] ?? null;
                    $member_id_new = $member_id[1] ?? null;


                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $policy_number_old)
                        ->where('member_id', $member_id_old)
                        ->with('member')
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $member_id_old,
                            'policy_id' => $policy_number_old
                        ]), 0, null, $row);
                    }

                    if ($memberPolicy->status != 'active') {
                        throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                            'member_id' => $member_id_old,
                            'policy_id' => $policy_number_old
                        ]), 0, null, $row);
                    }

                    if ($record_type_new == 'P') {
                        if (!empty($row['principal_id'])) {
                            throw new ImportRowException(__('enrollment.PRINCIPAL_ID_NOT_REQUIRED'), 0, null, $row);
                        }

                        if (empty($row['corporate_id'])) {
                            throw new ImportRowException(__('enrollment.CORPORATE_ID_REQUIRED'), 0, null, $row);
                        }
                    }

                    if ($record_type_new == 'D') {
                        if (empty($row['principal_id'])) {
                            throw new ImportRowException(__('enrollment.PRINCIPAL_ID_REQUIRED'), 0, null, $row);
                        }
                    }

                    // if (
                    //     $record_type_new == 'P' &&
                    //     $memberPolicy->member->corporate->code == $row["corporate_id"] &&
                    //     $memberPolicy->policy_id == $row['policy_number'] &&
                    //     $memberPolicy->member_id == $row['member_id'] &&
                    //     $memberPolicy->member->record_type == $row['record_type']
                    // ) {
                    //     throw new ImportRowException(__('enrollment.UNIQUE_CHANGE_PRINCIPAL_INVALID', [
                    //         'member_id' => $row['member_id'],
                    //         'policy_id' => $row['policy_number']
                    //     ]), 0, null, $row);
                    // }

                    // if (
                    //     $record_type_new == 'D' &&
                    //     $memberPolicy->member->corporate->code == $row["corporate_id"] &&
                    //     $memberPolicy->policy_id == $row['policy_number'] &&
                    //     $memberPolicy->member->record_type == $row['record_type'] &&
                    //     $memberPolicy->member->payor_id == $row['payor_id']
                    // ) {
                    //     throw new ImportRowException(__('enrollment.UNIQUE_CHANGE_DEPENDANT_INVALID', [
                    //         'member_id' => $row['member_id'],
                    //         'policy_id' => $row['policy_number']
                    //     ]), 0, null, $row);
                    // }

                    try {
                        DB::beginTransaction();

                        if (!empty($record_type_new)) {
                            $member = $memberPolicy->member;
                            $member->record_type = $record_type_new;
                            $member->principal_id = $row['principal_id'];

                            $member->save();
                        }

                        if (!empty($corp_code_new)) {
                            $oldCorporate = Corporate::where('code', $corp_code_old)->first();
                            $newCorporate = Corporate::where('code', $corp_code_new)->first();

                            if (!$newCorporate) {
                                throw new ImportRowException(__('enrollment.CORPORATE_NOT_FOUND'), 0, null, $row);
                            }
                            $corporateEmployee = CorporateEmployee::where('corporate_id', $oldCorporate->id)
                                ->where('member_id', $memberPolicy->member->id)
                                ->first();
                            $newCorporateEmployee = CorporateEmployee::updateOrCreate(
                                [
                                    'corporate_id' => $oldCorporate->id,
                                    'member_id' => $memberPolicy->member->id
                                ],
                                [
                                    'corporate_id' => $newCorporate->id,
                                    'member_id' => $memberPolicy->member->id
                                ]
                            );
                        }

                        if (!empty($policy_number_new)) {
                            $memberPolicy->policy_id = $policy_number_new;
                            $memberPolicy->save();
                        }

                        if (!empty($member_id_new)) {
                            $memberPolicy->member_id = $member_id_new;
                            $memberPolicy->save();

                            $member = $memberPolicy->member;
                            $member->member_id = $member_id_new;
                            $member->save();
                        }

                        DB::commit();
                    } catch (\Exception $e) {
                        DB::rollback();
                        throw new ImportRowException($e->getMessage(), $e->getCode(), $e, $row);
                    }

                    break;
                case "9": // Member Reactivation and Personal information update (Without replacement Card)
                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $row['policy_number'])
                        ->where('member_id', $row['member_id'])
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($this->dateParser($row['member_effective_date']) < now() || $this->dateParser($row['member_expiry_date']) < now()) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_MUST_BE_AFTER_TODAY'), 0, null, $row);
                    }

                    if ($this->dateParser($row['member_effective_date']) > $this->dateParser($row['member_expiry_date'])) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
                    }

                    $memberPolicy->fill([
                        'start' => $row['member_effective_date'],
                        'end' => $row['member_expiry_date']
                    ]);

                    $memberPolicy->save();
                    break;
                case "13": // Advance Renewal with OLD Card No. (NO PRINT)
                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $row['policy_number'])
                        ->where('member_id', $row['member_id'])
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($memberPolicy->status != 'active') {
                        throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    $newMemberPolicy = new MemberPolicy();
                    $newMemberPolicy->fill([
                        'member_id' => $row['member_id'],
                        'policy_id' => $row['policy_number'],
                        'start' => $this->dateParser($row['member_effective_date']),
                        'end' => $this->dateParser($row['member_expiry_date']),
                        'status' => 'active'
                    ]);
                    $newMemberPolicy->save();
                    break;




                    // THESE MODES BELOW ARE DISABLED
                case "4": // Member Update Start and End Date
                    throw new ImportRowException(__('MODE 4 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
                    break;
                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $row['policy_number'])
                        ->where('member_id', $row['member_id'])
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($memberPolicy->status != 'active') {
                        throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    $memberPolicy->fill([
                        'start' => $row['start_date'],
                        'end' => $row['end_date']
                    ]);

                    if (!$memberPolicy->isDirty()) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
                    }

                    if ($this->dateParser($row['member_effective_date']) > $this->dateParser($row['member_expiry_date'])) {
                        throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
                    }

                    $memberPolicy->save();

                    break;
                case "8": // Member Information Update (With Replacement Card)
                    throw new ImportRowException(__('MODE 8 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
                    break;
                    // case "10": // No Information Available

                    //     break;
                case "11": // Advance Renewal with OLD Card No. (PRINT)

                    throw new ImportRowException(__('MODE 11 NOT HANDLED PROPERLY, TRY TO USE MODE 13'), 0, null, $row);
                    break;
                case "12": // Advance Renewal iwh NEW Card No. (PRINT)

                    throw new ImportRowException(__('MODE 12 NOT HANDLED PROPERLY, TRY TO USE MODE 13'), 0, null, $row);
                    break;
                    // case "14": // No Information Available

                    //     break;
                case "15": // Lost Card / Change Card with new card number (Print) (Rarely Used)

                    throw new ImportRowException(__('MODE 15 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
                    break;
                case "16": // Endorsement Plan OLD Card No. (NO PRINT)
                    throw new ImportRowException(__('MODE 16 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
                    break;
                    $plan = CorporatePlan::query()
                        ->where('corporate_id', $corporate->id)
                        ->where('code', $row['plan_id'])
                        ->where('active', true)
                        ->first();
                    if (!$plan) {
                        throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
                    }

                    $memberPolicy = MemberPolicy::query()
                        ->where('policy_id', $row['policy_number'])
                        ->where('member_id', $row['member_id'])
                        ->first();

                    if (!$memberPolicy) {
                        throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                    if ($memberPolicy->status != 'active') {
                        throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
                            'member_id' => $row['member_id'],
                            'policy_id' => $row['policy_number']
                        ]), 0, null, $row);
                    }

                case "17": // Endorsement Plan OLD Card No. (PRINT)

                    throw new ImportRowException(__('MODE 17 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
                    break;
                default:
                    throw new ImportRowException(__("enrollment.MODE_UNAVAILABLE"), 0, null, $row);
            }
        } catch (\Exception $e) {
            // dd($row, $e->getMessage());
            throw new ImportRowException($e->getMessage(), (int) $e->getCode(), $e, $row);
        }

        // Should be success then returning new member data with extra ingestion code & status
        $row['ingestion_code'] = "200";
        $row['ingestion_status'] = "SUCCESS";

        return $row;
    }


    // This returning row with format or order following $result_doc_headers
    public function makeResultRowWithResultFormat($row_data)
    {
        $cells = [];
        foreach ($this->result_doc_headers as $header) {
            $value = $row_data[$this->doc_headers_to_field_map[$header]] ?? null;
            if (is_string($value)) {
                $cells[] = WriterEntityFactory::createCell($value);
            }
            else if ($value instanceof DateTime) {
                $cells[] = WriterEntityFactory::createCell(Carbon::parse($value)->format('Ymd'));
            }
            else {
                $cells[] = WriterEntityFactory::createCell($value);
            }
        }

        return $cells;
    }

    // This validation for range date in period corporate // validasi untuk range tanggal dalam period corporate yang ditentukan
    public function validateRangePeriode($dates){
        $date = date("Y-m-d", strtotime($dates));
        if (!isset($corporate->currentPolicy) || $corporate->currentPolicy->start <= $date) {

        }
        if (!isset($corporate->currentPolicy) || $corporate->currentPolicy->end >= $date) {
           dd($corporate->currentPolicy->end, $dates);
        }
    }

    // This returning row with format or order as it is
    public function makeResultRow($row_data)
    {
        $cells = [];
        foreach ($row_data as $cellValue) {
            $cells[] = WriterEntityFactory::createCell($cellValue);
        }

        return $cells;
    }
}
