<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Laravel\Passport\RefreshTokenRepository;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;

use App\Models\User;
use App\Models\Role;
use App\Models\UsersRole;
use App\Models\UsersAddress;
use App\Models\UsersNumber;
use App\Models\UsersProfile;
use App\Models\UsersPicture;
use App\Models\UsersEmergenciesContact;
use App\Models\UsersEmergenciesContactsPicture;
use App\Models\UsersNotification;
use App\Models\UsersFile;
use App\Models\UsersManagersFile;
use App\Models\UsersOwnersFile;
use App\Models\UsersStaffFile;
use App\Models\UsersInteraction;
use App\Models\UsersInteractionsFile;
use App\Models\UsersVehicle;
use App\Models\UsersVehiclesPicture;
use App\Models\UsersVehiclesFile;
use App\Models\UsersChildren;
use App\Models\UsersChildrensPicture;
use App\Models\UsersChildrensFile;
use App\Models\UsersPet;
use App\Models\UsersPetsShot;
use App\Models\UsersPetsPicture;
use App\Models\UsersPetsFile;
use App\Models\UsersOthersLiving;
use App\Models\UsersOthersLivingsPicture;
use App\Models\UsersOthersLivingsFile;
use App\Models\UsersEmployment;
use App\Models\UsersReference;
use App\Models\UsersListingsInfo;
use App\Models\TenantsHistoryLog;
use App\Models\Country;
use App\Models\State;
use App\Models\City;
use App\Models\Ethnicity;
use App\Models\Gender;

use App\Models\Key;
use App\Models\KeysTracking;
use App\Models\KeysTrackingsReplacementFile;

use App\Models\LoanableItem;
use App\Models\LoanableItemsTracking;
use App\Models\LoanableItemsTrackingsReplacementFile;
use App\Models\LoanableItemsTrackingsPicture;

use App\Models\PropertiesParkingSpace;
use App\Models\PropertiesParkingsSpacesHistoryLogs;

use Carbon\Carbon;
use Exception;
use DB;

use App\Libraries\Generic;

class TenantsController extends Controller
{
    
    protected $generic;
    
    public function __construct(){
        
        $this->generic = new Generic();
        
    }

