<?php

namespace Modules\Internal\Http\Controllers\Api;

use App\Helpers\Helper;
use App\Models\Person;
use App\Models\Practitioner;
use App\Models\PractitionerRole;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\Internal\Transformers\DoctorResource;

class DoctorController extends Controller
{
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index(Request $request)
    {

        $doctors = Practitioner::with('person', 'practitionerRoles.organization', 'practitionerRoles.speciality')
            ->when($request->search ?? null, function ($query, $search) {
                $query->whereHas('person', function ($person) use ($search) {
                    $person->where('name', 'LIKE', '%' . $search . '%');
                });
            })
            ->when($request->id ?? null, function ($query, $id) {
                $query->where('id', $id);
            })
            ->when($request->organization_id ?? null, function ($query, $organization_id) {
                $query->whereHas('practitionerRoles', function ($practitionerRole) use ($organization_id) {
                    $practitionerRole->where('organization_id', $organization_id);
                });
            })
            ->when($request->speciality_id ?? null, function ($query, $speciality_id) {
                $query->whereHas('practitionerRoles', function ($practitionerRole) use ($speciality_id) {
                    $practitionerRole->where('speciality_id', $speciality_id);
                });
            })
            ->paginate();

        // return $doctors;


        return response()->json(Helper::paginateResources(DoctorResource::collection($doctors)));
    }

    /**
     * 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)
    {
        $data_person = [
            'name' => $request->name,
            'gender' => $request->gender,
            'address' => $request->address,
            'phone' => $request->phone,
            'email' => $request->email,
            'birth_date' => date('Y-m-d', strtotime($request->birth_date)),
            'birth_place' => $request->birth_place,
        ];

        $person = Person::create($data_person);
        $address = $person->addresses()->create([
            'use' => 'both',
            'type' => 'physical',
            'text' => $request->address,
        ]);

        $person->main_address_id = $address->id;
        $person->save();

        $practitioner = $person->practitioner()->create();

        $practices = $request->practices;
        if ($practices[0]['organization_id'] !== null) {
            foreach ($practices as $key => $practice) {
                if (isset($practice['specialities'])) {
                    //jika input spesialis
                    foreach ($practice['specialities'] as $key => $speciality) {
                        $speciality_id = $speciality['speciality_id'];
                        $organization_id = $practice['organization_id'];
                        $practitionerRole = $practitioner->practitionerRoles()->create([
                            'organization_id' => $organization_id,
                            'speciality_id' => $speciality_id,
                        ]);
                    }
                } else {
                    //jika tidak input spesialis
                    $speciality_id = null;
                    $organization_id = $practice['organization_id'];

                    $practitionerRole = $practitioner->practitionerRoles()->create([
                        'organization_id' => $organization_id,
                        'speciality_id' => $speciality_id,
                    ]);
                }
            }
        }

        return response()->json([
            'status' => 'success',
            'message' => 'Data berhasil disimpan',
        ]);
    }

    /**
     * Show the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function show($id)
    {
        $practitioner = Practitioner::with('person', 'practitionerRoles.organization', 'practitionerRoles.speciality')->find($id);
        return response()->json(DoctorResource::make($practitioner));
    }

    /**
     * Show the form for editing the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function edit($id)
    {
        $practitioner = Practitioner::with('person', 'practitionerRoles.organization', 'practitionerRoles.speciality')->find($id);
        return response()->json(DoctorResource::make($practitioner));
    }

    /**
     * Update the specified resource in storage.
     * @param Request $request
     * @param int $id
     * @return Renderable
     */
    public function update(Request $request, $id)
    {
        $practitioner = Practitioner::find($id);
        $data_person = [
            'name' => $request->name,
            'gender' => $request->gender,
            'address' => $request->address,
            'phone' => $request->phone,
            'email' => $request->email,
            'birth_date' => date('Y-m-d', strtotime($request->birth_date)),
            'birth_place' => $request->birth_place,
        ];

        $person = $practitioner->person;
        $person->update($data_person);
        $address = $practitioner->person->addresses()->updateOrCreate([
            'use' => 'both',
            'type' => 'physical',
            'text' => $request->address,
        ]);
        $practitioner->person->main_address_id = $address->id;
        $practitioner->person->save();

        $practices = $request->practices;
        $practitionerRole = $practitioner->practitionerRoles()->get() ?? null;

        foreach ($practices as $practice) {
            $organization_id = $practice['organization_id'];
            foreach ($practice['specialities'] as $speciality) {
                $speciality_id = $speciality['speciality_id'];
                $cek =  $practitionerRole->where('organization_id', $organization_id)
                    ->where('speciality_id', $speciality_id)->first() ?? null;
                if (!$cek || $practitionerRole->isEmpty()) {
                    // Create new practitioner role if not found
                    $practitioner->practitionerRoles()->create([
                        'organization_id' => $organization_id,
                        'speciality_id' => $speciality_id,
                    ]);
                }
            }
        }


        if ($practitionerRole) {
            // Remove practitioner roles that are no longer exists
            $currentRoleIds = $practitionerRole->pluck('id')->toArray();
            $newRoleIds = [];

            foreach ($practices as $practice) {
                $organization_id = $practice['organization_id'];
                foreach ($practice['specialities'] as $speciality) {
                    $speciality_id = $speciality['speciality_id'];
                    $newPractitionerRole = $practitionerRole->where('organization_id', $organization_id)
                        ->where('speciality_id', $speciality_id)
                        ->first();

                    if ($newPractitionerRole) {
                        $newRoleIds[] = $newPractitionerRole->id;
                    }
                }
            }

            $deletedRoleIds = array_diff($currentRoleIds, $newRoleIds);

            if (count($deletedRoleIds) > 0) {
                // Delete practitioner roles that are no longer exists
                $data = $practitionerRole->whereIn('id', $deletedRoleIds);
                $data->each(function ($item) {
                    $item->delete();
                });
            }
        }

        return response()->json([
            'status' => 'success',
            'message' => 'Data berhasil disimpan',
        ]);
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Renderable
     */
    public function destroy($id)
    {
        $practitioner = Practitioner::find($id);
        $person = $practitioner->person->delete();
        $address = $practitioner->person->addresses()->delete();
        $practitionerRole = $practitioner->practitionerRoles()->delete();
        $practitioner->delete();
        return response()->json([
            'status' => 'success',
            'message' => 'Data berhasil dihapus',
        ]);
    }
}
