<?php

namespace App\Http\Controllers;

use App\Helpers\Formatter;
use App\Helpers\Helpers;
use App\Models\Device;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Filesystem\Filesystem;

class DeviceController extends Controller
{
  public function dashboard()
  {
    return $this->list();
  }

  public function list(Request $request)
  {
    $adminSender = Device::where('user_id', 1)->where('status', '=', 'ONLINE')->value('sender');
    $user = auth()->user();
    $devices = Device::where('user_id', $user->id)->orderBy('status', 'desc')->orderBy('name', 'asc')->search($request->search)->paginate()->appends($request->all());
    $currentSent = $user->current_sent;
    $totalSent = $user->total_sent;
    $totalDevices = $devices->count();
    $totalOnline = $devices->where('status', '=', 'ONLINE')->count();
    $extWebhookDataPlaceholder = json_encode([
      'sender' => '{sender}',
      'receiver' => '{receiver}',
      'text' => '{text}',
      'token' => '{token}',
      'key_id' => '{key_id}',
      'recnumber' => '{recnumber}',
      'recname' => '{recname}',
      'devtype' => '{devtype}',
      'mentioned' => '{mentioned}',
      'appurl' => '{appurl}',
      'nodeurl' => '{nodeurl}',
    ], JSON_PRETTY_PRINT);
    $listAll = false;
    return view('/device-list', compact('listAll', 'adminSender', 'user', 'devices', 'currentSent', 'totalSent', 'totalDevices', 'totalOnline', 'extWebhookDataPlaceholder'));
  }

  public function listAll(Request $request)
  {
    $adminSender = Device::where('user_id', 1)->where('status', '=', 'ONLINE')->value('sender');
    $user = auth()->user();
    $devices = Device::orderBy('status', 'desc')->orderBy('name', 'asc')->search($request->search)->paginate()->appends($request->all());
    $currentSent = User::sum('current_sent');
    $totalSent = User::sum('total_sent');
    $totalDevices = Device::count();
    $totalOnline = Device::where('status', '=', 'ONLINE')->count();
    $extWebhookDataPlaceholder = json_encode([
      'sender' => '{sender}',
      'receiver' => '{receiver}',
      'text' => '{text}',
      'token' => '{token}',
      'key_id' => '{key_id}',
      'recnumber' => '{recnumber}',
      'recname' => '{recname}',
      'devtype' => '{devtype}',
      'mentioned' => '{mentioned}',
      'appurl' => '{appurl}',
      'nodeurl' => '{nodeurl}',
    ], JSON_PRETTY_PRINT);
    $listAll = true;
    return view('/device-list', compact('listAll', 'adminSender', 'user', 'devices', 'currentSent', 'totalSent', 'totalDevices', 'totalOnline', 'extWebhookDataPlaceholder'));
  }

  public function show(Request $request)
  {
    $device = Device::where('id', '=', $request->device_id)->first();
    if (auth()->user()->id != $device->user_id && auth()->user()->role !== 'admin') {
      return redirect()->back()->with(['danger_alert' => __('You are not allowed to show Device')]);
    }
    return view('/device-show', compact('device'));
  }

  public function showContacts(Request $request)
  {
    $device = Device::where('sender', '=', $request->sender)->first();
    if (auth()->user()->id != $device->user_id && auth()->user()->role !== 'admin') {
      return redirect()->back()->with(['danger_alert' => __('You are not allowed to show Device')]);
    }
    $contactGroups = $device->contact_groups;
    return view('/device-showcontacts', compact('device', 'contactGroups'));
  }

