<?php

namespace App\Imports;

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use App\Services\OptumPreServiceEligibilityClient;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Imports\HeadingRowFormatter;
use PhpOffice\PhpSpreadsheet\Shared\Date;

class PreServiceEligibilityBatchRowsImport implements ToCollection, WithChunkReading, WithHeadingRow
{
    private int $importBatchId;

    public function __construct(int $importBatchId)
    {
        // Keep Excel header names as-is (e.g. memberId), so you can do $row['memberId']
        HeadingRowFormatter::default('none');
        $this->importBatchId = $importBatchId;
    }

    public function collection(Collection $rows)
    {
        if ($rows->isEmpty()) {
            return;
        }

        /** @var OptumPreServiceEligibilityClient $optum */
        $optum = app(OptumPreServiceEligibilityClient::class);
        $environment = (string) config('optum.environment', 'sandbox');

        $now = now();
        $inserts = [];

        foreach ($rows as $row) {
            $rowArray = is_array($row) ? $row : $row->toArray();
            $inputFields = $this->buildInputFields($rowArray);
            $providerTaxId = (string) ($inputFields['providerTaxId'] ?? $rowArray['providerTaxId'] ?? $rowArray['provider_tax_id'] ?? '9999999999999999');
            Log::info('TAX ID', ['inputFields' => $inputFields,'providerTaxId'=>$providerTaxId]);
            unset($inputFields['providerTaxId'], $inputFields['provider_tax_id']);

            $result = $optum->checkEligibility($inputFields, $providerTaxId, $environment);

            if($result['ok'] ){
               $rowData = $this->makingRowData($result['body']);
            }else{
                $rowData =@json_encode($result['message']);
            }

            $inserts[] = [
                'import_batch_id' => $this->importBatchId,
                'request_data' => json_encode($result['request'] ?? []),
                'response_data' => json_encode([
                    'ok' => $result['ok'] ?? false,
                    'headers' => $result['headers'] ?? [],
                    'body' => $result['body'] ?? null,
                    'environment' => $environment,
                ]),
                'row_data' => $rowData,//json_encode($rowArray),
                'created_at' => $now,
                'updated_at' => $now,
            ];
        }

        DB::table('import_batch_rows')->insert($inserts);
    }

    public function chunkSize(): int
    {
        return 1000;
    }

    public function headingRow(): int
    {
        return 1;
    }

    private function buildInputFields(array $data): array
    {
        $hasStringKeys = false;
        foreach (array_keys($data) as $k) {
            if (is_string($k)) {
                $hasStringKeys = true;
                break;
            }
        }

        if ($hasStringKeys) {

            $serviceLevelCodes = self::serviceLevelCode($data['serviceLevelCodes'] ?? $data['service_level_codes'] ?? 'MH');
            $input = [
                'serviceLevelCodes' => $serviceLevelCodes,
                'payerId' => isset($data['payerId']) ? (string)$data['payerId'] : ($data['payer_id'] ?? null),
                'memberId' => isset($data['memberId']) ? (string)$data['memberId'] : ($data['member_id'] ?? null),
                'dateOfBirth' => $this->formatExcelDate($data['dateOfBirth'] ?? $data['date_of_birth'] ?? null),
                'serviceStartDate' => $this->formatExcelDate($data['serviceStartDate'] ?? $data['service_start_date'] ?? null),
                'providerLastName' => $data['providerLastName'] ?? $data['provider_last_name'] ?? null,
            ];

            return array_filter($input, function ($v) {
                return !is_null($v) && $v !== '';
            });
        }

        /*$input = [
            'serviceLevelCodes' => $data[0] ?? '001',
            'payerId' => $data[1] ?? null,
            'memberId' => $data[2] ?? null,
            'firstName' => $data[3] ?? null,
            'lastName' => $data[4] ?? null,
            'groupNumber' => $data[5] ?? null,
            'dateOfBirth' => $data[6] ?? null,
            'serviceStartDate' => $data[7] ?? null,
            'serviceEndDate' => $data[8] ?? null,
            'trnId' => $data[9] ?? null,
            'providerLastName' => $data[10] ?? null,
            'providerNPI' => $data[11] ?? null,
            'planStartDate' => $data[12] ?? null,
            'planEndDate' => $data[13] ?? null,
            'familyIndicator' => $data[14] ?? null,
            'providerTaxId' => $data[15] ?? null,
        ];

        return array_filter($input, function ($v) {
            return !is_null($v) && $v !== '';
        });*/
    }

    function formatExcelDate($value)
    {
        if (empty($value)) {
            return null;
        }

        if (is_numeric($value)) {
            return Date::excelToDateTimeObject($value)->format('Y-m-d');
        }

        return date('Y-m-d', strtotime($value));
    }