    public function tenant(Request $request)
    {

        // echo "<pre>";
        // print_r($request->all());
        // exit();
        
        $user_id = auth()->user()->id;
        $owner_id = User::getOwnerOfUser($user_id);
        
        if(!User::checkPermission('add-edit-tenant')){
            return response()->json(config('constants.messages.permission_denied'), 400);
            exit();
        }
        
        $tenant_id = (!empty($request->id)) ? $request->id : 0;
        
        $validation_rules = [
            'firstname' => 'required|min:2',
            'lastname' => 'required',
        ];
        
        if(empty($request->id)){
            $validation_rules['email'] = 'required|email|unique:users';
        }
        
        $validator = Validator::make($request->all(), $validation_rules);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 400);
        }
        
        // get old tenant data from database
        $old_tenant = (!empty($tenant_id)) ? User::find($tenant_id) : [];
        $old_tenant_addresses = (!empty($tenant_id)) ? User::find($tenant_id)->addresses->first() : [];
        $old_tenant_numbers = (!empty($tenant_id)) ? User::find($tenant_id)->phoneNumbers->take(3) : [];
        $old_tenant_profile = (!empty($tenant_id)) ? User::find($tenant_id)->profile : [];
        $old_tenant_pictures = (!empty($tenant_id)) ? User::find($tenant_id)->pictures : [];
        
        $update_criteria = [];
        if(!empty($request->id)){
            $update_criteria['id'] = $request->id;
        }
        else{
            $update_criteria['id'] = 0;
        }
        
        $data = [
            'enable_portal' => $request->user_prefix_id ?? 0,
            'send_notifications' => $request->send_notifications ?? 0,
            'user_prefix_id' => $request->user_prefix_id ?? null,
            'firstname' => $request->firstname,
            'middlename' => $request->middlename ?? '',
            'lastname' => $request->lastname,
            'user_suffix_id' => $request->user_suffix_id ?? null,
            'uuid' => (string) Str::uuid(),
            'email' => $request->email,
            'password' => '$2y$10$Twa0QndbXF9emiDUktiGr.UFKL6crqjyj5AWlzR146HEuvDpHnaM.',
            'about_me' => $request->about_me ?? '',
            'website_id' => 1,     // indicate that this user is from property website
        ];
        
        if(!$tenant_id){  // first time when adding tenant
            $data['system_id'] = 'M-'.random_int(1000000000, 9999999999);
            $data['owner_id'] = $owner_id;
            $data['creator_id'] = $user_id;
        }
        
        // echo $tenant_id;
        // exit();
        
        $user = User::updateOrCreate(
            $update_criteria,
            $data
        );
        
        $tenant_id = $user->id;
        
        // set this user role
        // this user could be prospect as well as both role are very close to each other
        UsersRole::create([
            'user_id' => $tenant_id,
            'role_id' => $request->user_role_type_id,   // tenants role id
        ]);
        
        // addresses
        $addresses = $request->addresses ?? [];

        foreach($addresses as $a){
            
            $update_criteria = [];
            if(!empty($b['id'])){
                $update_criteria['id'] = $a['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersAddress::updateOrCreate($update_criteria, [
                'user_id' => $tenant_id,
                'address_line1' => $a['address_line1'] ?? '',
                'address_line2' => $a['address_line2'] ?? '',
                'city' => $a['city'] ?? '',
                'state' => $a['state'] ?? '',
                'country' => $a['country'] ?? '',
                'zip_code' => $a['zip_code'] ?? ''
            ]);
            
        }
        
        // numbers
        $numbers = $request->numbers ?? [];

        foreach($numbers as $n){
            
            $update_criteria = [];
            if(!empty($b['id'])){
                $update_criteria['id'] = $n['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersNumber::updateOrCreate($update_criteria, [
                'user_id' => $tenant_id,
                'country_code' => $n['phone_country_code'] ?? '',
                'phone_number' => $n['phone_number'] ?? '',
                'number_type' => $n['number_type'] ?? '',
            ]);
            
        }
        
        // user profile
        
        $update_criteria = [];
        $update_criteria['user_id'] = $tenant_id;
        
        $user = UsersProfile::updateOrCreate(
            $update_criteria,
            [
                'user_id' => $tenant_id,
                'enable_portal' => $request->enable_portal ?? 0,
                'send_notifications' => $request->send_notifications ?? 0,
                'ssn' => $request->ssn ?? '',
                'date_of_birth' => $request->date_of_birth ?? '',
                'dln_id' => $request->dln_id ?? '',
                'dl_id_picture' => $request->dl_id_picture ?? '',
                'dln_id_issue_country' => $request->dln_id_issue_country ?? '',
                'dln_id_issue_state' => $request->dln_id_issue_state ?? '',
                'dln_id_issue_notes' => $request->dln_id_issue_notes ?? '',
                'gender_id' => $request->gender_id ?? null,
                'ethnicity_id' => $request->ethnicity_id ?? null,
                'smoker' => $request->smoker ?? 0,
                'smoker_notes' => $request->smoker_notes ?? '',
                'known_allergies' => $request->known_allergies ?? '',
                'other_emergency_info' => $request->other_emergency_info ?? '',
                'user_notes' => $request->user_notes ?? '',
                'user_staff_notes' => $request->user_staff_notes ?? '',
                'user_manager_notes' => $request->user_manager_notes ?? '',
                'user_owner_notes' => $request->user_owner_notes ?? '',
                'moveout_address1' => $request->moveout_address1 ?? '',
                'moveout_address2' => $request->moveout_address2 ?? '',
                'moveout_country' => $request->moveout_country ?? '',
                'moveout_city' => $request->moveout_city ?? '',
                'moveout_state' => $request->moveout_state ?? '',
                'moveout_zip_code' => $request->moveout_zip_code ?? '',
                'moveout_number' => $request->moveout_number ?? '',
                'moveout_number_type' => $request->moveout_number_type ?? '',
                'moveout_email' => $request->moveout_email ?? '',
                'moveout_date' => $request->moveout_date ?? '',
                'moveout_reason_id' => $request->moveout_reason_id ?? null
            ]
        );
        
        // pictures
        $pictures = $request->pictures ?? [];

        foreach($pictures as $p){
            
            $update_criteria = [];
            if(!empty($p['id'])){
                $update_criteria['id'] = $p['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersPicture::updateOrCreate($update_criteria, [
                'picture' => $p['picture'],
                'is_cover' => $p['is_cover'] ?? 0,
                'order_number' => $p['order_number'] ?? 1,
                'user_id' => $tenant_id
            ]);
        }
        
        // emergencies contacts
        $contacts = $request->emergencies_contacts ?? [];

        foreach($contacts as $c){
            
            $update_criteria = [];
            if(!empty($c['id'])){
                $update_criteria['id'] = $c['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            $user_emergency_contact  = UsersEmergenciesContact::updateOrCreate($update_criteria, [
                'firstname' => $c['firstname']  ?? '',
                'lastname' => $c['lastname']  ?? '',
                'user_relationship_id' => $c['user_relationship_id']  ?? null,
                'other_user_relationship' => $c['other_user_relationship']  ?? '',
                'email' => $c['email']  ?? '',
                'address_line1' => $c['address_line1']  ?? '',
                'address_line2' => $c['address_line2']  ?? '',
                'country' => $c['country']  ?? '',
                'city' => $c['city']  ?? '',
                'state' => $c['state']  ?? '',
                'zip_code' => $c['zip_code']  ?? '',
                'number1' => $c['number1']  ?? '',
                'number1_type' => $c['number1_type'] ?? '',
                'number2' => $c['number2'] ?? '',
                'number2_type' => $c['number2_type'] ?? '',
                'number3' => $c['number3'] ?? '',
                'number3_type' => $c['number3_type'] ?? '',
                'user_id' => $tenant_id,
            ]);
            
            $user_emergency_contact_id = $user_emergency_contact->id;
            
            $pictures = $c['pictures'];
            
            foreach($pictures as $p){
                
                $update_criteria = [];
                if(!empty($p['id'])){
                    $update_criteria['id'] = $p['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersEmergenciesContactsPicture::updateOrCreate($update_criteria, [
                    'user_emergency_contact_id' => $user_emergency_contact_id,
                    'picture' => $p['picture'],
                    'order_number' => $p['order_number']
                ]);
                
            }
            
        }
        
        // notifications
        $notifications = $request->notifications ?? [];

        foreach($notifications as $n){
            
            $update_criteria = [];
            if(!empty($n['id'])){
                $update_criteria['id'] = $n['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            $date = (!empty($n['posting_date'])) ? $this->generic->formatInputDate($n['posting_date']) : date('d-m-Y');
            $time = $n['posting_time'] ?? date('h:m:i A');
            $str = strtotime($date.' '.$time);
            
            UsersNotification::updateOrCreate($update_criteria, [
                'title' => $n['title'] ?? '',
                'notification' => $n['notification'] ?? '',
                'is_popup_notification' => $n['is_popup_notification'] ?? 0,
                'posting_date' => $date,
                'posting_time' => $time,
                'posting_date_time_str' => $str,
                'user_id' => $tenant_id
            ]);
            
        }
        
        // files
        $files = $request->user_files ?? [];

        foreach($files as $f){
            
            $update_criteria = [];
            if(!empty($f['id'])){
                $update_criteria['id'] = $f['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersFile::updateOrCreate($update_criteria, [
                'title' => $f['title'] ?? '',
                'file' => $f['file'],
                'user_id' => $tenant_id,
            ]);
        }
        
        // staff files
        $staff_files = $request->user_staff_files ?? [];

        foreach($staff_files as $f){
            
            $update_criteria = [];
            if(!empty($f['id'])){
                $update_criteria['id'] = $f['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersStaffFile::updateOrCreate($update_criteria, [
                'user_id' => $tenant_id,
                'title' => $f['title'] ?? '',
                'file' => $f['file']
            ]);
            
        }
        
        // managers files
        $manager_files = $request->user_manager_files ?? [];

        foreach($manager_files as $f){
            
            $update_criteria = [];
            if(!empty($f['id'])){
                $update_criteria['id'] = $f['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersManagersFile::updateOrCreate($update_criteria, [
                'user_id' => $tenant_id,
                'title' => $f['title'] ?? '',
                'file' => $f['file']
            ]);
            
        }
        
        // owner files
        $owner_files = $request->user_owner_files ?? [];

        foreach($owner_files as $f){
            
            $update_criteria = [];
            if(!empty($f['id'])){
                $update_criteria['id'] = $f['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersOwnersFile::updateOrCreate($update_criteria, [
                'user_id' => $tenant_id,
                'title' => $f['title'] ?? '',
                'file' => $f['file']
            ]);
            
        }
        
        // interactions
        $interactions = $request->interactions ?? [];

        foreach($interactions as $i){
            
            $update_criteria = [];
            if(!empty($i['id'])){
                $update_criteria['id'] = $i['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            $date = (!empty($i['date'])) ? $this->generic->formatInputDate($i['date']) : date('d-m-Y');
            $time = $i['time'] ?? date('h:m:i A');
            
            $interaction = UsersInteraction::updateOrCreate($update_criteria, [
                'date' => $date,
                'time' => $time,
                'interaction_type_id' => $i['interaction_type_id'] ?? null,
                'other_type_description' => $i['other_type_description'] ?? '',
                'notes' => $i['notes'] ?? '',
                'who_meet_user_id' => $i['who_meet_user_id'] ?? null,
                'user_id' => $tenant_id
            ]);
            
            $interaction_id = $interaction->id;
            
            $files = $i['files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersInteractionsFile::updateOrCreate($update_criteria, [
                    'user_interaction_id' => $interaction_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ]);
                
            }
            
        }
        
        // keys trackings
        $keys_trackings = $request->keys_trackings ?? [];

        foreach($keys_trackings as $k){
            
            $update_criteria = [];
            if(!empty($k['id'])){
                $update_criteria['id'] = $k['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }

            $data = [
                'assigned_verification_picture' => $k['assigned_verification_picture'] ?? '',
                'assigned_verification_signature' => $k['assigned_verification_signature'] ?? '',
                'is_lost_damaged' => $k['is_lost_damaged'] ?? 0,
                'lost_damaged_date' => $k['lost_damaged_date'] ?? '',
                'send_replacement_cost_invoice' => $k['send_replacement_cost_invoice'] ?? 0,
                'replacement_additional_fees' => $k['replacement_additional_fees'] ?? 0,
                'replacement_reason' => $k['replacement_reason'] ?? '',
                'is_returned' => $k['is_returned'] ?? 0,
                'returned_date' => $k['returned_date'] ?? '',
                'returned_verification_picture' => $k['returned_verification_picture'] ?? '',
                'returned_verification_signature' => $k['returned_verification_signature'] ?? '',
                'notes' => $k['notes'] ?? ''
            ];
            
            if(empty($k['id'])){  // first time giving key to tenant
                $data['key_id'] = $k['key_id'];
                $data['assigned_to'] = $tenant_id;
                $data['assigned_by'] = $user_id;
                $data['assigned_date'] = $k['assigned_date'] ?? '';
            }
            
            $key_tracking = KeysTracking::updateOrCreate(
                $update_criteria,
                $data
            );
            
            $key_tracking_id = $key_tracking->id;
            
            $replacement_files = $k['replacement_files'];
            
            foreach($replacement_files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                KeysTrackingsReplacementFile::updateOrCreate($update_criteria, [
                    'key_tracking_id' => $key_tracking_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ]);
                
            }
            
            // update key stats
            $this->generic->updateKeyStats($key_tracking->key_id);
            
        }
        
        // loanable items trackings
        $loanable_items_trackings = $request->loanable_items_trackings ?? [];

        foreach($loanable_items_trackings as $l){
            
            $update_criteria = [];
            if(!empty($l['id'])){
                $update_criteria['id'] = $l['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }

            $data = [
                'assigned_verification_picture' => $l['assigned_verification_picture'] ?? '',
                'assigned_verification_signature' => $k['assigned_verification_signature'] ?? '',
                'is_lost_damaged' => $l['is_lost_damaged'] ?? 0,
                'lost_damaged_date' => $l['lost_damaged_date'] ?? '',
                'send_replacement_cost_invoice' => $l['send_replacement_cost_invoice'] ?? 0,
                'replacement_additional_fees' => $l['replacement_additional_fees'] ?? 0,
                'replacement_reason' => $l['replacement_reason'] ?? '',
                'is_returned' => $l['is_returned'] ?? 0,
                'returned_date' => $l['returned_date'] ?? '',
                'returned_verification_picture' => $l['returned_verification_picture'] ?? '',
                'returned_verification_signature' => $k['returned_verification_signature'] ?? '',
                'notes' => $l['notes'] ?? ''
            ];
            
            if(empty($l['id'])){  // first time giving key to tenant
                $data['loanable_item_id'] = $l['loanable_item_id'];
                $data['loanable_item_serial_number_id'] = $l['loanable_item_serial_number_id'];
                $data['assigned_to'] = $tenant_id;
                $data['assigned_by'] = $user_id;
                $data['assigned_date'] = $l['assigned_date'] ?? '';
            }
            
            $loanable_item_tracking = LoanableItemsTracking::updateOrCreate(
                $update_criteria,
                $data
            );
            
            $loanable_item_tracking_id = $loanable_item_tracking->id;
            
            
            // replacement files
            $replacement_files = $l['replacement_files'];
            
            foreach($replacement_files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                LoanableItemsTrackingsReplacementFile::updateOrCreate($update_criteria, [
                    'loanable_item_tracking_id' => $loanable_item_tracking_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ]);
                
            }
            
            // item given pictures
            $pictures = $l['item_given_pictures'];
            
            foreach($pictures as $p){
                
                $update_criteria = [];
                if(!empty($p['id'])){
                    $update_criteria['id'] = $p['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                LoanableItemsTrackingsPicture::updateOrCreate($update_criteria, [
                    'loanable_item_tracking_id' => $loanable_item_tracking_id,
                    'picture' => $p['picture'],
                    'is_given' => 1,
                    'is_return' => 0,
                ]);
                
            }
            
            // item given pictures
            $pictures = $l['item_return_pictures'];
            
            foreach($pictures as $p){
                
                $update_criteria = [];
                if(!empty($p['id'])){
                    $update_criteria['id'] = $p['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                LoanableItemsTrackingsPicture::updateOrCreate($update_criteria, [
                    'loanable_item_tracking_id' => $loanable_item_tracking_id,
                    'picture' => $p['picture'],
                    'is_given' => 0,
                    'is_return' => 1,
                ]);
                
            }
            
            // update key stats
            $this->generic->updateLoanableItemStats($loanable_item_tracking->loanable_item_id);
            
        }
        
        // vehicles
        $vehicles = $request->vehicles ?? [];
        
        // print_r($vehicles);
        
        
        foreach($vehicles as $v){
            
            $update_criteria = [];
            if(!empty($v['id'])){
                $update_criteria['id'] = $v['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            $vehicle = UsersVehicle::updateOrCreate($update_criteria, [
                'status' => $v['status'] ?? 0,
                'year' => $v['year'] ?? '',
                'vehicle_make_id' => $v['vehicle_make_id'] ?? null,
                'vehicle_model_id' => $v['vehicle_model_id'] ?? null,
                'color' => $v['color'] ?? '',
                'vin' => $v['vin'] ?? '',
                'license_plate' => $v['license_plate'] ?? '',
                'assign_parking_space' => $v['assign_parking_space'] ?? 0,
                'property_parking_space_id' => $v['property_parking_space_id'] ?? null,
                'notes' => $v['notes'] ?? '',
                'user_id' => $tenant_id
            ]);
            
            $vehicle_id = $vehicle->id;
            
            
            $pictures = $v['pictures'];
            
            foreach($pictures as $p){
                
                $update_criteria = [];
                if(!empty($p['id'])){
                    $update_criteria['id'] = $p['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersVehiclesPicture::updateOrCreate($update_criteria, [
                    'user_vehicle_id' => $vehicle_id,
                    'picture' => $p['picture'],
                    'order_number' => $p['order_number']
                ]);
                
            }
            
            $files = $v['files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersVehiclesFile::updateOrCreate($update_criteria, [
                    'user_vehicle_id' => $vehicle_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ]);
                
            }
            
            // parking space assignment work
            $is_parking_space_assigned = $v['assign_parking_space'] ?? 0;
            $property_parking_space_id = $v['property_parking_space_id'] ?? null;
            
            if($is_parking_space_assigned == 1){    // update parking space tables accordingly 
                $history_log = PropertiesParkingsSpacesHistoryLogs::where(['property_space_parking_id'=>$property_parking_space_id, 'tenant_id'=>$tenant_id])->first();
                
                if(empty($history_log)){    // if log is empty it means it is new assignment, so create history log
                    PropertiesParkingsSpacesHistoryLogs::create([
                        'property_space_parking_id' => $property_parking_space_id,
                        'tenant_id' => $tenant_id,
                        'unit_id' => null,
                        'start_date' => date('d-m-Y'),
                        'end_date' => ''
                    ]);
                    
                    // now mark parking space as assigned
                    PropertiesParkingSpace::where(['id'=>$property_parking_space_id])->update(['is_assigned'=>1]);
                }
            }
            
        }
        
        // children
        $childrens = $request->childrens ?? [];

        foreach($childrens as $c){
            
            $update_criteria = [];
            if(!empty($c['id'])){
                $update_criteria['id'] = $c['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            $children = UsersChildren::updateOrCreate($update_criteria, [
                'status' => $c['status'] ?? 0,
                'firstname' => $c['firstname'] ?? '',
                'middlename' => $c['middlename'] ?? '',
                'lastname' => $c['lastname'] ?? '',
                'gender_id' => $c['gender_id'] ?? '',
                'date_of_birth' => $c['date_of_birth'] ?? '',
                'public_note' => $c['public_note'] ?? '',
                'private_note' => $c['private_note'] ?? '',
                'user_id' => $tenant_id
            ]);
            
            $children_id = $children->id;
            
            
            $pictures = $c['pictures'];
            
            foreach($pictures as $p){
                
                $update_criteria = [];
                if(!empty($p['id'])){
                    $update_criteria['id'] = $p['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersChildrensPicture::updateOrCreate($update_criteria, [
                    'user_children_id' => $children_id,
                    'picture' => $p['picture'],
                    'order_number' => $p['order_number']
                ]);
                
            }
            
            $files = $c['files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersChildrensFile::updateOrCreate($update_criteria, [
                    'user_children_id' => $children_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => 0
                ]);
                
            }
            
            $files = $c['private_files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersChildrensFile::updateOrCreate($update_criteria, [
                    'user_children_id' => $children_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => 1
                ]);
                
            }
            
        }
        
        // pets
        $pets = $request->pets ?? [];

        foreach($pets as $p){
            
            $update_criteria = [];
            if(!empty($p['id'])){
                $update_criteria['id'] = $p['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            $pet = UsersPet::updateOrCreate($update_criteria, [
                'status' => $p['status'] ?? 0,
                'name' => $p['name'] ?? '',
                'pet_type_id' => $p['pet_type_id'] ?? null,
                'pet_gender_id' => $p['pet_gender_id'] ?? null,
                'breed' => $p['breed'] ?? '',
                'color' => $p['color'] ?? '',
                'weight' => $p['weight'] ?? '',
                'date_of_birth' => $p['date_of_birth'] ?? '',
                'support_animal' => $p['support_animal'] ?? 0,
                'deposit' => $p['deposit'] ?? '',
                'rent' => $p['rent'] ?? '',
                'license' => $p['license'] ?? '',
                'location_of_license' => $p['location_of_license'] ?? '',
                'public_note' => $p['public_note'] ?? '',
                'private_note' => $p['private_note'] ?? '',
                'user_id' => $tenant_id
            ]);
            
            $pet_id = $pet->id;
            
            $shots = $p['shots'];
            
            foreach($shots as $s){
                
                $update_criteria = [];
                if(!empty($s['id'])){
                    $update_criteria['id'] = $s['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersPetsShot::updateOrCreate($update_criteria, [
                    'user_pet_id' => $pet_id,
                    'type' => $s['type'] ?? '',
                    'is_shot_applied' => $s['is_shot_applied'] ?? 0,
                    'applied_date' => $s['applied_date'] ?? '',
                    'expiry_date' => $s['expiry_date'] ?? '',
                    'proof_picture' => $s['proof_picture'] ?? '',
                    'is_approved_by_owner' => $s['is_approved_by_owner'] ?? 0,
                    'is_rejected_by_owner' => $s['is_rejected_by_owner'] ?? 0,
                    'rejected_reason' => $s['rejected_reason'] ?? '',
                    'creator_id' => $user_id
                ]);
                
            }
            
            $pictures = $p['pictures'];
            
            foreach($pictures as $pi){
                
                $update_criteria = [];
                if(!empty($pi['id'])){
                    $update_criteria['id'] = $pi['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersPetsPicture::updateOrCreate($update_criteria, [
                    'user_pet_id' => $pet_id,
                    'picture' => $pi['picture'],
                    'order_number' => $pi['order_number']
                ]);
                
            }
            
            $files = $p['files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersPetsFile::updateOrCreate($update_criteria, [
                    'user_pet_id' => $pet_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => 0
                ]);
                
            }
            
            $files = $c['private_files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersPetsFile::updateOrCreate($update_criteria, [
                    'user_pet_id' => $pet_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => 1
                ]);
                
            }
            
        }
        
        // other livings
        $other_livings = $request->other_livings ?? [];

        foreach($other_livings as $o){
            
            $update_criteria = [];
            if(!empty($o['id'])){
                $update_criteria['id'] = $o['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            $other_living = UsersOthersLiving::updateOrCreate($update_criteria, [
                'status' => $o['status'] ?? 0,
                'firstname' => $o['firstname'] ?? '',
                'middlename' => $o['middlename'] ?? '',
                'lastname' => $o['lastname'] ?? '',
                'date_of_birth' => $o['date_of_birth'] ?? '',
                'gender_id' => $o['gender_id'] ?? null,
                'user_relationship_id' => $o['user_relationship_id'] ?? null,
                'other_relationship' => $o['other_relationship'] ?? '',
                'additional_deposit' => $o['additional_deposit'] ?? 0,
                'additional_rent' => $o['additional_rent'] ?? 0,
                'reason_for_movein' => $o['reason_for_movein'] ?? '',
                'public_note' => $o['public_note'] ?? '',
                'private_note' => $o['private_note'] ?? '',
                'user_id' => $tenant_id
            ]);
            
            $other_living_id = $other_living->id;
            
            $pictures = $o['pictures'];
            
            foreach($pictures as $p){
                
                $update_criteria = [];
                if(!empty($p['id'])){
                    $update_criteria['id'] = $p['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersOthersLivingsPicture::updateOrCreate($update_criteria, [
                    'user_other_living_id' => $other_living_id,
                    'picture' => $p['picture'],
                    'order_number' => $p['order_number']
                ]);
                
            }
            
            $files = $o['files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersOthersLivingsFile::updateOrCreate($update_criteria, [
                    'user_other_living_id' => $other_living_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => 0
                ]);
                
            }
            
            $files = $c['private_files'];
            
            foreach($files as $f){
                
                $update_criteria = [];
                if(!empty($f['id'])){
                    $update_criteria['id'] = $f['id'];
                }
                else{
                    $update_criteria['id'] = 0;
                }
                
                UsersOthersLivingsFile::updateOrCreate($update_criteria, [
                    'user_other_living_id' => $other_living_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => 1
                ]);
                
            }
            
        }
        
        // employments
        $employments = $request->employments ?? [];
        
        foreach($employments as $e){
            
            $update_criteria = [];
            if(!empty($e['id'])){
                $update_criteria['id'] = $e['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersEmployment::updateOrCreate($update_criteria, [
                'company_name' => $e['company_name'] ?? '',
                'position' => $e['position'] ?? '',
                'annual_salary' => $e['annual_salary'] ?? 0,
                'start_year' => $e['start_year'] ?? '',
                'end_year' => $e['end_year'] ?? '',
                'present' => $e['present'] ?? 0,
                'address_line1' => $e['address_line1'] ?? '',
                'address_line2' => $e['address_line2'] ?? '',
                'country' => $e['country'] ?? '',
                'city' => $e['city'] ?? '',
                'state' => $e['state'] ?? '',
                'zip_code' => $e['zip_code'] ?? '',
                'website' => $e['website'] ?? '',
                'supervisor' => $e['supervisor'] ?? '',
                'number' => $e['number'] ?? '',
                'number_type' => $e['number_type'] ?? '',
                'leaving_reason' => $e['leaving_reason'] ?? '',
                'notes' => $e['notes'] ?? '',
                'user_id' => $tenant_id
            ]);
            
        }
        
        // references
        $references = $request->references ?? [];
        
        foreach($references as $r){
            
            $update_criteria = [];
            if(!empty($r['id'])){
                $update_criteria['id'] = $r['id'];
            }
            else{
                $update_criteria['id'] = 0;
            }
            
            UsersReference::updateOrCreate($update_criteria, [
                'firstname' => $r['firstname'] ?? '',
                'lastname' => $r['lastname'] ?? '',
                'user_reference_relationship_id' => $r['user_reference_relationship_id'] ?? null,
                'other_reference_relationship' => $r['other_reference_relationship'] ?? '',
                'number1' => $r['number1'] ?? '',
                'number1_type' => $r['number1_type'] ?? '',
                'number2' => $r['number2'] ?? '',
                'number2_type' => $r['number2_type'] ?? '',
                'number3' => $r['number3'] ?? '',
                'number3_type' => $r['number3_type'] ?? '',
                'notes' => $r['notes'] ?? '',
                'user_id' => $tenant_id
            ]);
            
        }
        
        // listing informations for tenant own profile
        $update_criteria = [];
        $update_criteria['user_id'] = $tenant_id;
        
        $listings_infos = $request->listings_infos ?? [];
        
        $user = UsersListingsInfo::updateOrCreate(
            $update_criteria,
            [
                'user_id' => $tenant_id,
                'show_listing' => $listings_infos['show_listing'] ?? 0,
                'max_monthly_rent' => $listings_infos['max_monthly_rent'] ?? 0,
                'areas' => $listings_infos['areas'] ?? '',
                'type_id' => $listings_infos['type_id'] ?? null,
                'bedrooms' => $listings_infos['bedrooms'] ?? 0,
                'bathrooms' => $listings_infos['bathrooms'] ?? 0,
                'place_with_id' => $listings_infos['place_with_id']  ?? null,
                'private_bedroom' => $listings_infos['private_bedroom'] ?? 0,
                'private_bathroom' => $listings_infos['private_bathroom'] ?? 0,
                'lgbtq_friendly' => $listings_infos['lgbtq_friendly'] ?? 0,
                'pets_ok' => $listings_infos['pets_ok'] ?? 0,
                'desired_features' => $listings_infos['desired_features'] ?? ''
            ]
        );
        
        
        // ------------------------------------------------------------------------------
        // ------------------------- save history logs start ----------------------------
        // ------------------------------------------------------------------------------
        
        $create_log = $request->create_log ?? '';
        
        $old_data = [];
        $new_data = [];
        
        $all_changes = [];
        
        // basic info logs
        $indexes = ['firstname', 'middlename', 'lastname', 'email'];
        foreach($indexes as $i){
            if($create_log[$i]){
                $d = [
                    'user_id' => $tenant_id,
                    'created_by' => $user_id,
                    'field_name' => $i,
                    'old_data' => (!empty($tenant_id) && !empty($old_tenant->$i)) ? $old_tenant->$i : '',
                    'new_data' => $request->$i,
                    'type' => (!empty($tenant_id) && !empty($old_tenant->$i)) ? 'updated' : 'added'
                ];
                TenantsHistoryLog::create($d);
            }
        }
        
        // address logs
        $indexes = ['address_line1', 'address_line2', 'country', 'city', 'state', 'zip_code'];
        foreach($indexes as $i){
            if($create_log[$i]){
                $d = [
                    'user_id' => $tenant_id,
                    'created_by' => $user_id,
                    'field_name' => $i,
                    'old_data' => (!empty($tenant_id) && !empty($old_tenant_addresses->$i)) ? $old_tenant_addresses->$i : '',
                    'new_data' => $request->addresses[0][$i],
                    'type' => (!empty($tenant_id) && !empty($old_tenant_addresses->$i)) ? 'updated' : 'added'
                ];
                TenantsHistoryLog::create($d);
            }
        }
        
        // numbers extra work
        $old_tenant_numbers = (!empty($old_tenant_numbers)) ? $old_tenant_numbers->toArray() : [];
        $db_numbers = [
            'country_code_1' => (isset($old_tenant_numbers[0]['country_code'])) ? $old_tenant_numbers[0]['country_code'] : '',
            'phone_number_1' => (isset($old_tenant_numbers[0]['phone_number'])) ? $old_tenant_numbers[0]['phone_number'] : '',
            'number_type_1' => (isset($old_tenant_numbers[0]['number_type'])) ? $old_tenant_numbers[0]['number_type'] : '',
            'country_code_2' => (isset($old_tenant_numbers[1]['country_code'])) ? $old_tenant_numbers[1]['country_code'] : '',
            'phone_number_2' => (isset($old_tenant_numbers[1]['phone_number'])) ? $old_tenant_numbers[1]['phone_number'] : '',
            'number_type_2' => (isset($old_tenant_numbers[1]['number_type'])) ? $old_tenant_numbers[1]['number_type'] : '',
            'country_code_3' => (isset($old_tenant_numbers[2]['country_code'])) ? $old_tenant_numbers[2]['country_code'] : '',
            'phone_number_3' => (isset($old_tenant_numbers[2]['phone_number'])) ? $old_tenant_numbers[2]['phone_number'] : '',
            'number_type_3' => (isset($old_tenant_numbers[2]['number_type'])) ? $old_tenant_numbers[2]['number_type'] : '',
        ];
        
        $new_numbers = [
            'country_code_1' => (isset($request->numbers[0]['country_code'])) ? $request->numbers[0]['country_code'] : '',
            'phone_number_1' => (isset($request->numbers[0]['phone_number'])) ?$request->numbers[0]['phone_number'] : '',
            'number_type_1' => (isset($request->numbers[0]['number_type'])) ? $request->numbers[0]['number_type'] : '',
            'country_code_2' => (isset($request->numbers[1]['country_code'])) ? $request->numbers[1]['country_code'] : '',
            'phone_number_2' => (isset($request->numbers[1]['phone_number'])) ?$request->numbers[1]['phone_number'] : '',
            'number_type_2' => (isset($request->numbers[1]['number_type'])) ? $request->numbers[1]['number_type'] : '',
            'country_code_3' => (isset($request->numbers[2]['country_code'])) ? $request->numbers[2]['country_code'] : '',
            'phone_number_3' => (isset($request->numbers[2]['phone_number'])) ?$request->numbers[2]['phone_number'] : '',
            'number_type_3' => (isset($request->numbers[2]['number_type'])) ? $request->numbers[2]['number_type'] : '',
        ];
        
        $indexes = ['country_code_1', 'phone_number_1', 'number_type_1', 'country_code_2', 'phone_number_2', 'number_type_2', 'country_code_3', 'phone_number_3', 'number_type_3'];
        foreach($indexes as $i){
            if($create_log[$i]){
                $d = [
                    'user_id' => $tenant_id,
                    'created_by' => $user_id,
                    'field_name' => $i,
                    'old_data' => $db_numbers[$i],
                    'new_data' => $new_numbers[$i],
                    'type' => (!empty($db_numbers[$i])) ? 'updated' : 'added'
                ];
                TenantsHistoryLog::create($d);
            }
        }
        
        // profile changes logs
        $indexes = ['dl_id_picture', 'dln_id', 'dln_id_issue_country', 'dln_id_issue_state', 'ssn', 'gender_id', 'ethnicity_id', 'date_of_birth', 'moveout_address1', 'moveout_address2', 'moveout_country', 'moveout_city', 'moveout_state', 'moveout_zip_code', 'moveout_email', 'moveout_number', 'moveout_number_type'];
        foreach($indexes as $i){
            if($create_log[$i]){
                $d = [
                    'user_id' => $tenant_id,
                    'created_by' => $user_id,
                    'field_name' => $i,
                    'old_data' => (!empty($tenant_id) && !empty($old_tenant_profile->$i)) ? $old_tenant_profile->$i : '',
                    'new_data' => $request->$i ?? '',
                    'type' => (!empty($tenant_id) && !empty($old_tenant_profile->$i)) ? 'updated' : 'added'
                ];
                TenantsHistoryLog::create($d);
            }
        }
        
        // pictures
        $added_pictures = $create_log['pictures']['added'];
        foreach($added_pictures as $p){
            $d = [
                'user_id' => $tenant_id,
                'created_by' => $user_id,
                'field_name' => 'picture',
                'old_data' => '',
                'new_data' => $p,
                'type' => 'added'
            ];
            TenantsHistoryLog::create($d);
        }
        
        $deleted_pictures = $create_log['pictures']['deleted'];
        foreach($deleted_pictures as $p){
            $d = [
                'user_id' => $tenant_id,
                'created_by' => $user_id,
                'field_name' => 'picture',
                'old_data' => $p,
                'new_data' => '',
                'type' => 'deleted'
            ];
            TenantsHistoryLog::create($d);
        }
        
        // ------------------------------------------------------------------------------
        // ------------------------- save history logs end ------------------------------
        // ------------------------------------------------------------------------------
        
        return response()->json(['data' => $tenant_id]);
    }
    
    public function getTenant(Request $request)
    {
        
        $user_id = auth()->user()->id;
        $owner_id = User::getOwnerOfUser($user_id);
        
        // check if permission to do
        if(!User::checkPermission('get-tenant')){
            return response()->json(config('constants.messages.permission_denied'), 400);
            exit();
        }
        
        $tenant_id = $request->query('tenant_id');
        $tenant = User::find($tenant_id);
        
        // check if tenant exists
        if(empty($tenant)){
            return response()->json(['message' => 'No tenant found']);
        }
        
        // check if have access to view or edit
        if($tenant->owner_id != $owner_id){
            return response()->json(config('constants.messages.invalid_access'), 400);
            exit();
        }

        $tenant = $tenant->toArray();

        $tenant['addresses'] =    User::find($tenant_id)->addresses;
        $tenant['numbers'] =    User::find($tenant_id)->phoneNumbers;
        $tenant['profile'] =    User::find($tenant_id)->profile;
        $tenant['pictures'] =    User::find($tenant_id)->pictures;
        $tenant['emergencies_contacts'] =    User::emergenciesContacts($tenant_id);
        $tenant['notifications'] =    User::find($tenant_id)->notifications;
        $tenant['files'] =    User::find($tenant_id)->files;
        $tenant['staff_files'] =    User::find($tenant_id)->staffFiles;
        $tenant['managers_files'] =    User::find($tenant_id)->managersFiles;
        $tenant['owners_files'] =    User::find($tenant_id)->ownersFiles;
        $tenant['interactions'] =    User::interactions($tenant_id);
        $tenant['keys_trackings'] =    User::keysTrackings($tenant_id);
        $tenant['loanable_items_trackings'] =    User::LoanableItemsTrackings($tenant_id);
        $tenant['vehicles'] =    User::vehicles($tenant_id);
        $tenant['childrens'] =    User::children($tenant_id);
        $tenant['pets'] =    User::pets($tenant_id);
        $tenant['other_livings'] =    User::otherLivings($tenant_id);
        $tenant['employments'] =    User::find($tenant_id)->employments;
        $tenant['references'] =    User::find($tenant_id)->references;
        $tenant['listings_infos'] =    User::find($tenant_id)->listingsInfos;
        
        // get this user first assigned role
        $tenant['role_id'] = UsersRole::where(['user_id' => $tenant_id])->first()['role_id'];

        return response()->json(['data' => $tenant]);
    }
    
    public function getMyTenants()
    {
        
        $user_id = auth()->user()->id;
        $owner_id = User::getOwnerOfUser($user_id);
        
        // check if permission to do
        if(!User::checkPermission('get-my-tenants')){
            return response()->json(config('constants.messages.permission_denied'), 400);
            exit();
        }
        
        $tenants = User::select(['users.id', 'users.system_id', 'users.firstname', 'users.lastname', 'users.email', 'users.owner_id', 'users.is_active', 'users_profiles.date_of_birth'])
                        ->join('users_profiles', 'users.id', '=', 'users_profiles.user_id')
                        ->where(['owner_id' => $owner_id])
                        ->whereExists(function($query)
                        {
                            $query->select(DB::raw(1))
                            ->from('users_roles')
                            ->whereRaw('(users_roles.user_id = users.id AND users_roles.role_id = 5)');
                        })
                        ->get();
                        
        $prospects = User::select(['users.id', 'users.system_id', 'users.firstname', 'users.lastname', 'users.email', 'users.owner_id', 'users.is_active', 'users_profiles.date_of_birth'])
                        ->join('users_profiles', 'users.id', '=', 'users_profiles.user_id')
                        ->where(['owner_id' => $owner_id])
                        ->whereExists(function($query)
                        {
                            $query->select(DB::raw(1))
                            ->from('users_roles')
                            ->whereRaw('(users_roles.user_id = users.id AND users_roles.role_id = 7)');
                        })
                        ->get();
                        
        $tenants = (!empty($tenants)) ? $tenants->toArray() : [];
        $prospects = (!empty($prospects)) ? $prospects->toArray() : [];
        
        for($i=0; $i<count($tenants);$i++){
            $tenants[$i]['user_type_id'] = 5;
            $tenants[$i]['user_type'] = "Tenant";
        }
        
        for($i=0; $i<count($prospects);$i++){
            $prospects[$i]['user_type_id'] = 7;
            $prospects[$i]['user_type'] = "Prospect";
        }
        
        $data = [
            'tenants' => $tenants,
            'prospects' => $prospects
        ];
                
        return response()->json(['data' => $data]);
        
    }
    
    public function getTenantHistoryLogs(Request $request)
    {
        
        $user_id = auth()->user()->id;
        $owner_id = User::getOwnerOfUser($user_id);
        
        // check if permission to do
        if(!User::checkPermission('get-tenant-history-logs')){
            return response()->json(config('constants.messages.permission_denied'), 400);
            exit();
        }
        
        $tenant_id = $request->query('tenant_id');
        $tenant = User::find($tenant_id);
        
        // check if tenant exists
        if(empty($tenant)){
            return response()->json(['message' => 'No tenant found']);
        }
        
        // check if have access to view or edit
        if($tenant->owner_id != $owner_id){
            return response()->json(config('constants.messages.invalid_access'), 400);
            exit();
        }

        $history_logs = TenantsHistoryLog::
                        select(['tenants_history_logs.*', 'users.firstname', 'users.lastname'])
                        ->where(['user_id'=>$tenant_id])
                        ->join('users', 'users.id', '=', 'tenants_history_logs.created_by')
                        ->get();
                        
        $history_logs = (!empty($history_logs)) ? $history_logs->toArray() : [];
        
        for($i=0; $i<count($history_logs); $i++){
            
            if($history_logs[$i]['field_name'] == 'country' || $history_logs[$i]['field_name'] == 'dln_id_issue_country' || $history_logs[$i]['field_name'] == 'moveout_country'){
                if(!empty($history_logs[$i]['old_data'])){
                    $c = Country::where(['id'=>$history_logs[$i]['old_data']])->first();
                    $history_logs[$i]['old_data_title'] = (!empty($c)) ? $c->country : '';
                }
                if(!empty($history_logs[$i]['new_data'])){
                    $c = Country::where(['id'=>$history_logs[$i]['new_data']])->first();
                    $history_logs[$i]['new_data_title'] = (!empty($c)) ? $c->country : '';
                }
            }
            
            if($history_logs[$i]['field_name'] == 'state' || $history_logs[$i]['field_name'] == 'dln_id_issue_state' || $history_logs[$i]['field_name'] == 'moveout_state'){
                if(!empty($history_logs[$i]['old_data'])){
                    $c = State::where(['id'=>$history_logs[$i]['old_data']])->first();
                    $history_logs[$i]['old_data_title'] = (!empty($c)) ? $c->state : '';
                }
                if(!empty($history_logs[$i]['new_data'])){
                    $c = State::where(['id'=>$history_logs[$i]['new_data']])->first();
                    $history_logs[$i]['new_data_title'] = (!empty($c)) ? $c->state : '';
                }
            }
            
            if($history_logs[$i]['field_name'] == 'city' || $history_logs[$i]['field_name'] == 'moveout_city'){
                if(!empty($history_logs[$i]['old_data'])){
                    $c = City::where(['id'=>$history_logs[$i]['old_data']])->first();
                    $history_logs[$i]['old_data_title'] = (!empty($c)) ? $c->city : '';
                }
                if(!empty($history_logs[$i]['new_data'])){
                    $c = City::where(['id'=>$history_logs[$i]['new_data']])->first();
                    $history_logs[$i]['new_data_title'] = (!empty($c)) ? $c->city : '';
                }
            }
            
            if($history_logs[$i]['field_name'] == 'number_type_1' || $history_logs[$i]['field_name'] == 'number_type_2'  || $history_logs[$i]['field_name'] == 'number_type_3'  || $history_logs[$i]['field_name'] == 'moveout_number_type'){
                if(!empty($history_logs[$i]['old_data'])){
                    $c = City::where(['id'=>$history_logs[$i]['old_data']])->first();
                    $history_logs[$i]['old_data_title'] = (!empty($c)) ? $c->type : '';
                }
                if(!empty($history_logs[$i]['new_data'])){
                    $c = City::where(['id'=>$history_logs[$i]['new_data']])->first();
                    $history_logs[$i]['new_data_title'] = (!empty($c)) ? $c->type : '';
                }
            }
            
            if($history_logs[$i]['field_name'] == 'ethnicity_id'){
                if(!empty($history_logs[$i]['old_data'])){
                    $c = Ethnicity::where(['id'=>$history_logs[$i]['old_data']])->first();
                    $history_logs[$i]['old_data_title'] = (!empty($c)) ? $c->ethnicity : '';
                }
                if(!empty($history_logs[$i]['new_data'])){
                    $c = Ethnicity::where(['id'=>$history_logs[$i]['new_data']])->first();
                    $history_logs[$i]['new_data_title'] = (!empty($c)) ? $c->ethnicity : '';
                }
                $history_logs[$i]['field_name'] = 'ethnicity';
            }
            
            if($history_logs[$i]['field_name'] == 'gender_id'){
                if(!empty($history_logs[$i]['old_data'])){
                    $c = Gender::where(['id'=>$history_logs[$i]['old_data']])->first();
                    $history_logs[$i]['old_data_title'] = (!empty($c)) ? $c->gender : '';
                }
                if(!empty($history_logs[$i]['new_data'])){
                    $c = Gender::where(['id'=>$history_logs[$i]['new_data']])->first();
                    $history_logs[$i]['new_data_title'] = (!empty($c)) ? $c->gender : '';
                }
                $history_logs[$i]['field_name'] = 'gender';
            }
            
        }
        
        return response()->json(['data' => $history_logs]);
    }
    
    public function mergeTenant(Request $request)
    {
        
        $user_id = auth()->user()->id;
        $owner_id = User::getOwnerOfUser($user_id);
        
        // check if permission to do
        if(!User::checkPermission('merge-tenant')){
            return response()->json(config('constants.messages.permission_denied'), 400);
            exit();
        }
        
        $validation_rules = [
            'tenant_id' => 'required|numeric',
            'prospect_renter_id' => 'required|numeric',
        ];
        
        $validator = Validator::make($request->all(), $validation_rules);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 400);
        }
        
        $tenant_id = $request->tenant_id;
        $prospect_renter_id = $request->prospect_renter_id;
        
        $tenant = User::find($tenant_id);
        $prospect_renter = User::find($prospect_renter_id);
        
        // check if tenant exists
        if(empty($tenant)){
            return response()->json(['message' => 'No tenant found']);
        }
        
        // check if prospect renter exists
        if(empty($prospect_renter)){
            return response()->json(['message' => 'No prospect/renter found']);
        }
        
        // check if have access to view or edit
        if($tenant->owner_id != $owner_id || $prospect_renter->owner_id != $owner_id){
            return response()->json(config('constants.messages.invalid_access'), 400);
            exit();
        }
        
        // $tenant = $tenant->toArray();
        // $prospect_renter = $prospect_renter->toArray();
        
        $addresses =    User::find($prospect_renter_id)->addresses;
        $numbers =    User::find($prospect_renter_id)->phoneNumbers;
        $profile =    User::find($prospect_renter_id)->profile;
        $pictures =    User::find($prospect_renter_id)->pictures;
        $emergencies_contacts =    User::emergenciesContacts($prospect_renter_id);
        $notifications =    User::find($prospect_renter_id)->notifications;
        $files =    User::find($prospect_renter_id)->files;
        $staff_files =    User::find($prospect_renter_id)->staffFiles;
        $managers_files =    User::find($prospect_renter_id)->managersFiles;
        $owners_files =    User::find($prospect_renter_id)->ownersFiles;
        $interactions =    User::interactions($prospect_renter_id);
        $keys_trackings =    User::keysTrackings($prospect_renter_id);
        $loanable_items_trackings =    User::LoanableItemsTrackings($prospect_renter_id);
        $vehicles =    User::vehicles($prospect_renter_id);
        $childrens =    User::children($prospect_renter_id);
        $pets =    User::pets($prospect_renter_id);
        $other_livings =    User::otherLivings($prospect_renter_id);
        $employments =    User::find($prospect_renter_id)->employments;
        $references =    User::find($prospect_renter_id)->references;
        $listings_infos =    User::find($prospect_renter_id)->listingsInfos;
        
        $data = [
            'user_prefix_id' => $prospect_renter->user_prefix_id ?? null,
            'firstname' => $prospect_renter->firstname,
            'middlename' => $prospect_renter->middlename ?? '',
            'lastname' => $prospect_renter->lastname,
            'user_suffix_id' => $prospect_renter->user_suffix_id ?? null,
            //'email' => $prospect_renter->email,
            'about_me' => $prospect_renter->about_me ?? '',
        ];
        User::where(['id'=>$tenant_id])->update($data);
        
        foreach($addresses as $a){
            $data = [
                'user_id' => $tenant_id,
                'address_line1' => $a['address_line1'],
                'address_line2' => $a['address_line2'],
                'city' => $a['city'],
                'state' => $a['state'],
                'country' => $a['country'],
                'zip_code' => $a['zip_code']
            ];
            UsersAddress::create($data);
        }
        
        foreach($numbers as $a){
            $data = [
                'user_id' => $tenant_id,
                'country_code' => $a['country_code'],
                'phone_number' => $a['phone_number'],
                'number_type' => $a['number_type']
            ];
            UsersNumber::create($data);
        }
        
        $data = [
            'dln_id' => $profile['dln_id'],
            'dl_id_picture' => $profile['dl_id_picture'],
            'dln_id_issue_country' => $profile['dln_id_issue_country'],
            'dln_id_issue_state' => $profile['dln_id_issue_state'],
            'dln_id_issue_notes' => $profile['dln_id_issue_notes'],
            'gender_id' => $profile['gender_id'],
            'ethnicity_id' => $profile['ethnicity_id'],
            'smoker' => $profile['smoker'],
            'smoker_notes' => $profile['smoker_notes'],
            'known_allergies' => $profile['known_allergies'],
            'other_emergency_info' => $profile['other_emergency_info'],
            'user_notes' => $profile['user_notes'],
            'user_staff_notes' => $profile['user_staff_notes'],
            'user_manager_notes' => $profile['user_manager_notes'],
            'user_owner_notes' => $profile['user_owner_notes'],
            'moveout_address1' => $profile['moveout_address1'],
            'moveout_address2' => $profile['moveout_address2'],
            'moveout_country' => $profile['moveout_country'],
            'moveout_city' => $profile['moveout_city'],
            'moveout_state' => $profile['moveout_state'],
            'moveout_zip_code' => $profile['moveout_zip_code'],
            'moveout_number' => $profile['moveout_number'],
            'moveout_number_type' => $profile['moveout_number_type'],
            'moveout_email' => $profile['moveout_email'],
            'moveout_date' => $profile['moveout_date'],
            'moveout_reason_id' => $profile['moveout_reason_id']
        ];
        UsersProfile::where(['user_id'=>$tenant_id])->update($data);
        
        foreach($pictures as $a){
            $data = [
                'picture' => $a['picture'],
                'is_cover' => $a['is_cover'],
                'order_number' => $a['order_number'],
                'user_id' => $tenant_id
            ];
            UsersPicture::create($data);
        }
        
        foreach($emergencies_contacts as $c){
            $data = [
                'firstname' => $c['firstname']  ?? '',
                'lastname' => $c['lastname']  ?? '',
                'user_relationship_id' => $c['user_relationship_id']  ?? null,
                'other_user_relationship' => $c['other_user_relationship']  ?? '',
                'email' => $c['email']  ?? '',
                'address_line1' => $c['address_line1']  ?? '',
                'address_line2' => $c['address_line2']  ?? '',
                'country' => $c['country'] ?? '',
                'city' => $c['city']  ?? '',
                'state' => $c['state']  ?? '',
                'zip_code' => $c['zip_code']  ?? '',
                'number1' => $c['number1']  ?? '',
                'number1_type' => $c['number1_type'] ?? '',
                'number2' => $c['number2'] ?? '',
                'number2_type' => $c['number2_type'] ?? '',
                'number3' => $c['number3'] ?? '',
                'number3_type' => $c['number3_type'] ?? '',
                'user_id' => $tenant_id,
            ];
            
            $user_emergency_contact = UsersEmergenciesContact::create($data);
            
            $user_emergency_contact_id = $user_emergency_contact->id;
            
            $pictures = $c['pictures'];
            
            foreach($pictures as $p){
                $data = [
                    'user_emergency_contact_id' => $user_emergency_contact_id,
                    'picture' => $p['picture'],
                    'order_number' => $p['order_number']
                ];
                UsersEmergenciesContactsPicture::create($data);
            }
            
        }
        
        foreach($notifications as $n){
            $data = [
                'title' => $n['title'] ?? '',
                'notification' => $n['notification'] ?? '',
                'is_popup_notification' => $n['is_popup_notification'] ?? 0,
                'posting_date' => $n['posting_date'],
                'posting_time' => $n['posting_time'],
                'posting_date_time_str' => $n['posting_date_time_str'],
                'user_id' => $tenant_id
            ];
            UsersNotification::create($data);
        }
        
        foreach($files as $f){
            $data = [
                'title' => $f['title'] ?? '',
                'file' => $f['file'],
                'user_id' => $tenant_id,
            ];
            UsersFile::create($data);
        }
        
        foreach($staff_files as $f){
            $data = [
                'title' => $f['title'] ?? '',
                'file' => $f['file'],
                'user_id' => $tenant_id,
            ];
            UsersStaffFile::create($data);
        }
        
        foreach($managers_files as $f){
            $data = [
                'title' => $f['title'] ?? '',
                'file' => $f['file'],
                'user_id' => $tenant_id,
            ];
            UsersManagersFile::create($data);
        }
        
        foreach($owners_files as $f){
            $data = [
                'title' => $f['title'] ?? '',
                'file' => $f['file'],
                'user_id' => $tenant_id,
            ];
            UsersOwnersFile::create($data);
        }
        
        
        
        
        foreach($interactions as $i){
            $data = [
                'date' => $i['date'],
                'time' => $i['time'],
                'interaction_type_id' => $i['interaction_type_id'] ?? null,
                'other_type_description' => $i['other_type_description'] ?? '',
                'notes' => $i['notes'] ?? '',
                'who_meet_user_id' => $i['who_meet_user_id'] ?? null,
                'user_id' => $tenant_id
            ];
            $interaction = UsersInteraction::create($data);
            
            $interaction_id = $interaction->id;
            
            $files = $i['files'];
            
            foreach($files as $f){
                $data = [
                    'user_interaction_id' => $interaction_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ];
                UsersInteractionsFile::create($data);
            }
            
        } 
        
        foreach($keys_trackings as $k){
            $data = [
                'assigned_verification_picture' => $k['assigned_verification_picture'] ?? '',
                'assigned_verification_signature' => $k['assigned_verification_signature'] ?? '',
                'is_lost_damaged' => $k['is_lost_damaged'] ?? 0,
                'lost_damaged_date' => $k['lost_damaged_date'] ?? '',
                'send_replacement_cost_invoice' => $k['send_replacement_cost_invoice'] ?? 0,
                'replacement_additional_fees' => $k['replacement_additional_fees'] ?? 0,
                'replacement_reason' => $k['replacement_reason'] ?? '',
                'is_returned' => $k['is_returned'] ?? 0,
                'returned_date' => $k['returned_date'] ?? '',
                'returned_verification_picture' => $k['returned_verification_picture'] ?? '',
                'returned_verification_signature' => $k['returned_verification_signature'] ?? '',
                'notes' => $k['notes'] ?? '',
                'key_id' => $k['key_id'],
                'assigned_to' => $tenant_id,
                'assigned_by' => $user_id,
                'assigned_date' => $k['assigned_date'] ?? ''
            ];
            $key_tracking = KeysTracking::create($data);
            
            $key_tracking_id = $key_tracking->id;
            
            $replacement_files = $k['replacement_files'];
            
            foreach($replacement_files as $f){
                $data = [
                    'key_tracking_id' => $key_tracking_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ];
                KeysTrackingsReplacementFile::create($data);
            }
            
        }
        
        foreach($loanable_items_trackings as $l){
            $data = [
                'assigned_verification_picture' => $l['assigned_verification_picture'] ?? '',
                'assigned_verification_signature' => $k['assigned_verification_signature'] ?? '',
                'is_lost_damaged' => $l['is_lost_damaged'] ?? 0,
                'lost_damaged_date' => $l['lost_damaged_date'] ?? '',
                'send_replacement_cost_invoice' => $l['send_replacement_cost_invoice'] ?? 0,
                'replacement_additional_fees' => $l['replacement_additional_fees'] ?? 0,
                'replacement_reason' => $l['replacement_reason'] ?? '',
                'is_returned' => $l['is_returned'] ?? 0,
                'returned_date' => $l['returned_date'] ?? '',
                'returned_verification_picture' => $l['returned_verification_picture'] ?? '',
                'returned_verification_signature' => $k['returned_verification_signature'] ?? '',
                'notes' => $l['notes'] ?? '',
                'loanable_item_id' => $l['loanable_item_id'],
                'loanable_item_serial_number_id' => $l['loanable_item_serial_number_id'],
                'assigned_to' => $tenant_id,
                'assigned_by' => $user_id,
                'assigned_date' => $l['assigned_date'] ?? ''
            ];
            $loanable_item_tracking = LoanableItemsTracking::create($data);
            
            $loanable_item_tracking_id = $loanable_item_tracking->id;
            
            $replacement_files = $l['replacement_files'];
            
            foreach($replacement_files as $f){
                $data = [
                    'loanable_item_tracking_id' => $loanable_item_tracking_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ];
                LoanableItemsTrackingsReplacementFile::create($data);
            }
            
            $replacement_pictures = $l['replacement_pictures'];
            
            foreach($replacement_pictures as $p){
                $data = [
                    'loanable_item_tracking_id' => $loanable_item_tracking_id,
                    'picture' => $p['picture'],
                    'is_given' => $p['is_given'],
                    'is_return' => $p['is_return']
                ];
                LoanableItemsTrackingsPicture::create($data);
            }
            
        }
        
        foreach($vehicles as $v){
            $data = [
                'status' => $v['status'] ?? 0,
                'year' => $v['year'] ?? '',
                'vehicle_make_id' => $v['vehicle_make_id'] ?? null,
                'vehicle_model_id' => $v['vehicle_model_id'] ?? null,
                'color' => $v['color'] ?? '',
                'vin' => $v['vin'] ?? '',
                'license_plate' => $v['license_plate'] ?? '',
                'assign_parking_space' => $v['assign_parking_space'] ?? 0,
                'property_parking_space_id' => $v['property_parking_space_id'] ?? null,
                'notes' => $v['notes'] ?? '',
                'user_id' => $tenant_id
            ];
            $vehicle = UsersVehicle::create($data);
            
            $vehicle_id = $vehicle->id;
             
            $pictures = $v['pictures'];
            
            foreach($pictures as $p){
                $data = [
                    'user_vehicle_id' => $vehicle_id,
                    'picture' => $p['picture'] ?? '',
                    'order_number' => $p['order_number']
                ];
                
                UsersVehiclesPicture::create($data);
            }
            
            
            $files = $v['files'];
            
            foreach($files as $f){
                $data = [
                    'user_vehicle_id' => $vehicle_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file']
                ];
                UsersVehiclesFile::create($data);
            }
            
        }
        
        foreach($childrens as $c){
            $data = [
                'status' => $c['status'] ?? 0,
                'firstname' => $c['firstname'] ?? '',
                'middlename' => $c['middlename'] ?? '',
                'lastname' => $c['lastname'] ?? '',
                'gender_id' => $c['gender_id'] ?? '',
                'date_of_birth' => $c['date_of_birth'] ?? '',
                'public_note' => $c['public_note'] ?? '',
                'private_note' => $c['private_note'] ?? '',
                'user_id' => $tenant_id
            ];
            $children = UsersChildren::create($data);
            
            $children_id = $children->id;
             
            $pictures = $c['pictures'];
            
            foreach($pictures as $p){
                $data = [
                    'user_children_id' => $children_id,
                    'picture' => $p['picture'],
                    'order_number' => $p['order_number']
                ];
                UsersChildrensPicture::create($data);
            }
            
            $files = $c['files'];
            
            foreach($files as $f){
                $data = [
                    'user_children_id' => $children_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => $f['is_private']
                ];
                UsersChildrensFile::create($data);
            }
            
        }
        
        foreach($pets as $p){
            $data = [
                'status' => $p['status'] ?? 0,
                'name' => $p['name'] ?? '',
                'pet_type_id' => $p['pet_type_id'] ?? null,
                'pet_gender_id' => $p['pet_gender_id'] ?? null,
                'breed' => $p['breed'] ?? '',
                'color' => $p['color'] ?? '',
                'weight' => $p['weight'] ?? '',
                'date_of_birth' => $p['date_of_birth'] ?? '',
                'support_animal' => $p['support_animal'] ?? 0,
                'deposit' => $p['deposit'] ?? '',
                'rent' => $p['rent'] ?? '',
                'license' => $p['license'] ?? '',
                'location_of_license' => $p['location_of_license'] ?? '',
                'public_note' => $p['public_note'] ?? '',
                'private_note' => $p['private_note'] ?? '',
                'user_id' => $tenant_id
            ];
            $pet = UsersPet::create($data);
            
            $pet_id = $pet->id;
             
            $shots = $p['shots'];
            
            foreach($shots as $s){
                $data = [
                    'user_pet_id' => $pet_id,
                    'type' => $s['type'] ?? '',
                    'is_shot_applied' => $s['is_shot_applied'] ?? 0,
                    'applied_date' => $s['applied_date'] ?? '',
                    'expiry_date' => $s['expiry_date'] ?? '',
                    'proof_picture' => $s['proof_picture'] ?? '',
                    'is_approved_by_owner' => $s['is_approved_by_owner'] ?? 0,
                    'is_rejected_by_owner' => $s['is_rejected_by_owner'] ?? 0,
                    'rejected_reason' => $s['rejected_reason'] ?? '',
                    'creator_id' => $user_id
                ];
                UsersPetsShot::create($data);
            }
             
            $pictures = $p['pictures'];
            
            foreach($pictures as $pi){
                $data = [
                    'user_pet_id' => $pet_id,
                    'picture' => $pi['picture'],
                    'order_number' => $pi['order_number']
                ];
                UsersPetsPicture::create($data);
            }
            
            $files = $p['files'];
            
            foreach($files as $f){
                $data = [
                    'user_pet_id' => $pet_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => $f['is_private']
                ];
                UsersPetsFile::create($data);
            }
            
        }
        
        foreach($other_livings as $o){
            $data = [
                'status' => $o['status'] ?? 0,
                'firstname' => $o['firstname'] ?? '',
                'middlename' => $o['middlename'] ?? '',
                'lastname' => $o['lastname'] ?? '',
                'date_of_birth' => $o['date_of_birth'] ?? '',
                'gender_id' => $o['gender_id'] ?? null,
                'user_relationship_id' => $o['user_relationship_id'] ?? null,
                'other_relationship' => $o['other_relationship'] ?? '',
                'additional_deposit' => $o['additional_deposit'] ?? 0,
                'additional_rent' => $o['additional_rent'] ?? 0,
                'reason_for_movein' => $o['reason_for_movein'] ?? '',
                'public_note' => $o['public_note'] ?? '',
                'private_note' => $o['private_note'] ?? '',
                'user_id' => $tenant_id
            ];
            $other_living = UsersOthersLiving::create($data);
            
            $other_living_id = $other_living->id;
             
            $pictures = $o['pictures'];
            
            foreach($pictures as $p){
                $data = [
                    'user_other_living_id' => $other_living_id,
                    'picture' => $p['picture'],
                    'order_number' => $p['order_number']
                ];
                UsersOthersLivingsPicture::create($data);
            }
            
            $files = $o['files'];
            
            foreach($files as $f){
                $data = [
                    'user_other_living_id' => $other_living_id,
                    'title' => $f['title'] ?? '',
                    'file' => $f['file'],
                    'is_private' => $f['is_private']
                ];
                UsersOthersLivingsFile::create($data);
            }
            
        }
        
        foreach($employments as $e){
            $data = [
                'company_name' => $e['company_name'] ?? '',
                'position' => $e['position'] ?? '',
                'annual_salary' => $e['annual_salary'] ?? 0,
                'start_year' => $e['start_year'] ?? '',
                'end_year' => $e['end_year'] ?? '',
                'present' => $e['present'] ?? 0,
                'address_line1' => $e['address_line1'] ?? '',
                'address_line2' => $e['address_line2'] ?? '',
                'country' => $e['country'] ?? '',
                'city' => $e['city'] ?? '',
                'state' => $e['state'] ?? '',
                'zip_code' => $e['zip_code'] ?? '',
                'website' => $e['website'] ?? '',
                'supervisor' => $e['supervisor'] ?? '',
                'number' => $e['number'] ?? '',
                'number_type' => $e['number_type'] ?? '',
                'leaving_reason' => $e['leaving_reason'] ?? '',
                'notes' => $e['notes'] ?? '',
                'user_id' => $tenant_id
            ];
            UsersEmployment::create($data);
            
        }
        
        foreach($references as $r){
            $data = [
                'firstname' => $r['firstname'] ?? '',
                'lastname' => $r['lastname'] ?? '',
                'user_reference_relationship_id' => $r['user_reference_relationship_id'] ?? null,
                'other_reference_relationship' => $r['other_reference_relationship'] ?? '',
                'number1' => $r['number1'] ?? '',
                'number1_type' => $r['number1_type'] ?? '',
                'number2' => $r['number2'] ?? '',
                'number2_type' => $r['number2_type'] ?? '',
                'number3' => $r['number3'] ?? '',
                'number3_type' => $r['number3_type'] ?? '',
                'notes' => $r['notes'] ?? '',
                'user_id' => $tenant_id
            ];
            UsersReference::create($data);
            
        }
        
        $data = [
            'user_id' => $tenant_id,
            'show_listing' => $listings_infos['show_listing'] ?? 0,
            'max_monthly_rent' => $listings_infos['max_monthly_rent'] ?? 0,
            'areas' => $listings_infos['areas'] ?? '',
            'type_id' => $listings_infos['type_id'] ?? null,
            'bedrooms' => $listings_infos['bedrooms'] ?? 0,
            'bathrooms' => $listings_infos['bathrooms'] ?? 0,
            'place_with_id' => $listings_infos['place_with_id']  ?? null,
            'private_bedroom' => $listings_infos['private_bedroom'] ?? 0,
            'private_bathroom' => $listings_infos['private_bathroom'] ?? 0,
            'lgbtq_friendly' => $listings_infos['lgbtq_friendly'] ?? 0,
            'pets_ok' => $listings_infos['pets_ok'] ?? 0,
            'desired_features' => $listings_infos['desired_features'] ?? ''
        ];
        UsersListingsInfo::create($data);
        
        User::where(['id'=>$prospect_renter_id])->delete();
        
        return response()->json(['message' => 'Success', 'data' => []]);
    }
    
}