<?php

namespace App\Services;

use App\Events\ClaimApproved;
use App\Events\ClaimRequested;
use App\Models\Claim;
use App\Models\ClaimRequest;
use App\Models\Organization;
use App\Helpers\Helper;
use App\Models\Icd;
use App\Models\Member;
use Carbon\Carbon;
use App\Exceptions\ImportRowException;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;


use DB;
use Str;

class ClaimRequestService{

    public static function storeClaimRequest($row = null, $code, $member, $paymentType, $serviceCode, $requestLogID = null, $submissionDate = null, $status = 'requested', $organization_code = null)
    {
        // try {
            $organization = False;
            if($organization_code){
                $organization = Organization::where('code', $organization_code)->first();
                if (!$organization){
                    throw new ImportRowException(__('Code Provider Tidak ditemukan', [
                        'attribute' => 'provider_code',
                        'code' => $row['provider_code']
                    ]), 403, null, $row);
                }
            };

            DB::beginTransaction();

            $claimRequestData = [
                'code' => $code,
                'request_log_id' => $requestLogID ?? 0,
                'member_id' => $member->id,
                'submission_date' => $submissionDate ?? now(),
                'status' => $status,
                'payment_type' => $paymentType,
                'service_code' => $serviceCode,
                'policy_id' => $member->currentPolicy->id ?? null,
                'organization_id' => $organization ? $organization->id : 0,
            ];

            $claimRequest = ClaimRequest::create($claimRequestData);

            DB::commit();

            return $claimRequest;
        // } catch (\Exception $error) {
        //     DB::rollBack();

        //     throw new \Exception($error);
        // }
    }



    public static function storeClaimManagement($row, $member, $claim_request_id){
        try {
            $organization = 0;
            if($row['provider_code']){
                $organization = Organization::where('code', $row['provider_code'])->first();
                if (!$organization){
                    throw new ImportRowException(__('Provider Tidak ditemukan'), 0, null, $row);
                }
            };
            if(!$member){
                throw new ImportRowException(__('Member Tidak ditemukan'), 0, null, $row);
            };
            DB::beginTransaction();
            $data = [
                'member_id' => $member->id,
                'currency' => 'IDR',
                'plan_id' => $member->currentPlan->id,
                'total_claim' => $row['tot_amt_insurred'] ? $row['tot_amt_insurred'] : 0,
                'benefit_code' => $row['benefit_code'] ?  $row['benefit_code'] : '-',
                'benefit_desc' => $row['benefit_desc'] ?  $row['benefit_desc'] : '-',
                'amount_incurred' => $row['tot_amt_insurred'] ?  $row['tot_amt_insurred'] : 0,
                'amount_approved' => $row['tot_amt_approved'] ? $row['tot_amt_approved'] : 0,
                'amount_not_approved' => $row['tot_amt_not_approved'] ? $row['tot_amt_not_approved'] :0,
                'excess_paid' => $row['tot_excess_paid'] ? $row['tot_excess_paid'] : 0,
                'claim_request_id' => $claim_request_id,
                'organization_id' => $organization ? $organization->id : NULL,
                'status' => 'requested'
            ];


            $claimManagement = Claim::create($data);

            // update client id di claim request
            ClaimRequest::where('id', $claim_request_id)->update([
                'claim_id' => $claimManagement->id,
            ]);

            DB::commit();
            return $claimManagement;


        } catch (\Exception $error) {
            DB::rollBack();

            throw new \Exception($error);
        }
    }

    public static function updateClaimRequest($organization_id, $claim_request_id){
        try {
            $data = [
                'organization_id' => $organization_id
            ];
            DB::commit();
            $update = ClaimRequest::where('id', $claim_request_id)->update($data);
            return ClaimRequest::find($claim_request_id);

        } catch (\Exception $error) {
            DB::rollBack();

            throw new \Exception($error);
        }
    }

    protected function validatePlanRow($row)
    {
        if (empty($row['member_id'])) {
            throw new ImportRowException(__('Member ID Required'), 0, null, $row);
        }
    }

    public function handleClaimRequestRow($row)
    {
        try {
            $member = Member::where('member_id', $row['member_id'])->with(['currentPlan'])->first();
            if(!$member){
                throw new ImportRowException(__('Member Tidak ditemukan'), 0, null, $row);
            };
            $code = $row['client_claim_id'];
            $organization_id = $row['provider_code'];
            $submissionDate = Helper::formatDateDB($row['admission_date']);
            $paymentType = $row['claim_type'];
            $status = $row['status'];
            $serviceCode = $row['coverage_type'];

            $newClaimRequest = $this->storeClaimRequest(
                row: $row,
                code: $code,
                member: $member,
                paymentType: $paymentType,
                serviceCode: $serviceCode,
                submissionDate: $submissionDate,
                status: $status,
                organization_code: $organization_id
            );

            $newlyCreatedID = $newClaimRequest->id;

            $newClaimManangement = $this->storeClaimManagement($row, $member, $newlyCreatedID);
            ClaimRequested::dispatch($newClaimRequest);
            // Log History
            $newClaimRequest->histories()->create([
                'title' => 'New Claim Requested',
                'description' => "Claim Requested for Member : {$member->member_id} - ({$member->full_name})",
                'type' => 'info',
                'system_origin' => 'import-internal-aso'
            ]);

            $claim_request_data = $row;
            $this->validatePlanRow($claim_request_data);

            return $newClaimRequest;
        } catch (\Exception $e) {
            throw $e;
        }
    }

}
