<?php

namespace App\Http\Controllers;

use Maatwebsite\Excel\Facades\Excel;
use App\Helpers\Formatter;
use App\Helpers\Helpers;
use App\Exports\GroupExport;
use App\Exports\ParticipantExport;
use App\Exports\PhonebookExport;
use App\Imports\PhonebookImport;
use App\Models\ContactGroup;
use App\Models\Device;
use App\Models\PbTemp;
use App\Models\Phonebook;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
// use Illuminate\Support\Facades\Http;

class PhonebookController extends Controller
{
  public function list()
  {
    $phonebooks = auth()->user()->phonebooks()->take(300)->get();
    $listAll = false;
    return view('/phonebook-list', compact('listAll', 'phonebooks'));
  }

  public function listAll()
  {
    $phonebooks = Phonebook::latest()->take(300)->get();
    $listAll = true;
    return view('/phonebook-list', compact('listAll', 'phonebooks'));
  }

  public function show(Request $request)
  {
    $phonebook = Phonebook::where('id', '=', $request->phonebook_id)->first();
    if (auth()->user()->id != $phonebook->user_id && auth()->user()->role !== 'admin') {
      return redirect()
        ->back()
        ->with(['danger_alert' => __('You are not allowed to show Phonebook')]);
    }
    $phonebookData = json_decode($phonebook->data);
    $countContacts = count($phonebookData);
    // $contacts = Helpers::paginate($phonebookData, 100);
    $contacts = $phonebookData instanceof Collection ? $phonebookData : Collection::make($phonebookData);
    // $contacts->withPath(url("/phonebook-show?phonebook_id={$request->phonebook_id}"));
    return view('/phonebook-show', compact('phonebook', 'contacts', 'countContacts'));
  }

  public function store(Request $request)
  {
    $user = auth()->user();
    $package = $user->package;
    $countPhonebook = $user->phonebooks()->count();
    if (Helpers::isEx() && $package->max_phonebook <= $countPhonebook && $package->max_phonebook >= 0) {
      return redirect()
        ->back()
        ->with('danger_alert', __('Phonebook reached max limit! Max') . ': ' . $package->max_phonebook);
    }
    PbTemp::truncate();
    if (!empty($request->file('filename'))) {
      Excel::import(new PhonebookImport(), request()->file('filename'));
    }
    $contacts = PbTemp::all();
    foreach ($contacts as $contact) {
      if (!empty($contact->phone)) {
        if (!str_ends_with($contact->phone, '@g.us') && !str_ends_with($contact->phone, '@s.whatsapp.net')) {
          $contact->phone = Formatter::pf($contact->phone);
          $contact->save();
        }
      }
    }
    $phonebook = new Phonebook();
    $phonebook->user_id = $user->id;
    $phonebook->name = $request->input('name');
    if (Phonebook::where('user_id', '=', $user->id)->where('name', '=', $phonebook->name)->count() > 0) {
      return redirect()->back()->with(['danger_alert' => __('Duplicate found. Failed to add') . ': ' . $phonebook->name]);
    }
    $phonebook->data = json_encode(PbTemp::where('phone', '!=', '')->orWhere('phone', '!=', null)->orWhere('phone', '!=', 'NULL')->get());
    $phonebook->save();
    return redirect()->back()->with(['success_alert' => __('Successfully add') . ': ' . $phonebook->name]);
  }

