<?php
namespace App\Http\Controllers\api\v1;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\UserBlock;
use App\Models\UserConnection;
use App\Models\UserReport;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class SearchController extends Controller
{
    public function __construct(Request $request)
    {
        if (isset($request->lang)) {
            \App::setLocale($request->lang);
        }
        $this->lang = \App::getLocale();
    }
   private function validateAccesToken($access_token)
    {
        $user = User::where(['user_access_token' => $access_token])->first();
        if (!$user) {
            http_response_code(401);
            echo json_encode([
                'status' => (string) 0,
                'message' => 'Invalid access token',
                'oData' => (object) [],
                'errors' => (object) [],
            ]);
            exit();
        }
        if ($user->status != 1) {
            http_response_code(401);
            echo json_encode([
                'status' => (string) 0,
                'message' => 'User is not active',
                'oData' => (object) [],
                'errors' => (object) [],
            ]);
            exit();
        }
        return $user;
    }
    public function search(Request $request)
    {
        $status = '0';
        $message = '';
        $errors = [];
        $o_data = [];
        $validator = Validator::make(
            $request->all(),
            [
                'education_id' => 'nullable|array',
                'sect_id' => 'nullable|array',
                'keyword' => 'nullable',
                'marital_status_id' => 'nullable|array',
                'activity_ids.*' => 'nullable|array',
                'activity_ids.*' => 'nullable|exists:activities,id',
                'age_from' => 'nullable',
                'age_to' => 'nullable',
                'height_to_ft' => 'nullable',
                'height_to_cm' => 'nullable',
                'height_from_ft' => 'nullable',
                'height_from_cm' => 'nullable',
                'access_token'=>'required'
            ]
        );
        if ($validator->fails()) {
            return response()->json([
                'status' => $status,
                'message' => 'Validation error occurred',
                'errors' => $validator->errors(),
                'oData' => $o_data,
            ]);
        }

          $user = $this->validateAccesToken($request->access_token);
        if (empty($user)) {
            $message = trans('validation.invalid_user');
            return response()->json(
                [
                    'status' => '0',
                    'message' => $message,
                    'error' => (object) [],
                ],
                401,
            );
        }

        
        $limit = $request->limit ?? 10;
        $offset = isset($request->page) ? ($request->page - 1) * $limit : 0;
        $userId=$user->id;
        $query = User::with(['children', 'preference','nationality','emirate', 'country', 'images', 'details.sect', 'details.education', 'details.profession', 'details.maritalStatus', 'details.dressCode',  'plan', 'sports.sport', 'activities.activity', 'known_languages.language', 'notification_settings','geneticDiseases.geneticDisease','geneticDiseases.geneticDiseaseVariant.geneticDiseaseVariant'])->where('users.id','!=',$user->id)
        ->when($request->keyword, function ($query) use ($request) {
        $keyword = $request->keyword;
        $query->where(function ($q) use ($keyword) {
            $q->where('name', 'LIKE', "%$keyword%")
              ->orWhere('email', 'LIKE', "%$keyword%")
              ->orWhere('phone', 'LIKE', "%$keyword%")

              // User details
              ->orWhereHas('details', function ($q2) use ($keyword) {
                  $q2->where('about', 'LIKE', "%$keyword%");
              })

              // Education
              ->orWhereHas('details.education', function ($q3) use ($keyword) {
                  $q3->where('name', 'LIKE', "%$keyword%");
              })

              // Marital Status
              ->orWhereHas('maritalStatuses.maritalStatuses', function ($q4) use ($keyword) {
                  $q4->where('name', 'LIKE', "%$keyword%");
              })

              // Activities
              ->orWhereHas('activities.activity', function ($q5) use ($keyword) {
                  $q5->where('name', 'LIKE', "%$keyword%");
              })

              // Sports
              ->orWhereHas('sports.sport', function ($q7) use ($keyword) {
                  $q7->where('name', 'LIKE', "%$keyword%");
              });
        });
    });
        // Filter by related user_details fields
        $query->whereHas('details', function ($q) use ($request) {
            if ($request->filled('education_id')) {
                $q->whereIn('education_id', $request->education_id);
            }
            if ($request->filled('sect_id')) {
                $q->whereIn('sect_id', $request->sect_id);
            }
            if ($request->filled('marital_status_id')) {
                $q->whereIn('marital_status_id', $request->marital_status_id);
            }
            if ($request->filled('height_from_cm') && $request->filled('height_to_cm')) {
                $q->whereBetween('height_cm', [$request->height_from_cm, $request->height_to_cm]);
            }
            if ($request->filled('height_from_ft') && $request->filled('height_to_ft')) {
                $q->whereBetween('height_ft', [$request->height_from_ft, $request->height_to_ft]);
            }
        });
        // Age filter (from dob in users table)
        if ($request->filled('age_from') && $request->filled('age_to')) {
            $today = \Carbon\Carbon::today();
            $dob_from = $today->copy()->subYears($request->age_to)->startOfDay(); // Older
            $dob_to = $today->copy()->subYears($request->age_from)->endOfDay(); // Younger
            $query->whereDate('users.dob','>=',$dob_from)->whereDate('dob','<=',$dob_to);
        }
           if ($request->filled('activity_ids') && is_array($request->activity_ids)) {
        $query->whereHas('syncactivities', function ($q) use ($request) {
            $q->whereIn('activity_id', $request->activity_ids);
        });
    }

        // Get users with eager loaded details
        $users = $query->where('hide_on_search','!=',1)
                ->when($user->not_show_over_aged,function($q) use ($user){
                    $dob=$user->dob;
                 $q->whereDate('users.dob','>=',$dob);
                })->where('users.gender','!=',$user->gender)            
           ->leftJoin('user_requests as ur_sent', function ($join) use ($userId) {
        $join->on('users.id', '=', 'ur_sent.receiver_id')
             ->where('ur_sent.sender_id', '=', $userId);
    })
    ->leftJoin('user_requests as ur_received', function ($join) use ($userId) {
        $join->on('users.id', '=', 'ur_received.sender_id')
             ->where('ur_received.receiver_id', '=', $userId);
    })
    ->leftJoin('user_blocks as ub_me', function ($join) use ($userId) {
        $join->on('users.id', '=', 'ub_me.blocked_user_id')
             ->where('ub_me.user_id', '=', $userId);
    })
    ->leftJoin('user_blocks as ub_other', function ($join) use ($userId) {
        $join->on('users.id', '=', 'ub_other.user_id')
             ->where('ub_other.blocked_user_id', '=', $userId);
    })
    ->leftJoin('user_reports as ur_me', function ($join) use ($userId) {
        $join->on('users.id', '=', 'ur_me.reported_user_id')
             ->where('ur_me.reporter_id', '=', $userId);
    })
    ->leftJoin('user_reports as ur_other', function ($join) use ($userId) {
        $join->on('users.id', '=', 'ur_other.reporter_id')
             ->where('ur_other.reported_user_id', '=', $userId);
    })
    ->leftJoin('user_connections as uc1', function ($join) use ($userId) {
        $join->on('users.id', '=', 'uc1.connected_user_id')
             ->where('uc1.user_id', '=', $userId);
    })
    ->leftJoin('user_connections as uc2', function ($join) use ($userId) {
        $join->on('users.id', '=', 'uc2.user_id')
             ->where('uc2.connected_user_id', '=', $userId);
    })
    ->leftJoin('profile_picture_requests as ppr', function ($join) use ($userId) {
        $join->on('users.id', '=', 'ppr.receiver_id')
             ->where('ppr.sender_id', '=', $userId);
    })
    ->whereNull('users.deleted_at')
    ->where('users.deleted',0)

    // Exclude blocked or reported users entirely
    ->whereNull('ub_me.id')
    ->whereNull('ub_other.id')
    ->whereNull('ur_me.id')
    ->whereNull('ur_other.id')

    ->select('users.*')
    ->selectRaw('
        CASE WHEN uc1.id IS NOT NULL OR uc2.id IS NOT NULL THEN 1 ELSE 0 END as is_connected,

        CASE 
            WHEN (ub_me.id IS NULL AND ub_other.id IS NULL AND ur_me.id IS NULL AND ur_other.id IS NULL) 
                 AND ur_sent.id IS NOT NULL 
            THEN 1 ELSE 0 
        END as is_sent,

        CASE 
            WHEN (ub_me.id IS NULL AND ub_other.id IS NULL AND ur_me.id IS NULL AND ur_other.id IS NULL) 
                 AND ur_received.id IS NOT NULL 
            THEN 1 ELSE 0 
        END as is_received,

        0 as is_blocked, -- always zero since blocked users excluded
        0 as am_i_blocked, -- same here

        0 as is_reported, -- reported users excluded
        0 as am_i_reported,

        CASE 
            WHEN (uc1.id IS NOT NULL OR uc2.id IS NOT NULL) 
            THEN COALESCE(uc1.hide_image, 0) ELSE 0 
        END as hide_image_by_current_user,

        CASE 
            WHEN ppr.status = "accepted" 
            THEN "0" ELSE "1"
        END as hide_image_by_target_user
    ')
->when($limit != 0, function ($query) use ($limit, $offset) {
                $query->limit($limit)->offset($offset);
            })
          ->get()
          ->map(function ($u) use ($user) {
                $u = $u->toArray();
                convertNullRelationsToObjects($u);
            return convert_all_elements_to_string($u, true);

          })
            ->toArray();
        $o_data['users'] = $users;
        return response()->json(
            [
                'oData' => $o_data,
                'status' => '1',
                'message' => trans('validation.data_fetched_message'),
            ],
            200,
        );
    }
}