  public function store(Request $request)
  {
    $user = auth()->user();
    $package = $user->package;
    $count_device = $user->devices()->count();
    if (Helpers::isEx() && $package->max_device <= $count_device && $package->max_device >= 0) {
      return redirect()->back()->with('danger_alert', __('Device reached max limit! Max') . ': ' . $package->max_device);
    }
    // Validate OTP if WA verification is enabled and adminSender is provided
    if (filter_var(Helpers::setting('waVerification'), FILTER_VALIDATE_BOOLEAN) && $user->role !== 'admin' && !empty($request->input('adminSender'))) {
      if ($user->otp !== $request->input('otp')) {
        $user->otp = Str::random(20);
        $user->save();
        return redirect()->back()->with(['danger_alert' => __('OTP code is invalid.')]);
      }
    }
    $user->otp = Str::random(20);
    $user->save();
    $device = new Device();
    $device->user_id = $user->id;
    $device->name = $request->input('name');
    $device->sender = Formatter::pf($request->input('sender'));
    if (Device::where('sender', '=', $device->sender)->count() > 0) {
      return redirect()->back()->with(['danger_alert' => __('Duplicate found. Failed to add') . ': ' . $device->name]);
    }
    $device->token = Str::random(20);
    $device->subscribe_keyword = 'Subscribe';
    $device->unsubscribe_keyword = 'Unsubscribe';
    $device->subscribe_message = 'Hi *{name}*! Thank you for subscribing to our channel. We will make sure you will receive our best offer.';
    $device->unsubscribe_message = 'Hi *{name}*! We are very sad to see you go. Please Subscribe if you want to join back. Thank you!';
    $device->welcome_cust = '[]';
    $device->openai = json_encode([
      'apikey' => '',
      'contain' => $request->input('name'),
      'model' => 'gpt-3.5-turbo',
      'image_contain' => __('Generate image'),
      'image_model' => 'dall-e-3',
      'max_tokens' => 2048,
      'save_chats' => 0,
      'persona' => "My name is $device->name. I am a smart, polite, and gentle assistant",
    ]);
    $device->webhook = url('/api/webhook');
    $device->ext_webhook = json_encode([
      'url' => '',
      'data' => [],
    ]);
    $device->save();
    return redirect()->back()->with(['success_alert' => __('Successfully add') . ': ' . $device->name]);
  }

  public function update(Request $request)
  {
    $request->validate(['wu_receiver' => 'max:255']);
    if (!empty($request->input('extWebhookUrl')) && trim($request->input('extWebhookUrl')) === url('/api/webhook')) return response(['error' => 'The external webhook URL cannot be the same as the internal API webhook URL.']);
    if (!empty($request->input('extWebhookData'))) {
      $extWebhookDataDecoded = is_array($request->input('extWebhookData')) ? $request->input('extWebhookData') : json_decode($request->input('extWebhookData'));
      if (json_last_error() !== JSON_ERROR_NONE)  return response(['error' => 'The external webhook data must be a valid JSON string.']);
    } else {
      $extWebhookDataDecoded = [];
    }

    $device = Device::where('id', '=', $request->input('device_id'))->first();
    if (auth()->user()->id != $device->user_id && auth()->user()->role !== 'admin') {
      return redirect()->back()->with(['danger_alert' => __('You are not allowed to edit Device')]);
    }
    $device->name = $request->input('name');
    $device->token = $request->input('token');
    $device->autoread = $request->input('autoread');
    $device->autoswitch = $request->input('autoswitch');
    $device->autoreply_group = $request->input('autoreply_group');
    $device->warmingup = $request->input('warmingup');
    $device->wu_receiver = $request->input('wu_receiver');
    $device->subscribe_keyword = $request->input('subscribe_keyword');
    $device->unsubscribe_keyword = $request->input('unsubscribe_keyword');
    $device->subscribe_message = $request->input('subscribe_message');
    $device->unsubscribe_message = $request->input('unsubscribe_message');
    $device->autoreply_pause = $request->input('autoreply_pause');
    $device->autoreply_pause_msg = $request->input('autoreply_pause_msg');
    $device->autoreply_resume = $request->input('autoreply_resume');
    $device->autoreply_resume_msg = $request->input('autoreply_resume_msg');
    $device->autoreply_reset = $request->input('autoreply_reset');
    $device->autoreply_reset_msg = $request->input('autoreply_reset_msg');
    $device->incall_msg = $request->input('incall_msg');
    $device->welcome_msg = $request->input('welcome_msg');
    $device->openai = json_encode([
      'apikey' => $request->input('openai_apikey'),
      'contain' => $request->input('openai_contain'),
      'model' => $request->input('openai_model'),
      'image_contain' => $request->input('openai_image_contain'),
      'image_model' => $request->input('openai_image_model'),
      'max_tokens' => $request->input('openai_max_tokens'),
      'save_chats' => $request->input('openai_save_chats'),
      'persona' => $request->input('openai_persona'),
      'geminiai_apikey' => $request->input('geminiai_apikey'),
      'geminiai_contain' => $request->input('geminiai_contain'),
      'geminiai_model' => $request->input('geminiai_model'),
      'geminiai_image_contain' => $request->input('geminiai_image_contain'),
      'geminiai_image_model' => $request->input('geminiai_image_model'),
      'geminiai_max_tokens' => $request->input('geminiai_max_tokens'),
      'geminiai_save_chats' => $request->input('geminiai_save_chats'),
      'geminiai_persona' => $request->input('geminiai_persona'),
    ]);
    if (!empty($request->input('open')) && !empty($request->input('closed'))) {
      $open = $request->input('open');
      $closed = $request->input('closed');
      if (str_contains($open, ':') && str_contains($closed, ':')) {
        $device->working_hours = json_encode([$open, $closed]);
      }
    }
    if (empty($request->input('webhook'))) {
      $device->webhook = url('/api/webhook');
    } else {
      $device->webhook = $request->input('webhook');
    }
    $device->ext_webhook = json_encode([
      'url' => $request->input('extWebhookUrl'),
      'data' => $extWebhookDataDecoded,
    ]);
    $device->save();
    return redirect()->back()->with(['success_alert' => __('Successfully edit') . ': ' . $device->sender]);
  }

