<?php

namespace App\Http\Controllers\Api\V1\Vendor;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

use App\Models\Admin\ParlourList;
use App\Models\Admin\ParlourHasService;
use Illuminate\Support\Facades\Validator;
use App\Models\Admin\ParlourListHasSchedule;
use App\Http\Helpers\Api\Helpers as ApiResponse;
use Illuminate\Validation\ValidationException;
use App\Models\Admin\Area;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;
use Exception;
use App\Http\Helpers\Response;
use App\Constants\GlobalConst;
use App\Models\Admin\BasicSettings;
use App\Models\Vendor\Manager;
use App\Models\Vendor\ParlourHasStuff;
use App\Models\Vendor\ParlourImage;

class ParlourAddController extends Controller
{
    public function index()
    {
        $vendor_id      = auth()->user()->id;
        $parlour_lists  = ParlourList::where('vendor_id', $vendor_id)->with('manager', 'area', 'stuff', 'services', 'schedules','parlourImage')->orderBYDESC('id')->get();
        $parlour_image_path   = [
            'base_url'      => url('/'),
            'path_location' => files_asset_path_basename('site-section'),
            'default_image' => files_asset_path_basename('default')
        ];
        $data = [
            'stuff-image-path'    => $parlour_image_path,
            'data'               => $parlour_lists,
        ];
        $message =  ['success' => [__('Salon List')]];
        return ApiResponse::success($message, $data);
    }
    /**
     * Store parlour list information via API.
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(Request $request)
    {

        // Validation
        $validator = Validator::make($request->all(), [
            'area'             => 'required|integer',
            'name'             => 'required|string|max:50',
            'manager_id'       => 'required|integer',
            'stuff_id'         => 'nullable|array',
            'stuff_id.*'       => 'nullable|string',
            'experience'       => 'required|string|max:100',
            'speciality'       => 'nullable',
            'contact'          => 'required',
            'address'          => 'nullable',
            'off_days'         => 'required|string',
            'number_of_dates'  => 'required|integer',
            'service_name'     => 'required|array',
            'service_name.*'   => 'required|string',
            'price'            => 'required|array',
            'price.*'          => 'required|string',
            'from_time'        => 'required|array',
            'from_time.*'      => 'required|string',
            'to_time'          => 'required|array',
            'to_time.*'        => 'required|string',
            'max_client'       => 'required|array',
            'max_client.*'     => 'required|integer',
            'image'            => 'nullable|image|mimes:jpeg,png,jpg,gif,webp|max:2048',
            'preview'            => 'nullable',
            'preview.*'            => 'nullable',
        ]);

        if ($validator->fails()) {
            $error = ['error' => [$validator->errors()->all()]];
            return ApiResponse::onlyValidation($error);
        }

        // Extract validated data
        $validated = $validator->validate();


        $validated['slug'] = Str::uuid();
        $validated['area_id'] = $validated['area'];
        $validated['vendor_id'] = auth()->id();

        $validated['manager_id']     = $validated['manager_id'];

        $managerId =  $validated['manager_id'];

        $validated['active_status']  = GlobalConst::STATUSUNFREEZE;
        $validated['status']          = GlobalConst::STATUSPENDING;

        // Check for duplicate parlour
        if (ParlourList::where('contact', $validated['contact'])->exists()) {
            $error = ['error' => [__('Salon already exists')]];
            return ApiResponse::error($error);
        }

        // Handle image upload
        if ($request->hasFile('image')) {
            $image = $request->file('image');
            $imageName = Str::uuid() . '.' . $image->getClientOriginalExtension();
            $image->move(public_path('frontend/images/site-section'), $imageName);
            $validated['image'] = $imageName;
        }

        $service_name = $validated['service_name'];

        $price = $validated['price'];
        $stuff_name     = $validated['stuff_id'];
        $from_time = $validated['from_time'];
        $to_time = $validated['to_time'];
        $max_client = $validated['max_client'];
        $basic_setting = BasicSettings::first();
        if ($basic_setting->min_stuff) {
            if (count($stuff_name) < $basic_setting->min_stuff) {
                $message =  ['error' => [__('Minimum Number of Stuff is' . $basic_setting->min_stuff . '.')]];
                return ApiResponse::onlyError($message);
            }
        }

        $validated = Arr::except($validated, [
            'service_name',
            'price',
            'from_time',
            'to_time',
            'max_client',
            'area',
            'stuff_id'
        ]);

        try {
            $parlour_list = ParlourList::create($validated);

            if ($request->hasFile('preview')) {
                $images = $request->file('preview');
                foreach ($images as $image) {
                    $imageName = Str::uuid() . '.' . $image->getClientOriginalExtension();
                    $image->move(public_path('frontend/images/site-section'), $imageName);

                    ParlourImage::create([
                        'parlour_lists_id' => $parlour_list->id,
                        'image_path' => $imageName,
                    ]);
                }
            }
            if (count($from_time) > 0) {
                $days_schedule = [];
                foreach ($from_time as $key => $day_id) {
                    $days_schedule[] = [
                        'parlour_list_id' => $parlour_list->id,
                        'from_time' => $from_time[$key],
                        'to_time' => $to_time[$key],
                        'max_client' => $max_client[$key],
                        'created_at' => now(),
                    ];
                }
                ParlourListHasSchedule::insert($days_schedule);
            }

            Manager::where('id', $managerId)->update([
                'assign_status' => true,
            ]);


            if (count($service_name) > 0) {
                $services = [];
                foreach ($service_name as $key => $day_id) {

                    $services[] = [
                        'parlour_list_id' => $parlour_list->id,
                        'service_name' => $service_name[$key],
                        'price' => $price[$key],
                        'created_at' => now(),
                    ];
                }
                ParlourHasService::insert($services);
            }
            if (count($stuff_name) > 0) {
                foreach ($stuff_name as $key => $stuff_id) {
                    ParlourHasStuff::where('id', $stuff_id)->update([
                        'parlour_list_id' => $parlour_list->id,
                        'status'          => GlobalConst::STATUSASSIGN,
                        'updated_at'      => now(),
                    ]);
                }
            }

            $message =  ['success' => [__('Salon created successfully')]];
            return ApiResponse::onlySuccess($message);
        } catch (Exception $e) {
            $message =  ['error' => [__('Something went wrong! Please try again')]];
            return ApiResponse::onlyError($message);
        }
    }

    public function area()
    {

        $area  = Area::get();

        $data = [
            'data'               => $area
        ];

        $message =  ['success' => [__('Salon List')]];
        return ApiResponse::success($message, $data);
    }



    /**
     * Delete parlour list via API.
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function delete(Request $request)
    {
        // Validate the request
        $validator = Validator::make($request->all(), [
            'target' => 'required|numeric',
        ]);

        if ($validator->fails()) {
            $error = ['error' => [$validator->errors()->all()]];
            return ApiResponse::onlyValidation($error);
        }

        // Find the parlour list
        $parlour_list = ParlourList::find($request->target);
        $manager  = Manager::find($parlour_list->manager_id);

        if (!$parlour_list) {
            $message = ['success' => [__('No Salon found')]];
            return ApiResponse::success($message, []);
        }

        try {
            $parlour_list->delete();
            $manager->delete();

            $message = ['success' => [__('Salon Deleted Successfully!')]];
            return ApiResponse::success($message, []);
        } catch (Exception $e) {

            $message = ['error' => [__('Something went wrong! Please try again')]];
            return ApiResponse::onlyError($message);
        }
    }


    public function update(Request $request, $slug)
    {

        $parlour_list = ParlourList::where('slug', $slug)->first();

        $validator = Validator::make($request->all(), [
            'area'             => 'required',
            'name'             => 'required|string|max:50',
            'manager_id'       => 'nullable|integer',
            'experience'       => 'required|string|max:100',
            'speciality'       => 'nullable',
            'contact'          => 'required',
            'address'          => 'nullable',
            'off_days'         => 'required|string',
            'number_of_dates'  => 'required|integer',
            'stuff_id'         => 'nullable|array',
            'stuff_id.*'       => 'nullable|string',
            'service_name'     => 'required|array',
            'service_name.*'   => 'required|string',
            'price'            => 'required|array',
            'price.*'          => 'required|string',
            'from_time'        => 'required|array',
            'from_time.*'      => 'required|string',
            'to_time'          => 'required|array',
            'to_time.*'        => 'required|string',
            'max_client'       => 'required|array',
            'max_client.*'     => 'required|integer',
            'image'            => 'nullable',
            'preview'            => 'nullable',
            'preview.*'            => 'nullable',
        ]);

        if ($validator->fails()) {
            $error = ['error' => [$validator->errors()->all()]];
            return ApiResponse::onlyValidation($error);
        }

        $validated = $validator->validate();

        $validated['area_id'] = $validated['area'];

        $validated['manager_id']     = $validated['manager_id'];

        $managerId =  $validated['manager_id'];


        Manager::where('id', $managerId)->update([
            'assign_status' => true,
        ]);

        if (ParlourList::where('contact', $validated['contact'])->where('id', '!=', $parlour_list->id)->exists()) {
            $error = ['error' => [__('Salon already exists')]];
            return ApiResponse::onlyValidation($error);
        }

        if ($request->hasFile('image')) {
            $image = $request->file('image');
            $imageName = Str::uuid() . '.' . $image->getClientOriginalExtension();
            $image->move(public_path('frontend/images/site-section'), $imageName);
            $validated['image'] = $imageName;
        }

        $service_name = $validated['service_name'];
        $stuff_name     = $validated['stuff_id'];
        $basic_setting = BasicSettings::first();
        if ($basic_setting->min_stuff) {
            if (count($stuff_name) < $basic_setting->min_stuff) {
                $message =  ['error' => [__('Minimum Number of Stuff is' . $basic_setting->min_stuff . '.')]];
                return ApiResponse::onlyError($message);
            }
        }
        $price = $validated['price'];
        $from_time = $validated['from_time'];
        $to_time = $validated['to_time'];
        $max_client = $validated['max_client'];
        $validated = Arr::except($validated, [
            'service_name',
            'price',
            'from_time',
            'to_time',
            'max_client',
            'area',
            'stuff_id'
        ]);

        try {
            $parlour_list->update($validated);
              if ($request->hasFile('preview')) {
                $images = $request->file('preview');


                foreach ($images as $image) {
                    $imageName = Str::uuid() . '.' . $image->getClientOriginalExtension();
                    $image->move(public_path('frontend/images/site-section'), $imageName);

                    ParlourImage::create([
                        'parlour_lists_id' => $parlour_list->id,
                        'image_path' => $imageName,
                    ]);
                }
            }

            $existing_schedules = $parlour_list->schedules()->pluck('id')->all();
            $processed_schedule_ids = [];

            foreach ($from_time as $key => $value) {
                $scheduleData = [
                    'from_time'     => $from_time[$key],
                    'to_time'       => $to_time[$key],
                    'max_client'    => $max_client[$key],
                    'updated_at'    => now(),
                ];

                if (isset($existing_schedules[$key])) {
                    ParlourListHasSchedule::where('id', $existing_schedules[$key])->update($scheduleData);
                    $processed_schedule_ids[] = $existing_schedules[$key];
                } else {
                    $scheduleData['parlour_list_id'] = $parlour_list->id;
                    $scheduleData['created_at'] = now();
                    $new_schedule = ParlourListHasSchedule::create($scheduleData);
                    $processed_schedule_ids[] = $new_schedule->id;
                }
            }

            $removed_schedules = array_diff($existing_schedules, $processed_schedule_ids);
            if (!empty($removed_schedules)) {
                ParlourListHasSchedule::whereIn('id', $removed_schedules)->delete();
            }

            $existing_services = $parlour_list->services()->pluck('id')->all();
            $processed_service_ids = [];

            foreach ($service_name as $key => $value) {
                $serviceData = [
                    'service_name'  => $service_name[$key],
                    'price'         => $price[$key],
                    'updated_at'    => now(),
                ];

                if (isset($existing_services[$key])) {
                    ParlourHasService::where('id', $existing_services[$key])->update($serviceData);
                    $processed_service_ids[] = $existing_services[$key];
                } else {
                    $serviceData['parlour_list_id'] = $parlour_list->id;
                    $serviceData['created_at'] = now();
                    $new_service = ParlourHasService::create($serviceData);
                    $processed_service_ids[] = $new_service->id;
                }
            }

            $removed_services = array_diff($existing_services, $processed_service_ids);
            if (!empty($removed_services)) {
                ParlourHasService::whereIn('id', $removed_services)->delete();
            }

            if (count($stuff_name) > 0) {
                foreach ($stuff_name as $key => $stuff_id) {
                    ParlourHasStuff::where('id', $stuff_id)->update([
                        'parlour_list_id' => $parlour_list->id,
                        'status'          => GlobalConst::STATUSASSIGN,
                        'updated_at'      => now(),
                    ]);
                }
            }
        } catch (Exception $e) {
            $message = ['error' => [__('Something went wrong! Please try again')]];
            return ApiResponse::onlyError($message);
        }

        $message = ['success' => [__('Salon updated successfully')]];
        return ApiResponse::onlySuccess($message);
    }


    /**
     * status update parlour  via API.
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function statusUpdate(Request $request)
    {
        // Validate the request
        $validator = Validator::make($request->all(), [
            "parlour_id"  => "required|numeric",
            'active_status' => 'required|numeric',
        ]);

        if ($validator->fails()) {
            $message = ['success' => [__('invalid Request Data')]];
            return ApiResponse::success($message, []);
        }

        // Find the parlour list
        $parlour_list = ParlourList::find($request->parlour_id);

        if (!$parlour_list) {
            $message = ['success' => [__('no Salon found')]];
            return ApiResponse::success($message, []);
        }

        try {
            $parlour_list->update([
                'active_status' => $request->active_status,
            ]);
            $message = ['success' => [__('Salon Status Updated')]];
            return ApiResponse::success($message, []);
        } catch (Exception $e) {
            $message = ['error' => [__('Something went wrong! Please try again')]];
            return ApiResponse::onlyError($message);
        }
    }
}