    private static function makingRowData($responseData){
        $eligibility    = $responseData['data']['checkEligibility']['eligibility'][0] ?? [];
        $member         = $eligibility['eligibilityInfo']['member'] ?? [];
        $insurance      = $eligibility['eligibilityInfo']['insuranceInfo'] ?? [];
        $pcp            = $eligibility['primaryCarePhysician'] ?? [];
        $patient        = trim(($member['firstName'] ?? '') . ' ' . ($member['lastName'] ?? ''));
        $providerName   = $_POST['providerLastName'] ?? '';
        $pcpName        = trim(($pcp['firstName'] ?? '') . ' ' . ($pcp['lastName'] ?? ''));
        /*
        |--------------------------------------------------------------------------
        | BUILD FINAL COLUMN-WISE DATA
        |--------------------------------------------------------------------------
        */
        $headers = [
            "Patient","Provider Profile","Carrier","Member ID","Date Verified",
            "Date of Service","Coverage Status","Network Status",
            "Doctor Can see the Patient?","Plan Type","Service","Copay ($)","Coins (%)",
            "Ded Total Individual","Ded Total Family",
            "Ded Accumulate Individual","Ded Accumulate Family",
            "PCP","Referral","Auth","Effective date","Termination Date","Service Level Type"
        ];

        $finalData = [];

        // Initialize all keys
        foreach ($headers as $header) {
            $finalData[$header] = [];
        }

        /*
        |--------------------------------------------------------------------------
        | LOOP DATA
        |--------------------------------------------------------------------------
        */
        foreach ($eligibility['serviceLevels'] ?? [] as $level) {
            foreach (['family', 'individual'] as $type) {
                $serviceLevelType = $type;
                foreach ($level[$type] ?? [] as $network) {
                    $networkStatus = $network['networkStatus'] ?? '';
                    foreach ($network['services'] ?? [] as $service) {
                        $serviceType = $service['service'] ?? '';
                        $msg = $service['message'] ?? [];
                        // Copays
                        $copays = [];
                        foreach ($msg['coPay']['subMessages'] ?? [] as $cp) {
                            if (!empty($cp['copay'])) {
                                $copays[] = $cp['copay'];
                            }
                        }

                        // Coins
                        $coins = $msg['coInsurance']['messages'] ?? [];

                        // Deductible
                        $deductible = $msg['deductible']['messages'][0] ?? '';

                        // YTD
                        $ytd = $service['metYearToDateAmount'] ?? '';

                        // Build row
                        $row = self::buildRow(
                            $patient,
                            $providerName,
                            $insurance,
                            $member,
                            $networkStatus,
                            array_unique($copays),
                            array_unique($coins),
                            $deductible,
                            $ytd,
                            $pcpName,
                            $serviceType,
                            $serviceLevelType
                        );

                        // Convert row → column-wise structure
                        foreach ($headers as $header) {
                            $value = $row[$header] ?? '';
                            $finalData[$header][] = [$value]; // nested array as required
                        }
                    }
                }
            }
        }

        return json_encode($finalData, JSON_UNESCAPED_UNICODE);
    }


    /*
    |--------------------------------------------------------------------------
    | BUILD ROW (ASSOCIATIVE ARRAY)
    |--------------------------------------------------------------------------
    */
    private static function buildRow($patient, $providerName, $insurance, $member, $networkStatus, $copays, $coins, $deductible, $ytd, $pcpName, $serviceType, $serviceLevelType) {
        return [
            "Patient" => $patient,
            "Provider Profile" => $providerName,
            "Carrier" => $insurance['planTypeDescription'] ?? '',
            "Member ID" => $member['memberId'] ?? '',
            "Date Verified" => date('Y-m-d'),
            "Date of Service" => '',
            "Coverage Status" => $insurance['policyStatus'] ?? '',
            "Network Status" => $networkStatus,
            "Doctor Can see the Patient?" => "N/A",
            "Plan Type" => $insurance['coverageType'] ?? '',
            "Service" => $serviceType,
            "Copay ($)" => implode(', ', $copays),
            "Coins (%)" => implode(', ', $coins),
            "Ded Total Individual" => $deductible,
            "Ded Total Family" => "",
            "Ded Accumulate Individual" => $ytd,
            "Ded Accumulate Family" => "",
            "PCP" => $pcpName,
            "Referral" => "N/A",
            "Auth" => "N/A",
            "Effective date" => $insurance['planStartDate'] ?? '',
            "Termination Date" => $insurance['planEndDate'] ?? '',
            "Service Level Type" => $serviceLevelType
        ];
    }

    private static function serviceLevelCode($serviceLevelCodesRaw){
        if (is_string($serviceLevelCodesRaw)) {
            // Try JSON decode first (in case format is ["MH","BH"])
            $decoded = json_decode($serviceLevelCodesRaw, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                $serviceLevelCodes = $decoded;
            } else {
                $serviceLevelCodes = array_map('trim', explode(',', $serviceLevelCodesRaw));
            }

        } else {
            $serviceLevelCodes = (array) $serviceLevelCodesRaw;
        }

        $serviceLevelCodes = array_filter($serviceLevelCodes);
        return $serviceLevelCodes;
    }
}

