<?php

namespace Modules\Internal\Http\Controllers\Api;

use App\Helpers\Helper;
use App\Models\Benefit;
use App\Models\Claim;
use App\Models\Icd;
use App\Models\Member;
use App\Models\Organization;
use App\Models\ClaimHistoryCare;
use App\Models\DiagnosisSecondaryClaimHistoryCare;
use App\Services\ClaimService;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\HospitalPortal\Helpers\ApiResponse;
use Illuminate\Support\Facades\Validator;
use Modules\Internal\Transformers\ClaimShowResource;
use Modules\Internal\Transformers\ClaimEditResource;
use Modules\Internal\Transformers\ClaimHistoryCareResource;
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\View;

use PDF;

class ClaimController extends Controller
{
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index(Request $request)
    {
        // $serviceCode = 'IP';
        $claims = Claim::with([
            'member',
            'member.currentCorporate',
            'member.currentCorporate.currentPolicy',
            // 'member.currentPlan' => function($memberPlan) use ($serviceCode) {
            //     $memberPlan->where('plans.service_code', $serviceCode);
            // },
            'member.currentPlan' => function($memberPlan) {
                $memberPlan->join('claim_requests', 'claim_requests.service_code', '=', 'plans.service_code');
            },
            'diagnoses' => function ($diagnosis) {
                $diagnosis->where('type', 'primary');
            },
            'diagnoses.icd',
            'benefit',
            'claimRequest',
            'claimRequest.service',
        ])
        ->when($request->search, function ($q, $search) {
            $q->where(function ($subQuery) use ($search) {
                $subQuery->whereHas('claimRequest', function ($claimRequest) use ($search) {
                    $claimRequest->where('code', 'LIKE', "%" . $search . "%");
                })
                ->orWhereHas('member', function ($member) use ($search) {
                    $member->where('name', 'LIKE', "%" . $search . "%");
                });
            });
        })
        ->where('status', '!=', 'requested') // Penjagaan agar approve baru masuk ke claim management
        ->latest()
        ->paginate(10);


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

    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create()
    {
        return view('internal::create');
    }

    /**
     * Store a newly created resource in storage.
     * @param Request $request
     * @return Renderable
     */
    public function store(Request $request)
    {
        $request->validate([
            'diagnosis_id' => 'required',
            'member_id' => 'required',
            'total_claim' => 'required',
            'benefit_id' => 'required'
        ]);

        // return response()->json($request->toArray());

        $member = Member::find($request->member_id);
        $benefit = Benefit::find($request->benefit_id);
        $diagnosis = Icd::find($request->diagnosis_id);

        // Check Eligibility
        $validation = ClaimService::checkMemberEligibility($member, $benefit, $diagnosis, $request->total_claim);

        // Store Claim
        if ($validation['isEligible']) {
            $claim = ClaimService::storeClaim($member, $diagnosis, $request->total_claim, $benefit, 'requested');
        } else {
            return response()->json([
                'data' => $validation,
                'message' => $validation['errors'][0]['message']
            ], 403);
        }

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

    /**
     * Show the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function show($id)
    {
        $claim = Claim::query()
                ->with([
                    'member',
                    // 'member.currentPlan',
                    // 'member.currentPlan.benefits',
                    'member.currentCorporate',
                    // 'member.currentPolicy',
                    // // 'diagnosis',
                    // 'diagnoses',
                    // 'diagnoses.icd',
                    // 'benefit',
                    // 'files',
                    // 'claimRequest',
                    // 'claimRequest.files',
                    // 'items',
                    // 'items.claim_itemable',
                    // 'encounters',
                    // 'encounters.doctors',
                    // 'encounters.primaryDiagnoses',
                    // 'encounters.primaryDiagnoses.diagnosis',
                    // 'encounters.healthcare',
                    'historyHospitalCare',
                    'historyHospitalCare.person',
                    'historyHospitalCare.practitioner',
                    'historyHospitalCare.organization',
                    'historyHospitalCare.icd',
                    'historyHospitalCare.comparativeDiagnosis',
                    'historyHospitalCare.comparativeDiagnosis.icd',
                    ])
                ->findOrFail($id);

        return Helper::responseJson(ClaimShowResource::make($claim));
    }

    /**
     * Show the form for editing the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function edit($id)
    {
        $claim = Claim::query()
                ->with([
                    'member',
                    'plan',
                    'member.currentPlan',
                    'member.currentPlan.benefits',
                    'member.currentCorporate',
                    'member.currentPolicy',
                    // 'diagnosis',
                    'diagnoses',
                    'diagnoses.icd',
                    'benefit',
                    'files',
                    'claimRequest',
                    'claimRequest.files',
                    'items',
                    'items.claim_itemable',
                    'encounters',
                    'encounters.doctors',
                    'encounters.primaryDiagnoses',
                    'encounters.primaryDiagnoses.diagnosis',
                    'encounters.healthcare'
                    ])
                ->findOrFail($id);

        return Helper::responseJson(ClaimEditResource::make($claim));
    }

    /**
     * Update the specified resource in storage.
     * @param Request $request
     * @param int $id
     * @return Renderable
     */
    public function update(Request $request, $id)
    {
        $customMessages = [
            'required' => 'Kolom :attribute wajib diisi.',
            'numeric' => 'Kolom :attribute harus berupa angka.',
        ];

        $data = [
            'benefit_desc' => $request->benefit_desc,
            'amount_incurred' => $request->amount_incurred,
            'amount_approved' => $request->amount_approved,
            'amount_not_approved' => $request->amount_not_approved,
            'excess_paid' => $request->excess_paid,
        ];

        $validator = Validator::make($request->all(), [
            'benefit_desc' => 'required',
            'amount_incurred' => 'required|numeric',
            'amount_approved' => 'required|numeric',
            'amount_not_approved' => 'required|numeric',
            'excess_paid' => 'required|numeric',
        ], $customMessages);

        if ($validator->fails()) {
            return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400);
        }

        // Validasi berhasil, lanjutkan dengan pembaruan data
        $claim = Claim::findOrFail($id);
        $claim->fill([
            'benefit_desc' => $request->benefit_desc,
            'amount_incurred' => $request->amount_incurred,
            'amount_approved' => $request->amount_approved,
            'amount_not_approved' => $request->amount_not_approved,
            'excess_paid' => $request->excess_paid,
        ])->save();

        return $claim;
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Renderable
     */
    public function destroy($id)
    {
        //
    }

    public function checkLimit(Request $request)
    {
        return true;
    }

    public function updateDetails(Request $request, $id)
    {
        $request->validate([
            'healthcare_id' => 'required',
            'doctor_id' => 'required',
            'start' => 'required',
            'end' => 'required'
        ]);

        $claim = Claim::findOrFail($id);

        return $claim;
    }

    public function updateItems(Request $request, $id)
    {
        $request->validate([]);
        $claim = Claim::findOrFail($id);

        $order = 1;
        $data = [];
        $claim->items()->forceDelete();
        $totalClaim = 0;
        foreach ($request->benefit_items as $benefitItem) {
            $benefit = Benefit::find($benefitItem['id']);
            if ($benefit) {
                $benefit->claimItem()->create([
                    'claim_id' => $claim->id,
                    'order' => $order,
                    'name' => $benefit->code,
                    'currency' => 'IDR',
                    'nominal_ditagihkan' => $benefitItem['biaya_diajukan'] ?? 0,
                    'nominal_dicover' => $benefitItem['biaya_disetujui'] ?? 0,
                    'nominal_total' => $benefitItem['biaya_disetujui'] ?? 0,
                ]);
                $totalClaim += $benefitItem['biaya_disetujui'];
            }

            $order++;
        }

        // Update total
        $claim->total_claim = $totalClaim;
        $claim->save();

        return Helper::responseJson([], message: "Item Claim berhasil di update");
    }

    public function updateDiagnosis(Request $request, $id)
    {
        $request->validate([]);
        $claim = Claim::findOrFail($id);

        $claim->diagnoses()->forceDelete();
        if ($request->primary) {
            foreach ($request->primary as $diagnosisId) {
                    $claim->diagnoses()->create([
                        'claim_id' => $claim->id,
                        'type' => 'primary',
                        'diagnosis_id' => $diagnosisId,
                        'note' => '',
                        'description' => '',
                    ]);
            }
        }

        if ($request->secondary) {
            foreach ($request->secondary as $diagnosisId) {
                $claim->diagnoses()->create([
                    'claim_id' => $claim->id,
                    'type' => 'secondary',
                    'diagnosis_id' => $diagnosisId,
                    'note' => '',
                    'description' => '',
                ]);
            }
        }

        return Helper::responseJson([], message: "Diagnosis berhasil di update");
    }

    public function decline($id)
    {
        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $id)
        ->select('claim_requests.id')
        ->first();
        $id = $data_claim_requests->id;

        DB::table('claims')
        ->where('claim_request_id', $id)
        ->update(
            [
                'status' => 'declined'
            ]
        );

        // Claim Log
        DB::table('claim_logs')
        ->insert([
            'claim_request_id' => $id,
            'status' => 'declined',
            'date' => date('Y-m-d H:i:s'),
            'description' => "Claim Requested Declined",
            'system_origin' => 'prime-center',
            'created_by' => auth()->user()->id,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at'=> date('Y-m-d H:i:s'),
        ]);

        return Helper::responseJson([], message: "Claim berhasil di decline");
    }

    public function approve($id)
    {
        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $id)
        ->select('claim_requests.id')
        ->first();
        $id = $data_claim_requests->id;

        DB::table('claims')
        ->where('claim_request_id', $id)
        ->update(
            [
                'status' => 'approved'
            ]
        );

        // Claim Log
        DB::table('claim_logs')
        ->insert([
            'claim_request_id' => $id,
            'status' => 'approved',
            'date' => date('Y-m-d H:i:s'),
            'description' => "Claim Requested Successfully Approved",
            'system_origin' => 'prime-center',
            'created_by' => auth()->user()->id,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at'=> date('Y-m-d H:i:s'),
        ]);

        return Helper::responseJson([], message: "Claim berhasil di approve");
    }

