<?php

namespace App\Imports;

use App\Jobs\CampaignCreateJob;
use App\Jobs\XLSXCampaignCreateJob;
use App\Models\Campaign;
use App\Models\Contact;
use App\Models\ContactGroup;
use App\Models\Group;
use App\Models\Label;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\SkipsErrors;
use Maatwebsite\Excel\Concerns\SkipsOnError;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Events\AfterImport;
use Maatwebsite\Excel\Events\BeforeImport;
use Maatwebsite\Excel\Events\ImportFailed;

class CampaignContactsImport implements ToCollection, WithHeadingRow, SkipsOnError, WithChunkReading, ShouldQueue, WithEvents
{
    use SkipsErrors;

    public $group_id = '';
    public $from;
    public $campaign_id;
    public $auth_user;
    public $body;
    public $start_date;
    public $end_date;
    public $start_time;
    public $end_time;

    public function __construct($customer, $campaign_id, $group_id, $from, $body, $start_date, $end_date, $start_time, $end_time)
    {
        $this->auth_user = $customer;
        $this->campaign_id = $campaign_id;
        $this->group_id = $group_id;
        $this->from = $from;
        $this->body = $body;
        $this->start_date = $start_date;
        $this->end_date = $end_date;
        $this->start_time = $start_time;
        $this->end_time = $end_time;
    }


    /**
     * @param Collection $rows
     * @throws \Throwable
     */
    public function collection(Collection $rows)
    {
        $rows=$rows->unique('number');
        $errorMsg = "";
        DB::beginTransaction();
        $label= $this->auth_user->labels()->where('title', 'new')->first();
        if (!$label) {
            $label = new Label();
            $label->title = 'new';
            $label->status = 'active';
            $label->customer_id = $this->auth_user->id;
            $label->color = 'red';
            $label->save();
        }
        $current_plans = $this->auth_user->plans;
        $pre_contacts=$this->auth_user->contacts()->count();
        foreach($current_plans as $current_plan){
            $max_contact = $current_plan->contact_limit;
        }
        $available_limit=$max_contact - $pre_contacts;
        $i = 0;
        $contactGroup = [];
        $data = [];

        $unique_random_number=Str::random(16);

        foreach ($rows as $key => $row) {
            if($current_plan->contact_limit=='no' && $available_limit =='0') {
                Log::info('Contact Limit Extend');
                throw new \Exception('Contact Limit Extend');
            }else {
                if (isset($row['number']) && $row['number']) {
                    $fullNumber = "+" . str_replace('+', '', $row['number']);
                    //You can validate other values using same steps.
                    $data[$i]['contact_dial_code'] = $fullNumber;
                    $data[$i]['number'] = $fullNumber;
                    $data[$i]['first_name'] = $row['first_name'] ?? '';
                    $data[$i]['last_name'] = $row['last_name'] ?? '';
                    $data[$i]['email'] = $row['email'] ?? '';
                    $data[$i]['company'] = $row['company'] ?? '';
                    $data[$i]['address'] = $row['address'] ?? '';
                    $data[$i]['city'] = $row['city'] ?? '';
                    $data[$i]['state'] = $row['state'] ?? '';
                    $data[$i]['zip_code'] = $row['zip_code'] ?? '';
                    $data[$i]['note'] = $row['note'] ?? '';
                    $data[$i]['label_id'] = $label ? $label->id : '';
                    $data[$i]['customer_id'] = $this->auth_user->id;
                    $data[$i]['unique_random_number'] = $unique_random_number;
                    $i++;
                }
            }
        }
        if($data){
            foreach (array_chunk($data, 1000) as $contactChunk) {
                Contact::insert($contactChunk);
            }
        }

        $contactIds=Contact::where('unique_random_number',$unique_random_number)->pluck('id');

        foreach ($contactIds as $contact_id) {
            $contactGroup[]=[
                'customer_id'=>$this->auth_user->id,
                'contact_id'=>$contact_id,
                'group_id'=>$this->group_id,
                'created_at'=>now(),
            ];
        }

        foreach (array_chunk($contactGroup, 1000) as $contactGroupChunk) {
            ContactGroup::insert($contactGroupChunk);
        }


        if (!empty($errorMsg)) {
            DB::rollBack();
        } else {
            DB::commit();
        }
    }

    public function chunkSize(): int
    {
        return 2000;
    }

    public function registerEvents(): array
    {
        return [
            ImportFailed::class => function (ImportFailed $event) {
                Group::where('id', $this->group_id)->update(['import_status' => 'failed', 'import_fail_message' => substr($event->getException(), 0, 191)]);
                Campaign::where('id',  $this->campaign_id)->update(['status' => 'failed', 'import_fail_message' => substr($event->getException(), 0, 191)]);
            },
            BeforeImport::class => function (BeforeImport $event) {
                Group::where('id', $this->group_id)->update(['import_status' => 'running']);
            },
            AfterImport::class => function (AfterImport $event) {
               Group::where('id', $this->group_id)->update(['import_status' => 'completed']);
                XLSXCampaignCreateJob::dispatch($this->from,$this->auth_user->id,$this->group_id, $this->campaign_id, $this->body,$this->start_date,$this->end_date,$this->start_time, $this->end_time);
            }
        ];
    }

}