  public function scrapeGMaps(Request $request)
  {
    $user = auth()->user();
    $package = $user->package;
    $countPhonebook = $user->phonebooks()->count();
    if (Helpers::isEx() && $package->max_phonebook <= $countPhonebook && $package->max_phonebook >= 0) {
      return redirect()
        ->back()
        ->with('danger_alert', __('Phonebook reached max limit! Max') . ': ' . $package->max_phonebook);
    }
    $key = $request->input('key');
    $location = str_replace(' ', '', $request->input('location'));
    $radius = $request->input('radius');
    $keyword = empty($request->input('keyword')) ? '' : "&keyword={$request->input('keyword')}";
    $maxprice = empty($request->input('maxprice')) ? '' : "&maxprice={$request->input('maxprice')}";
    $minprice = empty($request->input('minprice')) ? '' : "&minprice={$request->input('minprice')}";
    $rankby = empty($request->input('rankby')) ? '' : "&rankby={$request->input('rankby')}";
    $type = empty($request->input('type')) ? '' : "&type={$request->input('type')}";
    $url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=$key&location=$location&radius=$radius" . $keyword . $maxprice . $minprice . $rankby . $type;
    $res = json_decode(Helpers::curlGet($url));
    if ($res?->status === 'OK') {
      $places = $res->results;
      $data = [];
      $i = 0;
      foreach ($places as $place) {
        $res2 = json_decode(Helpers::curlGet("https://maps.googleapis.com/maps/api/place/details/json?key=$key&place_id=$place->place_id"));
        if ($res2?->status === 'OK') {
          $detail = $res2->result;
          // available properties: address_components,adr_address,business_status,current_opening_hours,formatted_address,formatted_phone_number,geometry,icon,icon_background_color,icon_mask_base_uri,international_phone_number,name,opening_hours,photos,place_id,plus_code,rating,reference,reviews,types,url,user_ratings_total,utc_offset,vicinity,website,wheelchair_accessible_entrance
          $i += 1;
          $arr = [
            'id' => $i,
            'name' => $detail?->name ?? '',
            'phone' => preg_replace('/\D/', '', $detail?->international_phone_number ?? ''),
            'column1' => $detail?->formatted_address ?? '',
            'column2' => $detail?->rating ?? '',
            'column3' => $detail?->user_ratings_total ?? '',
            'column4' => $detail?->url ?? '',
            'column5' => $detail?->website ?? '',
          ];
          array_push($data, $arr);
        }
      }
      $pbName = empty($type.$keyword) ? 'gmaps-' . Carbon::now()->timestamp : (empty($type) ? $keyword : (empty($keyword) ? $type : "$type - $keyword"));
      Phonebook::updateOrInsert(['user_id' => $user->id, 'name' => $pbName], ['data' => json_encode($data)]);
      return redirect()->back()->with(['success_alert' => __('Successfully add') . ': ' . $pbName]);
    } else {
      return redirect()->back()->with(['danger_alert' => __('Fail to add') . ': ' . json_encode($res)]);
    }
  }

  public function storeGroups(Request $request)
  {
    $user = auth()->user();
    $package = $user->package;
    $countPhonebook = $user->phonebooks()->count();
    if (Helpers::isEx() && $package->max_phonebook <= $countPhonebook && $package->max_phonebook >= 0) {
      return redirect()
        ->back()
        ->with('danger_alert', __('Phonebook reached max limit! Max') . ': ' . $package->max_phonebook);
    }

    $groups = ContactGroup::where('sender', '=', $request->sender)->get();
    $data = [];
    $i = 0;
    foreach ($groups as $group) {
      $i += 1;
      $arr = ['id' => $i, 'name' => $group->subject, 'phone' => $group->groupId];
      array_push($data, $arr);
    }
    Phonebook::updateOrInsert(['user_id' => $user->id, 'name' => 'All groups'], ['data' => json_encode($data)]);
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully add') . ': All groups']);
  }

  public function storeParticipants(Request $request)
  {
    $user = auth()->user();
    $package = $user->package;
    $countPhonebook = $user->phonebooks()->count();
    if (Helpers::isEx() && $package->max_phonebook <= $countPhonebook && $package->max_phonebook >= 0) {
      return redirect()
        ->back()
        ->with('danger_alert', __('Phonebook reached max limit! Max') . ': ' . $package->max_phonebook);
    }

    $contactGroup = ContactGroup::where('id', '=', $request->id)->first();
    $data = [];
    $i = 0;
    $participants = json_decode($contactGroup->participants);
    foreach ($participants as $participant) {
      $i += 1;
      $arr = ['id' => $i, 'name' => __('Sir/Madam'), 'phone' => preg_replace('/\D/', '', $participant->id)];
      array_push($data, $arr);
    }
    Phonebook::updateOrInsert(['user_id' => $user->id, 'name' => $contactGroup->subject], ['data' => json_encode($data)]);
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully add') . ': ' . $contactGroup->subject]);
  }

  public function check(Request $request)
  {
    $device = Device::where('user_id', '=', $request->user_id)
      ->where('status', '=', 'ONLINE')
      ->first();
    if (empty($device)) {
      return redirect()
        ->back()
        ->with(['danger_alert' => __('You do not have ONLINE device')]);
    }
    $phonebook = Phonebook::where('id', '=', $request->phonebook_id)->first();
    $contacts = json_decode($phonebook->data, true);
    $i = 0;
    $indexes = [];
    foreach ($contacts as $contact) {
      $receiver = preg_replace('/\D/', '', $contact['phone']);
      $response = Helpers::curlGet(rtrim(config('app.node_url'), '/') . "/isonwa?receiver=$receiver&sender=$device->sender&token=$device->token");
      $res = json_decode($response);
      if (empty($res->isonwa)) {
        array_push($indexes, $i);
      }
      $i += 1;
    }
    foreach ($indexes as $index) {
      unset($contacts[$index]);
    }
    $phonebook->data = json_encode(array_values($contacts));
    $phonebook->save();
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully check') . ': ' . $phonebook->name]);
  }