  public function oaiDestroyChats(Request $request)
  {
    $device = Device::where('id', '=', $request->device_id)->first();
    if (!empty($device->user_id)) {
      if (auth()->user()->id != $device->user_id && auth()->user()->role !== 'admin') {
        return redirect()->back()->with(['danger_alert' => __('You are not allowed to delete Chat history')]);
      }
      $file = new Filesystem;
      $file->cleanDirectory(public_path("users/{$device->user_id}/oai/{$device->sender}"));
    }
    return redirect()->back()->with(['success_alert' => __('Delete OpenAI chat history files succesful')]);
  }

  public function gaiDestroyChats(Request $request)
  {
    $device = Device::where('id', '=', $request->device_id)->first();
    if (!empty($device->user_id)) {
      if (auth()->user()->id != $device->user_id && auth()->user()->role !== 'admin') {
        return redirect()->back()->with(['danger_alert' => __('You are not allowed to delete Chat history')]);
      }
      $file = new Filesystem;
      $file->cleanDirectory(public_path("users/{$device->user_id}/gai/{$device->sender}"));
    }
    return redirect()->back()->with(['success_alert' => __('Delete GeminiAI chat history files succesful')]);
  }

  public function destroy(Request $request)
  {
    $device = Device::where('id', '=', $request->device_id)->first();
    if (auth()->user()->id != $device->user_id && auth()->user()->role !== 'admin') {
      return redirect()->back()->with(['danger_alert' => __('You are not allowed to delete Device')]);
    }
    $response = Helpers::curlPost(rtrim(config('app.node_url'), '/') . '/delauth', ['token' => $device->token, 'logout' => true]);
    $res = json_decode($response);
    
    // Clean up device webhook file if exists
    $webhookFile = public_path("users/{$device->user_id}/assets/wh_{$device->sender}.php");
    if (file_exists($webhookFile)) {
      unlink($webhookFile);
    }
    
    $device->delete();
    return redirect()->back()->with([empty($res->success) ? 'danger_alert' : 'success_alert' => empty($res->message) ? __('Delete node server session files failed') : $res->message]);
  }
}