    public function reOpen($id)
    {
        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $id)
        ->select('claim_requests.id')
        ->first();
        $id = $data_claim_requests->id;

        DB::table('claims')
        ->where('claim_request_id', $id)
        ->update(
            [
                'status' => 'received'
            ]
        );

        // Claim Log
        DB::table('claim_logs')
        ->where('claim_request_id', $id)
        ->where(function ($query) {
            $query->where('status', 'declined')
                ->orWhere('status', 'approved');
        })
        ->delete();

        return Helper::responseJson([], message: "Claim berhasil di re-open");
    }

    public function downloadFinalLog($id)
    {
        //Claim
        $claim = DB::table("claims")
        ->where('claims.id', '=', $id)
        ->select(
            'claims.code',
            'claims.created_at',
            'claims.member_id',
            'claims.plan_id',
        )
        ->first();

        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $id)
        ->select('claim_requests.id')
        ->first();
        $id = $data_claim_requests->id;

        //Hospital
        $hospital = $hospital = DB::table('claim_services')
        ->leftJoin('corporate_hospitals', 'claim_services.hospital_id', '=', 'corporate_hospitals.id')
        ->leftJoin('organizations','organizations.id', '=', 'corporate_hospitals.organization_id')
        ->leftJoin('addresses', 'addresses.id', '=', 'organizations.main_address_id')
        ->where('claim_services.claim_request_id', '=', $id)
        ->select('corporate_hospitals.name', 'addresses.text AS address')
        ->first();

        //Memeber
        $member = DB::table('members')
        ->leftJoin('member_plans', 'member_plans.member_id', '=', 'members.id')
        ->where('members.id', '=', $claim->member_id)
        ->where('member_plans.plan_id', '=', $claim->plan_id)
        ->select(
            'members.name',
            DB::raw('(SELECT room_class_coverage FROM corporate_benefits WHERE corporate_benefits.plan_id = '.$claim->plan_id.' LIMIT 1) as room_class_coverage'),
            'members.birth_date',
            'members.gender',
            'members.payor_id',
            DB::raw('(SELECT corporates.name FROM corporates INNER JOIN corporate_employees ON corporate_employees.corporate_id = corporates.id WHERE corporate_employees.member_id = '.$claim->member_id.' LIMIT 1) AS corporate_name'),
            DB::raw('(SELECT services.name FROM services INNER JOIN plans ON plans.service_code = services.code WHERE plans.id = '.$claim->plan_id.' LIMIT 1) AS services'),
            DB::raw('(SELECT member_policies.end FROM member_policies WHERE member_policies.member_id = members.member_id LIMIT 1) AS periode_policy'),
             DB::raw('(SELECT member_policies.status FROM member_policies WHERE member_policies.member_id = members.member_id LIMIT 1) AS status_policy'),
        )
        ->first();

        //Benfit Claim
        $benefit = DB::table('claim_service_benefits')
        ->leftJoin('benefits', 'benefits.id', '=', 'claim_service_benefits.benefit_id')
        ->leftJoin('claim_services', 'claim_services.id', '=', 'claim_service_benefits.claim_service_id')
        ->where('claim_services.claim_request_id', '=', $id)
        ->select('benefits.description', 'claim_service_benefits.amount_incurred AS biaya_diajukan', 'claim_service_benefits.amount_approved AS biaya_disetujui', 'claim_service_benefits.amount_not_approved AS biaya_tidak_disetujui')
        ->get();

        // TODO Fix this tipu tipu
        //$inpationBenefit = $claim->member->currentPlan->benefits()->first();

        $pdf = PDF::loadView('pdf.final_log', [
            'claim' => $claim,
            'member' => $member,
            // 'dateOfAdmission' => $claim->start,
            'hospital' => $hospital,
            'benefit' => $benefit,
            //'inpationBenefit' => $inpationBenefit
        ]);

        return $pdf->download('Final LOG.pdf');

        $view = view('pdf.final_log', [
            'claim' => $claim,
            'member' => $member,
            // 'dateOfAdmission' => $claim->start,
            'hospital' => $hospital,
            'benefit' => $benefit,
           // 'inpationBenefit' => $inpationBenefit
        ]);

        return $view;
    }

    public function dataClaimReport(Request $request){
        $file_name = 'Data Claim Report';
        // Membuat penulis entitas Spout
        $writer = WriterEntityFactory::createXLSXWriter();
         // Membuka penulis untuk menulis ke file
        $writer->openToFile(public_path('files/Benefit Usage Report.xlsx'));

       // Sheet 1
        $writer->getCurrentSheet()->setName('Worksheet');
        $headers_map_to_table_fields = Claim::$listing_doc_headers;
        $headerRow = WriterEntityFactory::createRowFromArray($headers_map_to_table_fields);
        $writer->addRow($headerRow);

        $claims = Claim::with([
            'member',
            'member.currentPolicy',
            'member.currentPlan',
            'member.currentCorporate',
            'diagnoses' => function ($diagnosis) {
                return $diagnosis->where('type', 'primary');
            },
            'diagnoses.icd',
            'plan',
            'benefit',
            'claimRequest',
            'claimRequest.service',
            'encounters',
        ])
        // ->latest()
        ->get()->toArray();
        foreach ($claims as $index => $row){
            $rowData = [
               '', // Count of Usage
               $row['code'], // Claim Number
               $row['member']? $row['member']['payor_id'] : '-', // Insurar Code
               $row['member']['current_policy']? $row['member']['current_policy']['code'] : '', // Policy no
               $row['member']['current_corporate']? $row['member']['current_corporate']['name'] : '', // Corporate Name
               $row['member']['current_plan']?  $row['member']['current_plan']['code'] : '', // Plan Code
               $row['member']['name'], // Member Name
               $row['member']['record_type'], // Member Status
               $row['member']['birth_date'], // Date of brith
               $row['member']['member_id'], // Member Number
               $row['member']['current_corporate']?  $row['member']['current_corporate']['code'] : '', // Institution Code
               '', // Invoice Line Number
               $row['status'], // Claim Status
               $row['claim_request']? $row['claim_request']['submission_date'] : '-', // Admission Date
               '', // Discharge Date
               '', // Date Of Service
               '', // Place Of Service
               '', // Los
               '', // Provider code
               '', // Treating Doctor Code
               '', // Treating Doctor Name
               '', // Doctor Title
               $row['diagnoses']?$row['diagnoses'][0]['icd']['name']: '-', // Diagnosis
               $row['plan']?$row['plan']['service_code']: '', // Service Code
               $row['plan']?$row['plan']['type'] : '', // ServiceType
               $row['claim_request'] ? $row['claim_request']['service']['description'] : '', // ServiceDescription
               '', // UnitPrice
               '', // Quantity
               $row['member']['current_policy']['latest_limit_journal'] ? abs($row['member']['current_policy']['latest_limit_journal']['total_credit']): '', // Tarif
               '', // Claimable amount
               '', // Paid by customer
               '', // HD Disc
               '', // Doctor Notes
               '', // ConsultationID Date
               '', // Pharmacy Code
               '', // Pharmacy Name
               '', // Pharmacy Permit Number
               '', // Pharmacy Address
               '', // Pharmacy Phone number
               '', // Delivery Address
               '', // Claimable Status
               $row['claim_request'] ? $row['claim_request']['service']['description'] : '', // ServiceDescription, // Benefit Code
            ];
            // dd($rowData);
            $row = WriterEntityFactory::createRowFromArray($rowData);
            $writer->addRow($row);
        }

        // $dataClaim = Claim::query
        // $dataPlans = Claim::query()
        //     ->filter($request->all())
        //     ->where('corporate_id', $corporate_id)
        //     // ->whereHas('corporatePlan', function ($corporatePlan) use ($corporate_id) {
        //     //     $corporatePlan->where('corporate_id', $corporate_id);
        //     // })
        //     // ->with('corporatePlan')
        //     ->orderBy('corporate_plan_id', 'asc')
        //     ->get()->toArray();
        // foreach ($dataPlans as $index => $row){
        //     $rowData = [
        //         $row['service_code'], // Service
        //         $row['corporate_plan_id'], // Plan
        //         $row['code'], // Customer plans
        //         $row['type'], // Plan Type
        //         $row['start'], // Start Date of Plan
        //         $row['end'], // End Date of Plan
        //         $row['require_referral'], // Referral
        //         $row['referral_source'], // Referral Source
        //         $row['referral_duration'], // Referral Duration
        //         $row['family_plan'], // Family Plan
        //         $row['family_plan_share_rules'], // Family Sharing Overflow
        //         $row['limit_rules'], // Plan Limit
        //         $row['layer'], // Layer ID
        //         $row['layer_conditions'], // Layer Condition
        //         $row['budget_type'], // Budget Type
        //         $row['budget_code'], // Budget Code
        //         $row['budget_conditions'], // Budget Condition
        //         $row['surgery_limit'], // Surgery
        //         $row['non_surgery_limit'], // Non Surgery
        //         $row['max_claim_limit'], // Max/Claim
        //         $row['max_claim_count'], // Max Count of Claim
        //         $row['area_limit'], // Area
        //         $row['limit_shared_plans'], // Shared Plan
        //         $row['limit_shared_plan_type'], // Shared Plan Type
        //         $row['cashless_percentage'], // Cashless(%)
        //         $row['reimbursement_percentage'], // Reimbursement(%)
        //         $row['digital_percentage'], // Digital(%)
        //         $row['co_share_m_percentage'], // CoShareM(%)
        //         $row['co_share_s_percentage'], // CoShareS(%)
        //         $row['co_share_c_percentage'], // CoShareC(%)
        //         $row['cashless_deductible'], // Cashless Deductible
        //         $row['cashless_deductible'], // Reimbursement Deductible
        //         $row['digital_deductible'], // Digital Deductible
        //         $row['co_share_m_deductible'], // DeductibleM
        //         $row['co_share_s_deductible'], // DeductibleS
        //         $row['co_share_c_deductible'], // DeductibleC
        //         $row['co_share_deductible_condition'], // Co-share & Deductible Condition
        //         $row['msc'], // MSC
        //         $row['genders'], // Gender
        //         $row['min_age'], // Min Age
        //         $row['max_age'], // Max Age
        //         $row['rule_of_excess'], // Rule of Excess
        //         $row['max_excess_covered'], // Max Excess Covered
        //         $row['prorate_type'], // Prorate Type
        //         $row['prorate_lookup'], // Prorate Lookup
        //         $row['currency'], // Currency
        //         $row['max_surgery_reinstatement_days'], // Reinstatement days for Surgery NonSurgery
        //         $row['max_surgery_periode_days'], // Max Periode of Surgery Non Surgery
        //     ];
        //     $row = WriterEntityFactory::createRowFromArray($rowData);
        //     $writer->addRow($row);

        // }

        $writer->close();

        return Helper::responseJson([
            'file_name' => "Data Claim Report " . date('Y-m-d h:i:s'),
            "file_url" => url('files/Benefit Usage Report.xlsx')
        ]);
    }

    public function getDetailClaims($claim_id)
    {
        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $claim_id)
        ->select('claim_requests.id')
        ->first();
        $claim_id = $data_claim_requests->id;

        $customer_data = DB::table('claim_requests')
                    ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
                    ->leftJoin('members', 'claim_requests.member_id', '=', 'members.id')
                    ->leftJoin('corporate_employees', 'members.id', '=', 'corporate_employees.member_id')
                    ->leftJoin('corporates', 'corporate_employees.corporate_id', '=', 'corporates.id')
                    ->where('claim_requests.id', '=', $claim_id)
                    ->select(
                        'claim_requests.code',
                        'claim_requests.submission_date',
                        'claims.status',
                        'members.name',
                        'members.payor_id',
                        'members.member_id',
                        'claim_requests.payment_type',
                        'corporates.name AS coporate_name',
                    )
                    ->first();
        $results['customer_data'] = $customer_data;

        $documents = DB::table('files')
                                ->where('fileable_type', 'App\Models\ClaimRequest')
                                ->where('fileable_id', $claim_id)
                                ->select('original_name', \DB::raw("CONCAT('" . env('APP_URL') . "/storage/', path) as path"), 'type')
                                ->orderBy('id', 'desc')
                                ->get();
        $results['documents'] = $documents;

        $request_documents = DB::table('claim_request_files')
        ->where('claim_request_id', $claim_id)
        ->get();
        $results['request_documents'] = $request_documents;

        $claim_services = DB::table('claim_services')
        ->where('claim_services.claim_request_id', $claim_id)
        ->select(
            'claim_services.id',
            'claim_services.addmission_date',
            'claim_services.discharge_date',
            'claim_services.service_id',
            DB::raw('(SELECT services.name FROM services WHERE id = claim_services.service_id LIMIT 1) AS name_services'),
            'claim_services.hospital_id',
            DB::raw('(SELECT corporate_hospitals.name FROM corporate_hospitals WHERE id = claim_services.hospital_id LIMIT 1) AS name_hospitals'),
        )
        ->groupBy('claim_services.id')
        ->first();
        $results['claim_services'] = $claim_services;

        if($claim_services && $claim_services->id)
        {
            $claim_service_benefits = DB::table('claim_service_benefits')
            ->where('claim_service_id', $claim_services->id)
            ->select(
                'claim_service_benefits.claim_service_id',
                'claim_service_benefits.benefit_id',
                DB::raw('(SELECT benefits.description FROM benefits WHERE id = claim_service_benefits.benefit_id LIMIT 1) AS name_benefits')
            )
            ->get();
            foreach ($claim_service_benefits as $item) {
                $claimServiceId = $item->claim_service_id;
                $nameBenefits = $item->name_benefits;
                $benefitId = $item->benefit_id."";
                if (!isset($output[$claimServiceId])) {
                    $output[$claimServiceId] = (object)[
                        "claim_service_id" => $claimServiceId,
                        "name_benefits" => $nameBenefits,
                        "benefit_id" => [$benefitId],
                    ];
                } else {
                    $output[$claimServiceId]->name_benefits .= ", " . $nameBenefits;
                    $output[$claimServiceId]->benefit_id[] = $benefitId."";
                }
            }
            $output = array_values($output);

            $results['claim_service_benefits'] = $output[0];
        }
        else
        {
            $results['claim_service_benefits'] = null;
        }

        $dialog_submits = DB::table('claim_requests')
                            ->leftJoin('members', 'claim_requests.member_id','=', 'members.id')
                            ->where('claim_requests.id', $claim_id)
                            ->select('claim_requests.code', 'members.name', 'claim_requests.submission_date', 'claim_requests.service_code','claim_requests.status')
                            ->first();
        $results['dialog_submits'] = $dialog_submits;


        return Helper::responseJson($results);
    }

    public function getServices($claim_id)
    {
        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $claim_id)
        ->select('claim_requests.id', 'claim_requests.member_id')
        ->first();
        $claim_id = $data_claim_requests->id;

        //Corporate_id
        $corporate_id = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->leftJoin('members', 'claim_requests.member_id', '=', 'members.id')
        ->leftJoin('corporate_employees', 'members.id', '=', 'corporate_employees.member_id')
        ->leftJoin('corporates', 'corporate_employees.corporate_id', '=', 'corporates.id')
        ->where('claim_requests.id', '=', $claim_id)
        ->select('corporates.id')
        ->first();

        //Service Type
        $service_type = DB::table('claim_requests')
        ->leftJoin('services','claim_requests.service_code', 'services.code')
        ->where('claim_requests.id', $claim_id)
        ->select('services.name', 'services.code', 'services.id')
        ->get();
        $results['service_type'] = $service_type;

        //Member Plans
        $plan_id = DB::table('claims')
        ->where('claims.claim_request_id', $claim_id)
        ->select('claims.plan_id')
        ->first();

        //Benefit Name
        $benefit_name = DB::table('member_plans')
            ->leftJoin('corporate_benefits','corporate_benefits.plan_id', '=', 'member_plans.plan_id')
            ->leftJoin('benefits', 'benefits.id', '=', 'corporate_benefits.benefit_id')
            ->where('member_plans.member_id', '=', $data_claim_requests->member_id)
            ->where('member_plans.plan_id', '=', $plan_id->plan_id)
            ->select('benefits.code', 'benefits.description', 'benefits.id')
            ->get();
        $results['benefit_name'] = $benefit_name;

        //Hospital
        $hospital = DB::table('corporate_hospitals')
        ->where('corporate_hospitals.corporate_id', $corporate_id->id)
        ->where('corporate_hospitals.active', 1)
        ->select('corporate_hospitals.code', 'corporate_hospitals.name', 'corporate_hospitals.id')
        ->get();
        $results['hospital'] = $hospital;

        return Helper::responseJson($results);
    }

    public function saveServices(Request $request)
    {
        $request->validate([
            'claim_request_id' => 'required',
            'dateAdd' => 'required',
            'dateDisc' => 'required',
            'serviceType' => 'required',
            'hospital' => 'required',
            'benefitName' => 'required',
        ]);

        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $request->claim_request_id)
        ->select('claim_requests.id')
        ->first();
        $claim_id = $data_claim_requests->id;


        if($request->flagAddService === 'add')
        {
            $data = [
                'claim_request_id' => $claim_id,
                'service_id' => $request->serviceType,
                'hospital_id' => $request->hospital,
                'addmission_date' => $request->dateAdd,
                'discharge_date' => $request->dateDisc,
                'created_by' =>auth()->user()->id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => null,
            ];
            $id = DB::table('claim_services')
            ->insertGetId($data);
            foreach ($request->benefitName  as $value)
            {
                DB::table('claim_service_benefits')
                ->insert([
                    'claim_service_id' => $id,
                    'benefit_id' => $value,
                    'created_by' =>auth()->user()->id,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ]);
            }
        }
        else if($request->flagAddService === 'edit')
        {
            $data = [
                'claim_request_id' => $claim_id,
                'service_id' => $request->serviceType,
                'hospital_id' => $request->hospital,
                'addmission_date' => $request->dateAdd,
                'discharge_date' => $request->dateDisc,
                'created_by' =>auth()->user()->id,
                'created_at' => null,
                'updated_at' => date('Y-m-d H:i:s'),
            ];
            DB::table('claim_services')
            ->where('claim_services.id', $request->idService)
            ->update($data);

            DB::table('claim_service_benefits')
            ->where('claim_service_id', $request->idService)
            ->delete();

            foreach ($request->benefitName  as $value)
            {
                DB::table('claim_service_benefits')
                ->insert([
                    'claim_service_id' => $request->idService,
                    'benefit_id' => $value,
                    'created_by' =>auth()->user()->id,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ]);
            }
        }

        return Helper::responseJson([]);
    }

    public function requestDocuments(Request $request)
    {
        $request->validate([
            'claim_id' => 'required',
            'note' => 'required',
        ]);

        //Get claim request id
        $data_claim_requests = DB::table('claim_requests')
        ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
        ->where('claims.id', $request->claim_id)
        ->select('claim_requests.id')
        ->first();

        $claim_id = $data_claim_requests->id;

        $condition = $request->input('condition');
        $diagnosis = $request->input('diagnosis');
        $result = $request->input('result');
        $note = $request->input('note');

        $dataToInsert = [];
        $description = "";
        if ($condition) {
            $dataToInsert[] = [
                'claim_request_id' => $claim_id,
                'date' => date('Y-m-d H:i:s'),
                'type' => 'claim-kondisi',
                'description' => $note,
                'created_by' => auth()->user()->id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ];
            $description = "Condition";
            $this->sendNotif($description);
        }
        if ($diagnosis) {
            $dataToInsert[] = [
                'claim_request_id' => $claim_id,
                'date' => date('Y-m-d H:i:s'),
                'type' => 'claim-diagnosis',
                'description' => $note,
                'created_by' =>auth()->user()->id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ];
            $description = "Diagnosis";
            $this->sendNotif($description);
        }
        if ($result) {
            $dataToInsert[] = [
                'claim_request_id' => $claim_id,
                'date' => date('Y-m-d H:i:s'),
                'type' => 'claim-result',
                'description' => $note,
                'created_by' =>auth()->user()->id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ];
            $description = "Result";
            $this->sendNotif($description);
        }
        DB::table('claim_request_files')->insert($dataToInsert);

        return Helper::responseJson([]);
    }

    public function sendNotif($description)
    {
        // Insert data notifications
        $emailTo = 'hospitaladmin@linksehat.com';
        $dataNotif = [
            'email' => $emailTo,
            'title' => 'Request Document',
            'description' => 'Please enter the document '.$description,
            'type' => 1,
            'isUnRead' => true,
            'created_by' => auth()->user()->id,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ];
        $sendNotif = Helper::insertNotification($dataNotif);
        // Send Email after insert notifications
        if($sendNotif)
        {
            $nameTo = 'Hospital Admin';
            $dataEmail = [
                'email' => $emailTo,
                'name' => $nameTo,
                'subject' => 'Enter Document '.$description,
                'body' => View::make('email/notif_email', ['name' => $nameTo, 'link' => 'https://hospitalportal.linksehat.com/dashboard'])->render(),
            ];
            Helper::sendEmail($dataEmail);
        }
    }

    //////////////////// History Care Hospital ///////////////////////////

    public function storeHistoryCare(Request $request, $id){
        $request->validate([
            'service_code' => 'required',
            'admission_date' => 'required',
            'discharge_date' => 'required',
            'organization_id' => 'required',
            'practitioner_id' => 'required',
            'medical_record_number' => 'required',
            'symptoms' => 'required',
            'sign' => 'required',
            'main_diagnosis_id' => 'required',
        ]);

        $data = [
            'service_code' => $request->service_code,
            'admission_date' => $request->admission_date,
            'discharge_date' => $request->discharge_date,
            'organization_id' => $request->organization_id,
            'practitioner_id' => $request->practitioner_id,
            'medical_record_number' => $request->medical_record_number,
            'symptoms' => $request->symptoms,
            'sign' => $request->sign,
            'claim_id' => $id,
            'main_diagnosis_id' => $request->main_diagnosis_id,
            'status' => 0,
        ];

        $claimHistoryCare = ClaimHistoryCare::create($data);
        if (count($request->secondary_diagnosis_id)) {
            foreach($request->secondary_diagnosis_id as $value){
                $dataSecondary = [
                    'claim_history_care_id' => $claimHistoryCare->id,
                    'icd_id' => intval($value)
                ];
                DiagnosisSecondaryClaimHistoryCare::create($dataSecondary);
            }
        }

        return Helper::responseJson($claimHistoryCare);
    }

    public function updateHistoryCare(Request $request, $id){
        $data = $request->validate([
            'service_code' => 'required',
            'admision_date' => 'required',
            'discharge_date' => 'required',
            'organization_id' => 'required',
            'practitioner_id' => 'required',
            'medical_record_number' => 'required',
            'symptoms' => 'required',
            'sign' => 'required',
            'main_diagnosis_id' => 'required',
        ]);

        // $data['status'] = 0;

        $claimHistoryCare = ClaimHistoryCare::findOrFail($id);
        $claimHistoryCare->update($data);

        // Hapus diagnosis sekunder yang terkait
        DiagnosisSecondaryClaimHistoryCare::where('claim_history_care_id', $id)->delete();

        if (count($request->secondary_diagnosis_id)) {
            foreach ($request->secondary_diagnosis_id as $value) {
                $dataSecondary = [
                    'claim_history_care_id' => $claimHistoryCare->id,
                    'icd_id' => intval($value),
                ];
                DiagnosisSecondaryClaimHistoryCare::create($dataSecondary);
            }
        }

        return Helper::responseJson(message: 'Data Berhasil di update');

    }

    public function showHistoryCare($id){
        $data = ClaimHistoryCare::with(['organization', 'practitioner', 'practitioner.person', 'icd'])->find($id);

        return Helper::responseJson(ClaimHistoryCareResource::make($data));
    }

    public function approvalHistoryCare(Request $request){
        $request->validate([
            'claim_id' => 'required'
        ]);

        $claimHistoryCare = ClaimHistoryCare::findOrFail($request->claim_id);
        $claimHistoryCare->status = $request->status;
        $claimHistoryCare->save();

        return Helper::responseJson(message: 'Data Berhasil di update');
    }

    /**
     * Get Benefit Configuration
     *
     * Bagaskoro, BSD 03 November 2023
     */
    public function getBenefitConfiguration(Request $request, $claim_id) {

        $benefit_list = DB::table('claims')
            ->leftJoin('claim_services', 'claims.claim_request_id', '=', 'claim_services.claim_request_id')
            ->leftJoin('claim_service_benefits', 'claim_services.id', '=', 'claim_service_benefits.claim_service_id')
            ->leftJoin('benefits', 'claim_service_benefits.benefit_id', '=', 'benefits.id')
            ->select("claim_service_benefits.id AS claim_service_benefits_id", "benefits.description AS benefit_name", "claim_service_benefits.amount_incurred", "claim_service_benefits.amount_approved", "claim_service_benefits.amount_not_approved", "claim_service_benefits.excess_paid")
            ->where("claims.id", "=", $claim_id)
            ->get();

        return response()->json([
            'error'   => false,
            'message' => "success",
            'data'    => [
                'benefit_list' => $benefit_list,
            ]
        ],200);
    }

    /**
     * Edit Benefit Configuration
     *
     * Bagaskoro, BSD 03 November 2023
     */
    public function editBenefitConfiguration(Request $request, $claim_service_benefits_id) {
        $request->merge(['claim_service_benefits_id' => $claim_service_benefits_id]);

        // validation rule
        $validator = Validator::make($request->all(),[
            'claim_service_benefits_id' => 'required|exists:claim_service_benefits,id',
            'amount_incurred'           => 'required|numeric',
            'amount_approved'           => 'required|numeric',
            'amount_not_approved'       => 'required|numeric',
            'excess_paid'               => 'required|numeric',
        ],$this->messages());

        // validation error
        if ($validator->fails()) {
            return response()->json([
                'error'   => true,
                'message' => $validator->getMessageBag()
            ],400);
        }

        try {
            DB::table('claim_service_benefits')->where('id', $claim_service_benefits_id)->update([
                'amount_incurred'       => $request->amount_incurred,
                'amount_approved'       => $request->amount_approved,
                'amount_not_approved'   => $request->amount_not_approved,
                'excess_paid'           => $request->excess_paid,
            ]);
        }
        catch (\Throwable $th) {
            return Helper::responseJson(status: 'failed', statusCode: 500, message: $th->getMessage());
        }

        return Helper::responseJson(status: 'success', statusCode: 200, message: "data berhasil disimpan !");
    }

    protected function messages()
    {
        return [
            'required'      => ':attribute harus diisi',
            'integer'       => ':attribute harus angka',
            'unique'        => ':attribute (:input) sudah ada',
            'max'           => ':attribute maximal :max karakter',
            'exists'        => ':attribute (:input) tidak ditemukan',
            'numeric'       => ':attribute harus angka',
            'digits_between'=> ':attribute maximal :max digit minimal :min digit'
        ];
    }
}
