<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\CreateListRequest;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\JsonResponse;
use App\Models\Lists;
use App\Http\Helper\Helper;
use Auth;

class ListController extends Controller
{ 
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    function __construct()
    {
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(): View
    {
        Helper::checkPermissions('lists_manage');
        $page = 'lists_manage';
        $page_title = __('app.lists');
        $breadcrumbs = [
            __('app.lists') => route('lists.index'),
            __('app.manage') => '#'
        ];
        $groups = \App\Models\Group::groups(config('custom.group_lists'));
        return view('lists.index',compact('page', 'page_title', 'breadcrumbs', 'groups'));
    }

    /**
       * Retrun JSON datatable data
    */
    public function getLists(Request $request): Void
    {
        $result = Lists::join('groups', 'groups.id', '=', 'lists.group_id')
        ->select('lists.id', 'lists.name as name', 'lists.created_at', 'groups.id as group_id', 'groups.name as group_name', 'lists.total_contacts')
        ->app();

        // error occured while search contacts_count
        if(!empty($request->get('search')['value'])) {
            $columns = ['lists.id', 'lists.id', 'lists.name', 'groups.name', 'lists.id', 'lists.created_at'];
        } else {
            $columns = ['lists.id', 'lists.id', 'lists.name', 'groups.name', 'contacts_count', 'lists.created_at'];
        }

        $data = Helper::dataFilters($request, $result, $columns);

        $result = $data['result'];
        $lists = $result->get();

        $data =  Helper::datatableTotals($data['total']);

        foreach($lists as $list) {
          $checkbox = "<input type=\"checkbox\" value=\"{$list->id}\" class=\"form-check-input\">";

          $group_name = "<span id='{$list->group_id}'>$list->group_name<span>";
          $contacts = "<a class='link-info' href='".route('contacts.index', ['list_id' => $list->id])."'>{$list->total_contacts}</a>";

          $actions = '<div class="btn-group">';
          $actions .= '<button type="button" class="btn btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">'.__('app.actions').'</button>';
          $actions .= '<ul class="dropdown-menu" style="">';
          $actions .= '<li><a class="dropdown-item" href="javascript:;" onclick="viewModal(\'modal\', \''.route('lists.show', [$list->id]).'\')"><i class="bi bi-eye"></i> '.__('app.view').'</a></li>';
          $actions .= '<li><a class="dropdown-item" href="'.route('lists.edit', $list->id).'"><i class="bi bi-pencil-square"></i> '.__('app.edit').'</a></li>';
          $actions .= '<li><a class="dropdown-item" href="'.route('contacts.create', ['list_id' => $list->id]).'"><i class="bi bi-person-add"></i> '.__('app.add_new_contact').'</a></li>';
          $actions .= '<li><a class="dropdown-item" href="'.route('contacts.import', [$list->id]).'"><i class="bi bi-download"></i> '.__('app.import').'</a></li>';
          
          if(Helper::checkPermissions('list_export')) {
            $actions .= '<li><a class="dropdown-item" href="javascript:;" onclick="viewModal(\'modal\', \''.route('contacts.export', [$list->id, 'show_modal']).'\', \''.__('app.msg_export_list').'\')"><i class="bi bi-upload"></i> '.__('app.export').'</a></li>';  
          }

          $actions .= '<li><a class="dropdown-item" href="'.route('list.copy', ['id' => $list->id]).'"><i class="bi bi-copy"></i> '.__('app.copy').'</a></li>';
          $actions .= '<li><a class="dropdown-item" href="javascript:;" onclick="move(\''.$list->id.'\', \''.htmlentities($list->name).'\')"><i class="bi bi-arrows"></i> '.__('app.move').'</a></li>';
          $actions .= '<li><a class="dropdown-item" href="javascript:;" onclick="viewModal(\'modal\', \''.route('list.split', ['id' => $list->id]).'\')"><i class="bi bi-layout-split"></i> '.__('app.split').'</a></li>';
          $actions .= '<li><a class="dropdown-item" href="javascript:;" onclick="emptyList(\''.$list->id.'\', \''.route('list.empty', ['id' => $list->id]).'\', \''.__('app.msg_list_empty').'\')"><i class="bi bi-trash2"></i> '.__('app.empty').'</a></li>';
          $actions .= '<li><a class="dropdown-item text-danger" href="javascript:;" onclick="destroy(\''.$list->id.'\', \''.route('lists.destroy', $list->id).'\')"><i class="bi bi-trash"></i> '.__('app.delete').'</a></li>';
          $actions .= '</ul>';

          $data['data'][] = [
            "DT_RowId" => "row_{$list->id}",
            $checkbox,
            '<a class="link-info" href="javascript:;" onclick="viewModal(\'modal\', \''.route('lists.show', [$list->id]).'\')">'.$list->id.'</a>',
            $list->name,
            $group_name,
            $contacts,
            Helper::datetimeDisplay($list->created_at),
            $actions
            ];
        }
        echo json_encode($data);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(): View
    {
        Helper::checkPermissions('add_new_list');
        $page = 'lists_create';
        $page_title = __('app.add_new_list');
        $breadcrumbs = [
            __('app.lists') => route('lists.index'),
            __('app.add_new_list') => '#'
        ];
        
        $groups = \App\Models\Group::groups(config('custom.group_lists'));
        $custom_fields = \App\Models\CustomField::customFields();
        $sending_domains = \App\Models\SendingDomain::getSendingDomains();
        return view('lists.create',compact('page', 'page_title', 'breadcrumbs', 'groups', 'custom_fields', 'sending_domains'));
      }
    
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(CreateListRequest $request): RedirectResponse
    {
        
        $data = $this->_listData($request);
        $list = Lists::create($data);

        if(!empty($data['custom_fields'])) {
            $custom_field_ids = array_values($data['custom_fields']);
            $list->customFields()->attach($custom_field_ids);
        }

        activity('create')->withProperties(['app_id' => Auth::user()->app_id])->log(__('app.list') . " ({$request->name}) ". __('app.log_create'));

        if(isset($data['save_continue']))
            return redirect()->route('lists.create')
            ->with('success', ($request->email . ' ' . __('app.created_successfully')));
        else
            return redirect()->route('lists.index')
            ->with('success', ($request->email . ' ' . __('app.created_successfully')));
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\list  $list
     * @return \Illuminate\Http\Response
     */
    public function show(Lists $list): View
    {        
        return view('lists.view')->with('list', $list);
    }
    
    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\list  $list
     * @return \Illuminate\Http\Response
     */
    public function edit(Lists $list): View
    {
        Helper::checkPermissions('add_new_list');
        $page = 'lists_create';
        $page_title = __('app.edit_list');
        $breadcrumbs = [
            __('app.lists') => route('lists.index'),
            __('app.edit_list') => '#'
        ];
        $list_custom_fields = $list->getCustomFieldId()->toArray();
        $groups = \App\Models\Group::groups(config('custom.group_lists'));
        $custom_fields = \App\Models\CustomField::customFields();
        $sending_domains = \App\Models\SendingDomain::getSendingDomains();
        return view('lists.edit')->with(compact('page', 'page_title', 'breadcrumbs', 'list', 'list_custom_fields', 'groups', 'custom_fields', 'sending_domains'));
    }
    
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\list  $list
     * @return \Illuminate\Http\Response
     */
    public function update(CreateListRequest $request, Lists $list): RedirectResponse
    {
        $data = $this->_listData($request);
        $list->fill($data)->save();

        if(!empty($data['custom_fields'])) {
          $custom_field_ids = array_values($data['custom_fields']);
          $list->customFields()->sync($custom_field_ids);
        }
        activity('update')->withProperties(['app_id' => Auth::user()->app_id])->log(__('app.list') . " ({$request->name}) ". __('app.log_update'));

        return redirect()->route('lists.edit', $list->id)
        ->with('success', ($request->name . ' ' . __('app.updated_successfully')));
    }

    /**
      * Make empty a list
    */
    public function empty(int $id)
    {
        $empty = \App\Models\Contact::whereListId($id)->forceDelete();
        return $empty;
    }


    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\list  $list
     * @return \Illuminate\Http\Response
     */
    public function destroy(int $id, Request $request): JsonResponse
    {
        if(!empty($request->action)) {
            $ids = array_values($request->ids);
            $names = json_encode(array_values(Lists::whereIn('id', $ids)->pluck('name')->toArray()));
            $destroy = Lists::whereIn('id', $ids)->delete();
        } else {
            $names = Lists::whereId($id)->value('name');
            $destroy = Lists::destroy($id);
        }
        activity('delete')->withProperties(['app_id' => Auth::user()->app_id])->log(__('app.list') . " ({$names}) ". __('app.log_delete'));

        $data = [
          'success' => true,
          'message' => __('app.deleted_successfully')
        ];

        return response()->json($data, 200);
    }

    /**
    * Retrun data for store or update
    */
    private function _listData($request): Array
    {
        $input = $request->except('_token');
        $input['from_email'] = $input['from_email_part1'] . '@' . $input['from_email_part2'];
        $input['user_id'] = Auth::user()->id;
        $input['app_id'] = Auth::user()->app_id;
        return $input;
    }

    /**
    * Retrun to index page after copy the list
    */
    public function copy(int $id): RedirectResponse
    {
        $list = Lists::whereId($id)->app()->first();
        $list->name = $list->name .' - copy ';
        $list = $list->replicate();
        $list->save();

        activity('copy')->withProperties(['app_id' => Auth::user()->app_id])->log(__('app.list') . " ({$list->name}) ". __('app.log_copy')); // log

        return redirect()->route('lists.index')
            ->with('success', ($list->name . ' ' . __('app.copied_successfully')));
    }

    /**
    * Split a list
    */
    public function split($id, Request $request)
    {
        if ($request->isMethod('post')) {
          $request->validate([
            'no_of_lists' => 'required|integer|min:2',
          ]);

          if($request->no_of_lists > 0) {
            $list_contacts = \App\Models\Contact::whereListId($id)->count();
            $list = Lists::findOrFail($id);
            if($list_contacts > 1) {
                $no_of_lists = $request->no_of_lists;            
                $list_custom_fields = $list->getCustomFieldId()->toArray();
                $list_name = $list->name;
                $no_of_contacts_per_list = $list_contacts / $no_of_lists;
                for($i=1; $i<$no_of_lists; $i++) {
                  // create new list
                  $list->name = $list_name." - $i";
                  $new_list = $list->replicate();
                  $new_list->save();
                  $new_list->customFields()->attach($list_custom_fields);
                  // move contacts to new list
                  \App\Models\Contact::whereListId($id)->limit($no_of_contacts_per_list)->update(['list_id' => $new_list->id]);
                }
                activity('split')->withProperties(['app_id' => Auth::user()->app_id])->log(__('app.list') . " ({$list_name}) ". __('app.log_split'));

                return redirect()->route('lists.index')
                ->with('success', ($list->name . ' ' . __('app.copied_successfully')));
            } else {
                return redirect()->route('lists.index')
                ->with('error', ($list->name . ': ' . __('app.msg_list_has_only_one_contact')));

            }
          }
        } else {
          $list = Lists::findOrFail($id);
          return view('lists.split')->with('list', $list);
        }
    }

    /**
    * Bulk update list contacts
    */
    public function bulkUpdate(Request $request)
    {
        Helper::checkPermissions('bulk_update');
        if($request->isMethod('post')) {
            switch($request->action) {
              case 'active':
                $value = 'is_active';
                $status = true;
                break;
              case 'inactive':
                $value = 'is_active';
                $status = false;
                break;
              case 'confirmed':
                $value = 'is_confirmed';
                $status = true;
                break;
              case 'unconfirmed':
                $value = 'is_confirmed';
                $status = false;
                break;
              case 'subscribed':
                $value = 'is_unsubscribed';
                $status = false;
                break;
              case 'unsubscribed':
                $value = 'is_unsubscribed';
                $status = true;
                break;
              case 'verified':
                $value = 'is_verified';
                $status = true;
                break;
              case 'inactive':
                $value = 'is_verified';
                $status = false;
                break;
            }

            $request->validate([
              'list_ids' => 'required|array|min:1'
            ],
            [
              'list_ids.required' => 'The list is required.',
              'list_ids.min' => 'You must select at least one list.',
            ]);

            if($request->option == 'write') {
              $request->validate([
                'emails' => 'required'
              ],[
                'emails.required' => 'Emails are required.',
              ]);
              $emails = Helper::splitLineBreakWithComma($request->emails);
              foreach($emails as $email) {
                \App\Models\Contact::whereEmail(trim($email))->whereIn('list_id', $request->list_ids)->update([$value => $status]);
              }
            } else {
              $request->validate([
                'file' => 'required|mimes:csv,txt|max:'.Helper::getMaxFileSizeMB()
              ]);
              $file = $request->file('file');
              $reader = \League\Csv\Reader::createFromPath($file->getPathName(), 'r');
              $records = $reader->getRecords();
              foreach ($records as $offset => $record) {
                \App\Models\Contact::whereEmail(trim($record[0]))->whereIn('list_id', $request->list_ids)->update([$value => $status]);
              }
            }
        }
        return view('lists.bulk_update');
    }

}
