<?php

namespace App\Services;

use App\Models\CorporateEmployee;
use App\Models\Member;
use App\Models\Encounter;
use App\Models\RequestLog;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class CorporateMemberService
{
    public function getAllMemberDashboards(int $corporateId, Request $request)
    {
        $limit = $request->has('perPage') ? $request->input('perPage') : 10;
        $memberIds = CorporateEmployee::where('corporate_id', $corporateId)
            ->when($request->input('division'), function ($query, $value) {
                $query->where('division_id', $value);
            })
            ->pluck('member_id');
        return Member::with(['person'])
            ->whereIn('id', $memberIds)
            ->when($request->input('search'), function ($query, $search) {
                $query->where(function ($query) use ($search) {
                    $query->orWhere('member_id', 'like', "%" . $search . "%")
                        ->orWhere('name', 'like', "%" . $search . "%");
                });
            })
            ->when($request->has('orderBy'), function ($query) use ($request) {
                $orderBy = match ($request->input('orderBy')) {
                    'memberId' => 'member_id',
                    'fullName' => 'name',
                    'status' => 'active',
                    default => null,
                };
                if ($orderBy !== null && $request->order) {
                    $query->orderBy($orderBy, $request->order);
                }
            })
            ->select([
                'id',
                'person_id',
                'member_id',
                'name',
                'active',
            ])
            ->withCount([
                'claims as claims_sum_total_claim' => function ($query) {
                    $query->select(DB::raw('COALESCE(SUM(total_claim), 0)'))->whereNull('deleted_at');
                },
            ])
            ->paginate($limit);
    }

    public function getAllMemberClaimReports(int $corporateId, Request $request)
    {
        $limit = $request->has('per_page') ? $request->input('per_page') : 10;

        $results = 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('corporate_divisions', 'corporate_employees.division_id', '=', 'corporate_divisions.id')
            ->where('corporate_employees.corporate_id', '=', $corporateId)
            ->when($request->input('search'), function ($query, $search) {
                $query->where(function ($query) use ($search) {
                    $query->orWhere('claim_requests.code', 'like', "%" . $search . "%")
                        ->orWhere('members.member_id', 'like', "%" . $search . "%")
                        ->orWhere('members.name', 'like', "%" . $search . "%")
                        ->orWhere('corporate_divisions.name', 'like', "%" . $search . "%")
                        ->orWhere('claim_requests.status', 'like', "%" . $search . "%")
                        ->orWhere('claim_requests.submission_date', 'like', "%" . $search . "%");
                });
            })
            ->when($request->has('orderBy'), function ($query) use ($request) {
                $orderBy = $request->orderBy;
                $direction = $request->order ?? 'asc';

                $query->orderBy($orderBy, $direction);
            })
            ->select(
                'members.id',
                'claim_requests.code',
                'members.member_id',
                'members.name as full_name',
                'corporate_divisions.name AS division_name',
                DB::raw('
                            CASE
                                WHEN claim_requests.status = "requested" THEN "requested"
                                WHEN claim_requests.status = "approved" AND claims.status = "approved" THEN "approved"
                                WHEN claim_requests.status = "approved" AND claims.status = "declined" THEN "declined"
                                WHEN claim_requests.status = "approved" AND claims.status = "disbrusmented" THEN "disbrusmented"
                                /*WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "pending"*/
                                WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "reviewed"
                                ELSE ""
                            END AS status
                        '),
                'claim_requests.id AS claim_request_id',
                'claim_requests.submission_date'
            )
            ->paginate($limit);
        return $results;
    }

    public function getAllMemberClaimSubmits(int $corporateId, Request $request)
    {
        $limit = $request->has('perPage') ? $request->input('perPage') : 10;

        return Member::query()
            // ->joinClaimRequests('right')
            ->joinCorporateEmployees('left')
            ->joinCorporateDivisions('left')
            ->with('currentPlans')
            ->withSum('claims', 'total_claim')
            ->whereHas('employeds', function (Builder $corporateEmployee) use ($corporateId) {
                $corporateEmployee->where('corporate_id', $corporateId);
            })
            ->when($request->input('search'), function (Builder $query, $search) {
                $query->where(function (Builder $query) use ($search) {
                    $query->orWhere('members.member_id', 'like', "%" . $search . "%")
                        ->orWhere('members.name', 'like', "%" . $search . "%");
                });
            })
            ->when($request->input('division'), function (Builder $division, $value) {
                $division->whereHas('division', function (Builder $corporateEmployee) use ($value) {
                    $corporateEmployee->where('division_id', $value);
                });
            })
            ->when($request->has('orderBy'), function (Builder $query) use ($request) {
                $orderBy = match ($request->orderBy) {
                    'memberId' => 'member_id',
                    'fullName' => 'name',
                    default => ''
                };

                if (in_array($orderBy, ['member_id', 'name', 'active'])) {
                    $query->getQuery()->orderBy($orderBy, $request->order);
                } elseif ($request->orderBy === 'division') {
                    $query->getQuery()->orderBy('corporate_divisions.name', $request->order);
                }
            })
            // ->select(['members.id', 'members.person_id', 'members.member_id', 'members.name', 'corporate_divisions.name AS division_name', 'members.active', 'claim_requests.id', 'claim_requests.member_id', 'claim_requests.submission_date'])
            ->select(['members.id', 'members.person_id', 'members.member_id', 'members.name', 'corporate_divisions.name AS division_name', 'members.active',])
            ->paginate($limit);
    }

    public function getAllMemberAlarmCenter(int $corporateId, Request $request)
    {
        $limit = $request->has('perPage') ? $request->input('perPage') : 10;
        // $start_date = date('Y-m-d', strtotime($request->input('start_date') . ' +1 day'));
        // $end_date = date('Y-m-d', strtotime($request->input('end_date') . ' +1 day'));

        // dd($request);

        // return Member::query()
        //     // ->joinCorporateEmployees('left')
        //     // ->joinMemberPlans('left')
        //     // ->joinPlans('left')
        //     // ->with(['currentPlan', 'person'])
        //     // ->where('corporate_employees.corporate_id', $corporateId)
        //     ->when($request->input('search'), function (Builder $query, $search) {
        //         $query->where(function (Builder $query) use ($search) {
        //             $query->orWhere('members.member_id', 'like', "%" . $search . "%")
        //                 ->orWhere('members.name', 'like', "%" . $search . "%");
        //         });
        //     })
        //     ->when($request->input('start_date'), function (Builder $query, $start_date) {
        //         $query->where('members.members_effective_date', '>=', $start_date);
        //     })
        //     ->when($request->input('end_date'), function (Builder $query, $end_date) {
        //         $query->where('members.members_expire_date', '<', $end_date);
        //     })
        //     ->when($request->input('division'), function (Builder $query, $value) {
        //         $query->where('corporate_employees.division_id', $value);
        //     })
        //     ->when($request->input('status'), function (Builder $query, $value) {
        //         $query->where('plans.active', $value);
        //     })
        //     ->when($request->has('orderBy'), function (Builder $query) use ($request) {
        //         $orderBy = match ($request->input('orderBy')) {
        //             'memberId' => 'member_id',
        //             'fullName' => 'name',
        //             // 'status' => 'active',
        //             'start_date' => 'member_plans.members_effective_date',
        //             'end_date' => 'member_plans.members_expire_date',
        //                 // 'service' => 'plans.service_code',

        //             default => ''
        //         };

        //         $query->getQuery()->orderBy($orderBy, $request->order);
        //     })
        //     ->select([
        //         'members.id',
        //         'members.person_id',
        //         'members.member_id',
        //         'members.name',
        //         'members.members_effective_date', // Use the actual property name
        //         'members.members_expire_date',      // Use the actual property name
        //         // 'plans.active',
        //         // 'plans.service_code'
        //     ])
        //     // ->selectRaw("(select sum(`claims`.`total_claim`) from `claims` where `members`.`id` = `claims`.`member_id` AND `claims`.`deleted_at` IS NULL) AS `claims_sum_total_claim`")
        //     // ->groupBy('member_id')
        //     ->paginate($limit);

        return RequestLog::query()
            ->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
            // ->joinMemberPlans('left')
            // ->joinPlans('left')
            // ->with(['currentPlan', 'person'])
            // ->where('corporate_employees.corporate_id', $corporateId)
            // ->whereHas('currentCorporate', function (Builder $query) use ($corporateId) {
            //     // $query->where('corporate_id', $corporateId);
            // })
            ->when($request->input('search'), function (Builder $query, $search) {
                $query->where(function (Builder $query) use ($search) {
                    $query->orWhere('members.member_id', 'like', "%" . $search . "%")
                        ->orWhere('members.name', 'like', "%" . $search . "%");
                });
            })
            ->when($request->input('start_date'), function (Builder $query, $start_date) {
                $query->where('members.members_effective_date', '>=', $start_date);
            })
            ->when($request->input('end_date'), function (Builder $query, $end_date) {
                $query->where('members.members_expire_date', '<', $end_date);
            })
            ->when($request->input('division'), function (Builder $query, $value) {
                $query->where('corporate_employees.division_id', $value);
            })
            ->when($request->input('status'), function (Builder $query, $value) {
                $query->where('plans.active', $value);
            })
            ->when($request->has('orderBy'), function (Builder $query) use ($request) {
                $orderBy = match ($request->input('orderBy')) {
                    'memberId' => 'member_id',
                    'fullName' => 'name',
                    'status' => 'active',
                    'start_date' => 'member_plans.members_effective_date',
                    'end_date' => 'member_plans.members_expire_date',
                    'request_date' => 'request_logs.submission_date',

                    default => ''
                };

                $query->getQuery()->orderBy($orderBy, $request->order);
            })
            ->select([
                'members.id',
                'members.person_id',
                'members.member_id',
                'members.name as full_name',
                'members.members_effective_date', // Use the actual property name
                'members.members_expire_date',      // Use the actual property name
                'members.active',
                'request_logs.service_code',
            ])
            // ->selectRaw("(select sum(`claims`.`total_claim`) from `claims` where `members`.`id` = `claims`.`member_id` AND `claims`.`deleted_at` IS NULL) AS `claims_sum_total_claim`")
            ->groupBy('member_id')
            ->paginate($limit);


    }

    public function getAllMemberEmployeeData(int $corporateId, Request $request)
    {
        $limit = $request->has('perPage') ? $request->input('perPage') : 10;

        return Member::query()
            ->whereHas('employeds', function ($query) use ($corporateId) {
                $query->where('corporate_id', $corporateId);
            })
            ->when($request->input('search'), function ($query, $search) {
                $query->where(function ($query) use ($search) {
                    $query->orWhere('member_id', 'like', "%" . $search . "%")
                        ->orWhere('name', 'like', "%" . $search . "%");
                });
            })
            ->when($request->has('orderBy'), function ($query) use ($request) {
                $orderBy = match ($request->input('orderBy')) {
                    'memberId' => 'member_id',
                    'fullName' => 'name',
                    'status' => 'active',
                    'start_date' => 'members_effective_date',
                    'end_date' => 'members_expire_date',
                    default => null,
                };

                if ($orderBy !== null && $request->order) {
                    $query->orderBy($orderBy, $request->order);
                }
            })
            ->select([
                'id',
                'person_id',
                'member_id',
                'name_prefix',
                'name_suffix',
                'name',
                'members_effective_date',
                'members_expire_date',
                'active',
            ])
            ->paginate($limit);
    }

    public function getAllEncounter(int $corporateId)
    {
        return Encounter::query()->select(['id'])->paginate(10);
    }
}