  public function update(Request $request, Phonebook $phonebook)
  {
    $phonebook = Phonebook::where('id', '=', $request->input('phonebook_id'))->first();
    if (auth()->user()->id != $phonebook->user_id && auth()->user()->role !== 'admin') {
      return redirect()
        ->back()
        ->with(['danger_alert' => __('You are not allowed to update Phonebook')]);
    }
    $phonebook->name = $request->input('name');
    PbTemp::truncate();
    if (!empty($request->file('filename'))) {
      Excel::import(new PhonebookImport(), request()->file('filename'));
      $phonebook->data = json_encode(
        PbTemp::where('phone', '!=', '')
          ->orWhere('phone', '!=', null)
          ->orWhere('phone', '!=', 'NULL')
          ->get()
      );
    }
    $phonebook->save();
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully update Phonebook') . ': ' . $phonebook->name]);
  }

  public function addContact(Request $request)
  {
    $contact_id = $request->contact_id;
    $phonebook = Phonebook::where('id', '=', $request->phonebook_id)->first();
    if (auth()->user()->id != $phonebook->user_id && auth()->user()->role !== 'admin') {
      return redirect()
        ->back()
        ->with(['danger_alert' => __('You are not allowed to add Phonebook')]);
    }
    $contacts = json_decode($phonebook->data, true);
    array_push($contacts, [
      'id' => $contact_id + 1,
      'name' => $request->contact_name,
      'phone' => $request->contact_phone,
      'email' => $request->contact_email,
      'memo' => $request->contact_memo,
      'column1' => $request->contact_column1,
      'column2' => $request->contact_column2,
      'column3' => $request->contact_column3,
      'column4' => $request->contact_column4,
      'column5' => $request->contact_column5,
    ]);
    $phonebook->data = json_encode(array_values($contacts));
    $phonebook->save();
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully add Contact')]);
  }

  public function editContact(Request $request)
  {
    $contact_id = $request->contact_id;
    $phonebook = Phonebook::where('id', '=', $request->phonebook_id)->first();
    if (auth()->user()->id != $phonebook->user_id && auth()->user()->role !== 'admin') {
      return redirect()
        ->back()
        ->with(['danger_alert' => __('You are not allowed to edit Phonebook')]);
    }
    $contacts = json_decode($phonebook->data, true);
    foreach ($contacts as $key => $val) {
      if ($val['id'] == $contact_id) {
        $contacts[$key]['name'] = $request->contact_name;
        $contacts[$key]['phone'] = $request->contact_phone;
        $contacts[$key]['email'] = $request->contact_email;
        $contacts[$key]['memo'] = $request->contact_memo;
        $contacts[$key]['column1'] = $request->contact_column1;
        $contacts[$key]['column2'] = $request->contact_column2;
        $contacts[$key]['column3'] = $request->contact_column3;
        $contacts[$key]['column4'] = $request->contact_column4;
        $contacts[$key]['column5'] = $request->contact_column5;
        $phonebook->data = json_encode(array_values($contacts));
        $phonebook->save();
        break;
      }
    }
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully edit Contact')]);
  }

  public function export(Request $request)
  {
    return Excel::download(new PhonebookExport($request->listAll), 'phonebooks.xlsx');
  }

  public function exportGroups(Request $request)
  {
    return Excel::download(new GroupExport($request->sender), "groups.xlsx");
  }

  public function exportParticipants(Request $request)
  {
    return Excel::download(new ParticipantExport($request->id), "$request->subject.xlsx");
  }

  public function destroyContact(Request $request)
  {
    $contact_id = $request->contact_id;
    $phonebook = Phonebook::where('id', '=', $request->phonebook_id)->first();
    if (auth()->user()->id != $phonebook->user_id && auth()->user()->role !== 'admin') {
      return redirect()
        ->back()
        ->with(['danger_alert' => __('You are not allowed to delete Phonebook')]);
    }
    $contacts = json_decode($phonebook->data, true);
    foreach ($contacts as $key => $val) {
      if ($val['id'] == $contact_id) {
        unset($contacts[$key]);
        $phonebook->data = json_encode(array_values($contacts));
        $phonebook->save();
        break;
      }
    }
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully delete Contact')]);
  }

  public function destroy(Request $request)
  {
    $phonebook = Phonebook::where('id', '=', $request->phonebook_id)->first();
    if (auth()->user()->id != $phonebook->user_id && auth()->user()->role !== 'admin') {
      return redirect()
        ->back()
        ->with(['danger_alert' => __('You are not allowed to delete Phonebook')]);
    }
    $phonebook->delete();
    return redirect()
      ->back()
      ->with(['success_alert' => __('Successfully delete Phonebook')]);
  }
}
