<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Apptitle;
use App\Models\CampaignUserList;
use App\Models\Footertext;
use App\Models\LiveChatCustomers;
use App\Models\Seosetting;
use Illuminate\Http\Request;
use App\Imports\CustomerImport;
use App\Jobs\BulkMails;
use App\Models\CampaignTemplates;
use App\Models\EmailCampaigns;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use Torann\GeoIP\Facades\GeoIP;
use Jenssegers\Agent\Agent;
use App\Models\EmployeeActivity;
use Illuminate\Support\Facades\Auth;

class EmailCampaignController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $this->authorize('Users List Access');

        $basic = Apptitle::first();
        $data['basic'] = $basic;

        $title = Apptitle::first();
        $data['title'] = $title;

        $footertext = Footertext::first();
        $data['footertext'] = $footertext;

        $seopage = Seosetting::first();
        $data['seopage'] = $seopage;

        $users = CampaignUserList::get();
        $data['users'] = $users;

        $batchnames = CampaignUserList::distinct('batchName')->pluck('batchName')->filter(function ($item) {
            return $item != null;
        });
        $data['batchnames'] = $batchnames;

        return view('admin.emailCampaigns.customer.customersList')->with($data);
    }

    public function userImport(Request $request)
    {
        $this->authorize('Users List Import');
        $basic = Apptitle::first();
        $data['basic'] = $basic;

        $title = Apptitle::first();
        $data['title'] = $title;

        $footertext = Footertext::first();
        $data['footertext'] = $footertext;

        $seopage = Seosetting::first();
        $data['seopage'] = $seopage;

        return view('admin.emailCampaigns.customer.customerimport')->with($data);
    }

    public function userImportSave(Request $req)
    {
        if ($req->hasFile('file')) {
            $file = $req->file('file')->store('import');
            if ($req->file->getClientOriginalExtension() == 'xlsx' || $req->file->getClientOriginalExtension() == 'csv') {

                $batchName = $req->batchName ?? now()->format('Y-m-d');

                $import = Excel::import(new CustomerImport($batchName), $file);

                $geolocation = GeoIP::getLocation(request()->getClientIp());
                $agent = new Agent();
                $activity = new EmployeeActivity();
                $activity->user_id = Auth::user()->id;
                $activity->activity_type = 'Email Compain Customer list imported';
                $activity->ip_address = $geolocation->ip;
                $activity->browser = $agent->browser();
                $activity->device = $agent->device();
                $activity->save();

                return redirect(url('admin/emailCampaigns/users'))->with('success', lang('The Customer list was imported successfully.', 'alerts'));
            }
            return redirect()->back()->with('error', lang('Please choose a valid file.', 'alerts'));
        } else {
            return redirect()->back()->with('error', lang('Please select file to import data of Customer.', 'alerts'));
        }
    }

    public function store(Request $req)
    {
        $this->authorize('Users Create');
        $validator = Validator::make($req->all(), [
            'email' => 'required|email|indisposable|max:255',
        ]);
        if ($validator->passes()) {

            $userExists = CampaignUserList::where('email',$req->email)->first();
            if($userExists != null){
                return response()->json(['error' => lang('User already existed with this email address.', 'alerts'), 'message' => 'userexisted']);
            }

            CampaignUserList::create([
                'email' => $req->email,
                'source' => 'Created',
                'batchName' => $req->batchName,
            ]);

            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Email Compain User Created';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();

            return response()->json(['success' => lang('User added successfully.', 'alerts'), 'data' => CampaignUserList::all()]);
        }
        return response()->json(['errors' => $validator->errors()]);
    }

    public function delete(CampaignUserList $id)
    {
        $this->authorize('Users Delete');
        if ($id) {
            $id->delete();
            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Email Compain User Deleted';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();
            return response()->json(['success' => lang('User deleted successfully.', 'alerts')]);
        }
        return response()->json('error', true);
    }

    public function status(Request $request)
    {
        $this->authorize('Users Status');
        $user = CampaignUserList::find($request->id);
        $user->status = $request->status == 'false' ? '0' : '1';
        $user->update();

        $geolocation = GeoIP::getLocation(request()->getClientIp());
        $agent = new Agent();
        $activity = new EmployeeActivity();
        $activity->user_id = Auth::user()->id;
        $activity->activity_type = 'Email Compain User Status Changed';
        $activity->ip_address = $geolocation->ip;
        $activity->browser = $agent->browser();
        $activity->device = $agent->device();
        $activity->save();

        if($request->status == 'false'){
            return Response::json(['success' => lang('User unsubscribed successfully.', 'alerts')]);
        }else{
            return Response::json(['success' => lang('User subscribed successfully.', 'alerts')]);
        }

    }

    public function massdelete(Request $request)
    {
        $this->authorize('Users Delete');

        $users = CampaignUserList::find($request->id);
        if ($users) {
            foreach ($users as $user) {
                $user->delete();
            }
        }

        $geolocation = GeoIP::getLocation(request()->getClientIp());
        $agent = new Agent();
        $activity = new EmployeeActivity();
        $activity->user_id = Auth::user()->id;
        $activity->activity_type = 'Multiple Email Compain Users Deleted';
        $activity->ip_address = $geolocation->ip;
        $activity->browser = $agent->browser();
        $activity->device = $agent->device();
        $activity->save();

        return response()->json(['success' => lang('Users deleted successfully', 'alerts')]);
    }

    public function emailCampaigns()
    {
        $this->authorize('All Email Campaigns Access');

        $basic = Apptitle::first();
        $data['basic'] = $basic;

        $title = Apptitle::first();
        $data['title'] = $title;

        $footertext = Footertext::first();
        $data['footertext'] = $footertext;

        $seopage = Seosetting::first();
        $data['seopage'] = $seopage;

        $allCampaigns = EmailCampaigns::all();
        $data['allCampaigns'] = $allCampaigns;

        return view('admin.emailCampaigns.index')->with($data);
    }

    public function emailCampaignsCreate()
    {
        $this->authorize('Email Campaigns Create');

        $basic = Apptitle::first();
        $data['basic'] = $basic;

        $title = Apptitle::first();
        $data['title'] = $title;

        $footertext = Footertext::first();
        $data['footertext'] = $footertext;

        $seopage = Seosetting::first();
        $data['seopage'] = $seopage;

        $batches = CampaignUserList::where('status', '1')->distinct('batchName')->pluck('batchName')->filter(function ($item) {
            return $item != null;
        });
        $data['batches'] = $batches;

        $livecustomers = CampaignUserList::where('status', '1')->distinct('email')->where('source', 'Livechat')->pluck('email');
        $data['livecustomers'] = $livecustomers;

        $allUsers = CampaignUserList::where('status', '1')->distinct('email')->pluck('email');
        $data['allUsers'] = $allUsers;

        $templates = CampaignTemplates::all();
        $data['templates'] = $templates;

        $newslettercustomers = CampaignUserList::where('status', '1')->distinct('email')->where('source', 'News Letter')->pluck('email');
        $data['newslettercustomers'] = $newslettercustomers;

        return view('admin.emailCampaigns.create')->with($data);
    }

    public function emailCampaignssend(Request $request)
    {
        $this->authorize('Email Campaigns Create');

        $validator = Validator::make($request->all(), [
            'sendType' => 'required|string',
            'subject' => 'required|string',
            'message' => 'required|string',
            'selectedUsers' => $request->sendType == 'individualUsers' ? 'required' : '',
            'batchName' => $request->sendType == 'batch' ? 'required' : '',
            'livechatUsersSelect' => $request->sendType == 'livechat' ? 'required' : '',
        ]);
        if ($validator->passes()) {

            if ($request->sendType == 'individualUsers') {
                $uniqueUsers = array_unique($request->selectedUsers);
                $uniqueUsers = array_values($uniqueUsers);
            }
            if ($request->sendType == 'batch') {
                $uniqueUsers = CampaignUserList::where('status', '1')->whereIn('batchName', $request->batchName)->distinct('email')->pluck('email')->toArray();
            }
            if ($request->sendType == 'livechat') {
                $uniqueUsers = array_unique($request->livechatUsersSelect);
                $uniqueUsers = array_values($uniqueUsers);
            }
            if ($request->sendType == 'newsletter') {
                $uniqueUsers = array_unique($request->newsletterUsersSelect);
                $uniqueUsers = array_values($uniqueUsers);
            }

            $campaign = new EmailCampaigns();
            $campaign->title = $request->subject;
            $campaign->type = $request->sendType;
            $campaign->status = $request->time != null ? lang('Scheduled to') . ' ' . $request->time : lang('Sent Immediately');
            $campaign->scheduledTime = $request->time ?? '';
            $campaign->users = json_encode($uniqueUsers);
            $campaign->save();

            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Email Campaign Sent';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();

            if (!isset($request->time)) {
                try {
                    $batchSize = 50;

                    $delayBetweenBatches = 5;

                    // Split customers into batches
                    $chunks = collect($uniqueUsers)->chunk($batchSize);
                    foreach ($chunks as $batchIndex => $batch) {
                        $batchDelay = $batchIndex * $delayBetweenBatches;
                        foreach ($batch as $email) {
                            dispatch((new BulkMails($email, $request->message, $campaign->title))->delay(now()->addMinutes($batchDelay)));
                        }
                    }
                } catch (\Throwable $th) {
                    return Response::json(['success' => lang('Campaign sent successfully.')]);
                }
                return Response::json(['success' => lang('Campaign sent successfully.')]);
            } else {
                $campaign->message = $request->message;
                $campaign->save();
                return Response::json(['success' => lang('Campaign scheduled successfully')]);
            }
        } else {
            return Response::json('fail', true);
        }
    }

    public function emailCampaignsDelete(EmailCampaigns $id)
    {
        $this->authorize('Campaigns Delete');
        if ($id) {
            $id->delete();

            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Email Campaign Deleted';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();

            return response()->json(['success' => lang('Campaign deleted successfully.', 'alerts')]);
        }
        return response()->json('error', true);
    }
    public function emailCampaignsMassDelete(Request $request)
    {
        $this->authorize('Campaigns Delete');
        $campaigns = EmailCampaigns::find($request->id);
        if ($campaigns) {
            foreach ($campaigns as $campaign) {
                $campaign->delete();
            }
        }

        $geolocation = GeoIP::getLocation(request()->getClientIp());
        $agent = new Agent();
        $activity = new EmployeeActivity();
        $activity->user_id = Auth::user()->id;
        $activity->activity_type = 'Email Campaigns Deleted';
        $activity->ip_address = $geolocation->ip;
        $activity->browser = $agent->browser();
        $activity->device = $agent->device();
        $activity->save();

        return response()->json(['success' => lang('Campaigns deleted successfully', 'alerts')]);
    }

    public function templates()
    {
        $this->authorize('Templates Access');

        $basic = Apptitle::first();
        $data['basic'] = $basic;

        $title = Apptitle::first();
        $data['title'] = $title;

        $footertext = Footertext::first();
        $data['footertext'] = $footertext;

        $seopage = Seosetting::first();
        $data['seopage'] = $seopage;

        $templates = CampaignTemplates::all();
        $data['templates'] = $templates;

        return view('admin.emailCampaigns.templates.index')->with($data);
    }

    public function templatesCreate()
    {
        $this->authorize('Templates Create');

        $basic = Apptitle::first();
        $data['basic'] = $basic;

        $title = Apptitle::first();
        $data['title'] = $title;

        $footertext = Footertext::first();
        $data['footertext'] = $footertext;

        $seopage = Seosetting::first();
        $data['seopage'] = $seopage;

        return view('admin.emailCampaigns.templates.create')->with($data);
    }

    public function templatesCreateStore(Request $request)
    {
        $this->authorize('Templates Create');

        $validator = Validator::make($request->all(), [
            'title' => 'required|string|max:255|unique:campaign_templates',
            'subject' => 'required|string|max:255',
            'message' => 'required',
        ]);

        if ($validator->passes()) {
            CampaignTemplates::create([
                'title' => $request->title,
                'subject' => $request->subject,
                'message' => $request->message,
            ]);

            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Email Compain Template Create';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();

            return Response::json(['success' => lang('Template created successfully')]);
        }
        return Response::json(['errors' => $validator->errors()]);
    }

    public function templatesEdit($temp)
    {
        $this->authorize('Templates Edit');

        $basic = Apptitle::first();
        $data['basic'] = $basic;

        $title = Apptitle::first();
        $data['title'] = $title;

        $footertext = Footertext::first();
        $data['footertext'] = $footertext;

        $seopage = Seosetting::first();
        $data['seopage'] = $seopage;

        $temp = CampaignTemplates::findOrFail($temp);
        $data['template'] = $temp;

        return view('admin.emailCampaigns.templates.edit')->with($data);
    }

    public function templatesCreateUpdate(Request $request)
    {
        $this->authorize('Templates Edit');
        $template = CampaignTemplates::find($request->id);

        $validator = Validator::make($request->all(), [
            'title' => ($request->title != null && $template->title == $request->title) ? '' : 'required|string|max:255|unique:campaign_templates',
            'subject' => 'required|string|max:255',
            'message' => 'required',
        ]);

        if ($validator->passes()) {
            $template->title = $request->title;
            $template->subject = $request->subject;
            $template->message = $request->message;
            $template->update();

            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Email Compain Template Updated';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();

            return Response::json(['success' => lang('Template updated successfully')]);
        }
        return Response::json(['errors' => $validator->errors()]);
    }

    public function templatesDeleteUpdate(CampaignTemplates $id)
    {
        $this->authorize('Templates Delete');
        if ($id) {
            $id->delete();

            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Email Compain Template Deleted';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();

            return response()->json(['success' => lang('Template deleted successfully.', 'alerts')]);
        }
        return response()->json('error', true);
    }

    public function templatesMassDeleteUpdate(Request $request)
    {
        $this->authorize('Templates Delete');
        $users = CampaignTemplates::find($request->id);
        if ($users) {
            foreach ($users as $user) {
                $user->delete();
            }
        }

        $geolocation = GeoIP::getLocation(request()->getClientIp());
        $agent = new Agent();
        $activity = new EmployeeActivity();
        $activity->user_id = Auth::user()->id;
        $activity->activity_type = 'Multiple Email Compain Templates Deleted';
        $activity->ip_address = $geolocation->ip;
        $activity->browser = $agent->browser();
        $activity->device = $agent->device();
        $activity->save();

        return response()->json(['success' => lang('Templates deleted successfully', 'alerts')]);
    }
}
