<?php

namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithPagination;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Mail;
use Illuminate\Contracts\Validation\Validator;

class RecordIN extends Component
{
    use WithPagination;
    protected $paginationTheme = 'bootstrap';

    protected $listeners = ['setCausal' => 'setCausal','refreshMembers' => 'refreshMembers'];

    public $sortField ='date';
    public $sortAsc = false;

    public $typeIN = "IN";

    public $fromPage = '';

    public $isDuplicate = false;
    public $multiP = false;
    public $from, $to;

    public $multiMonthTo = 0;
    public $multiYearTo = 0;
    public $multiMonthFrom = 0;
    public $multiYearFrom = 0;
    public $createSubscription = 0;

    public $corrispettivo_causal_id = 0;

    public function sortBy($field)
    {
        if($this->sortField === $field)
        {
            $this->sortAsc = ! $this->sortAsc;
        } else {
            $this->sortAsc = true;
        }

        $this->sortField = $field;
    }

    public $courseId = 0;
    public $months = array();

    public $records, $dataId, $member_id, $supplier_id,
    $causal_id,
    $payment_method_id,
    $destination_id,
    $date,
    $month,
    $year,
    $type,
    $deleted,
    $financial_movement,
    $amount,
    $vat,
    $virtual,
    $note,
    $parent,
    $corrispettivo_fiscale,
    $commercial, $update = false, $add = false;

    public $corrispettivo = [];
    public $corrispettivo_destination = [];

    public $currentReceip;

    public $filterMember = 0, $filterPaymentMethod = 0, $filterCausals = 0, $filterFrom = '', $filterTo = '', $filterCommercial = 0;

    public $hasFilter = false;

    public $total = 0;

    public $selectedFilter = '';

    public $multipleIds = [];
    public $multipleAction = '';

    public $first = true;

    public $selectId = 0;
    public $refreshAfter = 0;

    public $canSave = true;

    public $newMemberFirstName = '';
    public $newMemberLastName = '';
    public $newMemberEmail = '';
    public $newMemberToComplete = false;
    public $newMemberFiscalCode = '';
    public $newMemberFiscalCodeExist = false;
    public $newMemberExists = false;

    public $causals = array();
    public $payments = array();
    public $banks = array();
    public $members = array();
    public $vats = array();

    public $rows = array();

    protected $rules = [
        'member_id' => 'required',
        'payment_method_id' => 'required',
        'rows.*.causal_id' => 'required',
        'rows.*.amount' => 'required'
    ];

    protected $messages = [
        'member_id.required' => 'La persona è obbligatorio',
        'payment_method_id.required' => 'Il metodo di pagamento è obbligatorio',
        'rows.*.causal_id.required' => 'La causale è obbligatoria',
        'rows.*.amount.required' => 'L\'importo è obbligatorio',
    ];

    public function updatedMemberId() {
        
        if ($this->member_id > 0)
        {
            $member = \App\Models\Member::findOrFail($this->member_id);
            if (!$member->isAdult())
            {
                if($member->father_name != '')
                    $this->parent = $member->father_name . " (C.F. " . $member->father_fiscal_code . ")";
                else if($member->mother_name != '')
                    $this->parent = $member->mother_name . " (C.F. " . $member->mother_fiscal_code . ")";
                else
                    $this->parent = '';
            }
            $this->virtual = $member->getMoney();
            $this->newMemberFirstName = '';
            $this->newMemberLastName = '';
            $this->newMemberEmail = '';
            $this->newMemberToComplete = false;
            $this->newMemberFiscalCode = '';
            $this->newMemberFiscalCodeExist = false;
        }
        $this->emit('refresh');
    }

    public function updatedCausalId() {
        //$this->emit('refresh');
    }

    public function updatedDate() {
        //$this->emit('refresh');
    }

    public function hydrate()
    {
        $this->emit('load-select');
    }

    /*public function updated() {
        $this->emit('refresh');
    }*/

    public function updatedPaymentMethodId() {
        //$this->emit('refresh');

        if ($this->payment_method_id) {
            $payment_method = \App\Models\PaymentMethod::findOrFail($this->payment_method_id);
            $this->destination_id = $payment_method->destination_id ?? null;
        }

        $this->canSave = $this->checkCanSave();
    }

    public function updatedCorrispettivoFiscale() {
        if ($this->corrispettivo_fiscale) {
            foreach ($this->payments as $payment) {
                if ($payment->corrispettivo_fiscale) {
                    $this->corrispettivo_destination[$payment->id] = $payment->destination_id;
                }
            }
        }
    }

    public function updatedAmount() {
        // $this->emit('refresh');
        $this->canSave = $this->checkCanSave();
    }
    public function updatedCommercial($value)
    {
        $this->emitSelf('refreshMembers');
    }


    public function checkCanSave()
    {
        $ret = true;
        if ($this->payment_method_id != null)
        {
            $payment_method = \App\Models\PaymentMethod::findOrFail($this->payment_method_id);
            if ($payment_method->money)
            {
                $from = str_replace(".", "", str_replace(",", "", number_format($this->virtual, 2)));
                $this->from = $this->virtual;
                $from = $this->from;
                $to = str_replace(".", "", str_replace(",", "", $this->currencyToDouble($this->amount)));
                $this->to = $this->amount;
                $to = $this->to;
                $ret = $from >= $to;
            }
        }
        return $ret;
    }

    public function setAmount()
    {
        $tot = 0;
        foreach($this->rows as $r)
        {
            $tot += $this->currencyToDouble($r["amount"]);
        }
        $this->amount = $tot;
        $this->canSave = $this->checkCanSave();
    }

    public function refreshMembers()
    {
        if ($this->add || $this->update)
        {
            if($this->commercial){
                $this->members = \App\Models\Member::select(['id', 'first_name', 'last_name', 'fiscal_code'])
                    ->where(function($query) {
                        $query->where('is_archived', false)
                            ->orWhereNull('is_archived');
                    })
                    ->where(function($query) {
                        $query->where('is_deleted', false)
                            ->orWhereNull('is_deleted');
                    })->orderBy('last_name')->orderBy('first_name')->get();
            } else {
                $this->members = \App\Models\Member::select(['id', 'first_name', 'last_name', 'fiscal_code'])->where('current_status', 2)->orWhere('current_status', 1)
                    ->where(function($query) {
                        $query->where('is_archived', false)
                            ->orWhereNull('is_archived');
                    })
                    ->where(function($query) {
                        $query->where('is_deleted', false)
                            ->orWhereNull('is_deleted');
                    })->orderBy('last_name')->orderBy('first_name')->get();
            }
        }
        else
            $this->members = \App\Models\Member::select(['id', 'first_name', 'last_name', 'fiscal_code'])
                ->where(function($query) {
                    $query->where('is_archived', false)
                        ->orWhereNull('is_archived');
                })
                ->where(function($query) {
                    $query->where('is_deleted', false)
                        ->orWhereNull('is_deleted');
                })->orderBy('last_name')->orderBy('first_name')->get();
    }

    public function resetFields(){
        $this->member_id = null;
        $this->supplier_id = null;
        $this->payment_method_id = null;
        $this->destination_id = null;
        $this->commercial = 0;
        $this->corrispettivo_fiscale = false;
        $this->date = date("Y-m-d");
        $this->type = 'IN';
        $this->deleted = false;
        $this->financial_movement = false;
        $this->newMemberFirstName = '';
        $this->newMemberLastName = '';
        $this->newMemberEmail = '';
        $this->newMemberToComplete = false;
        $this->newMemberFiscalCode = '';
        $this->newMemberFiscalCodeExist = false;
        $this->newMemberExists = false;
        $this->currentReceip = null;
        $this->parent = '';
        $this->courseId = 0;
        $this->months = array();
        $this->rows = array();
        $this->rows[] = array('causal_id' => isset($_GET["causalId"]) ? $_GET["causalId"] : null, 'when' => array(array('month' => date("n"), 'year' => date("Y"), 'period' => '')),  'amount' => null, 'vat_id' => null, 'note' => '', 'commercial' => 0);
        $this->corrispettivo = [];
        $this->corrispettivo_destination = [];
        $this->emit('load-data-table');
    }

    public function getMemberProperty()
    {
        $ret = null;
        if ($this->member_id > 0)
        {
            $ret = \App\Models\Member::findOrFail($this->member_id);
        }
        return $ret;
    }

    public function getCausalProperty()
    {
        $ret = null;
        if ($this->causal_id > 0)
        {
            $ret = \App\Models\Causal::findOrFail($this->causal_id);
        }
        return $ret;
    }

    public function getCausal($causal)
    {
        $ret = '';
        if ($causal > 0)
        {
            $ret = \App\Models\Causal::findOrFail($causal)->getTree();
        }
        return $ret;
    }

    public function getPaymentMethod($payment)
    {
        $ret = '';
        if ($payment > 0)
        {
            $ret = \App\Models\PaymentMethod::findOrFail($payment)->name;
        }
        return $ret;
    }

    public function getBankName($bank_id)
    {
        $ret = '';
        if ($bank_id > 0)
        {
            $ret = \App\Models\Bank::findOrFail($bank_id)->name;
        }
        return $ret;
    }

    function buildTree($records, $parentId = 0) {
        $this->causals = array();

        foreach ($records as $record)
        {
            if ($record->parent_id == $parentId)
            {
                $children = $this->buildTree($record, $record->id);
                if ($children) {
                    $record->children = $children;
                }
                $this->causals[] = $record;
            }
        }

        return $this->causals;
    }

    public function getCausale($records, $indentation)
    {
        foreach($records as $record)
        {
            $this->causals[] = array('id' => $record->id, 'name' => $record->getTree(), 'text' => $record->getTree(), 'level' => $indentation);
            if(count($record->childs))
                $this->getCausale($record->childs, $indentation + 1);
        }
    }

    public function mount()
    {

        if (isset($_GET["from"]))
        {
            $this->fromPage = $_GET["from"];
        }

        $this->causals = array();

        $this->multiMonthFrom = date("n");
        $this->multiYearFrom = date("Y");
        $this->multiMonthTo = date("n");
        $this->multiYearTo = date("Y");

        $fisc = \App\Models\Causal::where('corrispettivo_fiscale', true)->first();
        if ($fisc)
            $this->corrispettivo_causal_id = $fisc->id;

        $this->getCausale(\App\Models\Causal::select('id', 'name')->where('parent_id', null)->where('type', 'IN')->get(), 0);

        //$this->buildTree(\App\Models\Causal::all(), null);

        $this->refreshMembers();
        $this->payments = \App\Models\PaymentMethod::select('id', 'name')->where('enabled', true)->whereIn('type', array('ALL', 'IN'))->orderBy('name')->get();
        $this->banks = \App\Models\Bank::select('id', 'name')->where('enabled', true)->whereIn('visibility', array('ALL', 'IN'))->orderBy('name')->get();
        $this->vats = \App\Models\Vat::select('id', 'name', 'value')->orderBy('value')->get();

        if ($this->first)
        {
            if (isset($_GET["new"]))
            {
                $this->refreshAfter = 1;
                $this->add();
            }
            if (isset($_GET["memberId"]))
            {
                $this->refreshAfter = 1;
                $this->member_id = $_GET["memberId"];
                $member = \App\Models\Member::findOrFail($this->member_id);
                if (!$member->isAdult())
                {
                    if($member->father_name != '')
                        $this->parent = $member->father_name . " (C.F. " . $member->father_fiscal_code . ")";
                    else if($member->mother_name != '')
                        $this->parent = $member->mother_name . " (C.F. " . $member->mother_fiscal_code . ")";
                    else
                        $this->parent = '';
                }
            }
            if (isset($_GET["causalId"]))
            {
                $this->refreshAfter = 1;
                $this->causal_id = $_GET["causalId"];
            }
            if (isset($_GET["id"]))
            {
                $this->refreshAfter = 1;
                $this->edit($_GET["id"]);
            }
            $count = 0;
            if (isset($_GET["courseId"]))
            {
                $this->courseId = $_GET["courseId"];
                $mc = \App\Models\MemberCourse::findOrFail($this->courseId);
                $course = \App\Models\Course::findOrFail($mc->course_id);
            }
            if (isset($_GET["months"]))
            {

                $price = $_GET["price"] / 100 * 100;
                $this->refreshAfter = 1;
                $desc = "Pagamento";
                $months = explode("|", $_GET["months"]);
                $this->months = $months;
                $this->rows[0]["amount"] = formatPrice($price * sizeof($months));
                foreach($months as $idx => $m)
                {
                    $this->rows[0]["when"][$idx]["month"] = $m;

                    $currentYear = date('Y');
                    $currentMonth = date('n');

                    if ($currentMonth > env('FISCAL_YEAR_MONTH_TO', 1) && $m > env('FISCAL_YEAR_MONTH_TO', 1)) { // current 9-12 && $m 9-12
                        $currentYear = $currentYear;
                    } elseif ($currentMonth > env('FISCAL_YEAR_MONTH_TO', 1) && $m < env('FISCAL_YEAR_MONTH_FROM', 1)) { // current 9-12 && $m 1-8
                        $currentYear += 1;
                    } elseif ($currentMonth < env('FISCAL_YEAR_MONTH_FROM', 1) && $m > env('FISCAL_YEAR_MONTH_TO', 1)) { // current 1-8 && $m 9-12
                        $currentYear -= 1;
                    } elseif ($currentMonth < env('FISCAL_YEAR_MONTH_FROM', 1) && $m < env('FISCAL_YEAR_MONTH_FROM', 1)) { // current 1-8 && $m 1-8
                        $currentYear = $currentYear;
                    }
                    $this->rows[0]["when"][$idx]["year"] = $currentYear;

                    if ($idx > 0)
                    {
                        if ($this->rows[0]["when"][$idx - 1]["year"] != $this->rows[0]["when"][$idx]["year"])
                            $desc .= " " . $this->rows[0]["when"][$idx - 1]["year"] . " ";
                    }
                    $desc .= " " . $this->getMonth($m);// . " " . $this->rows[0]["when"][$idx]["year"];
                }
                $desc .= " " . $this->rows[0]["when"][$idx]["year"];
                $this->rows[0]["note"] = $desc;
                $count += 1;

            }


            if (isset($_GET["createSubscription"]) && $_GET["createSubscription"] == 1)
            {

                $this->createSubscription = 1;
                $this->courseId = $_GET["courseId"];
                $price = $_GET["subscription_price"] / 100 * 100;
                $this->refreshAfter = 1;
                if ($count == 1)
                    $this->rows[] = array('causal_id' => null, 'when' => array(array('month' => date("n"), 'year' => date("Y"), 'period' => '')),  'amount' => null, 'vat_id' => null, 'note' => '', 'commercial' => 0);
                $this->rows[$count]["causal_id"] = null;
                $this->rows[$count]["amount"] = formatPrice($price);
                $this->rows[$count]["note"] = "Pagamento iscrizione " . $course->name;
                if (isset($_GET["subCausalId"]))
                {
                    $this->refreshAfter = 1;
                    $this->rows[$count]["causal_id"] = $_GET["subCausalId"];
                }
            }

        }
        $this->first = false;

        $this->newMemberExists = false;
    }

    public function search()
    {
        $this->hasFilter = true;
    }

    public function disableSearch()
    {
        $this->filterMember = 0;
        $this->filterPaymentMethod = 0;
        $this->filterCausals = 0;
        $this->filterTo = '';
        $this->filterFrom = '';
        $this->filterCommercial = 0;
        $this->hasFilter = false;
        $this->total = 0;
    }

    public function render()
    {

        $datas = [];
        return view('livewire.records_in', ['datas' => $datas]);
    }

    public function executeMultipleAction(){

        if ($this->multipleAction == 'delete')
            $this->multipleDelete();

    }

    public function add()
    {

        $this->emit('load-select');
        //if ($this->hasFilter)
            $this->emit('hide-search');
        $this->resetFields();
        $this->dataId = 0;
        $this->add = true;
        $this->update = false;
        $this->emit('setEdit', true);
    }

    public function storeCorrispettivo()
    {

        $this->emit('refresh');

        $rules = [
            'member_id' => 'required'
        ];

        $this->validate($rules);



        foreach($this->payments as $p)
        {
            if ($p->corrispettivo_fiscale)
            {
                $price = isset($this->corrispettivo[$p->id]) ? $this->currencyToDouble($this->corrispettivo[$p->id]) : 0;
                $destination_id = isset($this->corrispettivo_destination[$p->id]) ? $this->corrispettivo_destination[$p->id] : null;

                if ($price > 0)
                {

                    $record = \App\Models\Record::create([
                        'member_id' => $this->member_id,
                        'supplier_id' => null,
                        'payment_method_id' => $p->id,
                        'destination_id' => $destination_id,
                        'commercial' => $this->commercial,
                        'corrispettivo_fiscale' => $this->corrispettivo_fiscale,
                        'date' => $this->date,
                        'type' => $this->type,
                        'amount' => $price,
                        'financial_movement' => $this->financial_movement,
                        'deleted' => $this->deleted
                    ]);

                    \App\Models\RecordRow::create([
                        'record_id' => $record->id,
                        'causal_id' => $this->corrispettivo_causal_id,
                        'note' => '',
                        'amount' => $price,
                        'vat_id' => null,
                        'commercial' => $this->commercial,
                        'when' => json_encode([])
                    ]);
                }

            }
        }

        $this->resetFields();
        $this->add = false;
        $this->isDuplicate = false;
        $this->emit('setEdit', false);

    }

    public function store($generate)
    {

        $this->emit('refresh');

        $rules = [
            'payment_method_id' => 'required',
            'rows.*.causal_id' => 'required',
            'rows.*.amount' => 'required'
        ];

        /*$f = false;
        foreach($this->rows as $row)
        {
            if ($row["commercial"]) $f = true;
        }
        if ($f)
            $rules["member_id"] = 'required';*/
        if(!$this->commercial)
            $rules["member_id"] = 'required';
        //dd($this->getErrorBag());

        /*$validator =  Validator::make($request->all(), $rules);

        if ($validator->fails())
        {
            $this->emit('goToAnchor');
        }*/

        //if (!$this->validate($rules))
            //$this->emit('goToAnchor');

        $this->validate($rules);
        //dd("£ASDSDFS");
        try {

            $record = \App\Models\Record::create([
                'member_id' => $this->member_id,
                'supplier_id' => $this->supplier_id,
                'payment_method_id' => $this->payment_method_id,
                'destination_id' => $this->destination_id,
                'commercial' => $this->commercial,
                'corrispettivo_fiscale' => $this->corrispettivo_fiscale,
                'date' => $this->date,
                'type' => $this->type,
                'financial_movement' => $this->financial_movement,
                'deleted' => $this->deleted
            ]);
            $this->dataId = $record->id;

            $no_receipt_causal = false;

            // Inserisco le righe
            $tot = 0;
            $vat = 0;
            foreach($this->rows as $row)
            {
                foreach($row["when"] as $x => $y)
                {
                    $row["when"][$x]['period'] = $row["when"][$x]['month'] . "-" . $row["when"][$x]['year'];
                }
                \App\Models\RecordRow::create([
                    'record_id' => $this->dataId,
                    'causal_id' => $row["causal_id"],
                    'note' => $row["note"],
                    'amount' => $this->currencyToDouble($row["amount"]),
                    'vat_id' => $row["vat_id"],
                    'commercial' => $this->commercial,
                    'when' => json_encode($row["when"])
                ]);
                $tot += $this->currencyToDouble($row["amount"]);
                $vat += getVatValue($this->currencyToDouble($row["amount"]), $row["vat_id"]);

                $cau = \App\Models\Causal::findOrFail($row["causal_id"]);
                if ($cau->no_receipt)
                    $no_receipt_causal = true;

                // Se la causale ricarica a borsellino, se il totale supera y euro, inserisco x euro gratis
                if ($cau->money)
                {
                    if ($this->currencyToDouble($row["amount"]) >= env('MIN_MONEY', 100))
                    {
                        $money = new \App\Models\Money();
                        $money->member_id = $this->member_id;
                        $money->record_id = $this->dataId;
                        $money->amount = env('EXTRA_MONEY', 10);
                        $money->date = date("Y-m-d");
                        $money->note = env('EXTRA_MONEY', 10) . ' in più per aver caricato ' . $this->currencyToDouble($row["amount"]);
                        $money->save();
                    }
                }

            }
            $record->amount = $tot;
            $record->save();

            // se sto pagando un corso, aggiorno lo status dei mesi
            if ($this->courseId > 0)
            {
                $record->months = json_encode($this->months);
                $record->member_course_id = $this->courseId;
                $record->save();
                $c = \App\Models\MemberCourse::findOrFail($this->courseId);
                $xxx = json_decode($c->months);
                foreach($xxx as $idx => $mm)
                {
                    if (in_array($mm->m, $this->months))
                    {
                        $xxx[$idx]->status = 1;
                    }
                }
                $c->months = json_encode($xxx);
                if ($this->createSubscription == 1)
                    $c->subscribed = true;
                $c->save();
            }

            if (!$this->financial_movement)
            {
                $payment_method = \App\Models\PaymentMethod::findOrFail($this->payment_method_id);
                if (!$payment_method->money)
                {
                    if ($generate && !$no_receipt_causal)
                        $this->createReceipt();
                }
            }

            session()->flash('success','Movimento creato');
            $this->resetFields();
            $this->add = false;
            $this->isDuplicate = false;
            $this->emit('setEdit', false);
        } catch (\Exception $ex) {
            session()->flash('error','Errore (' . $ex->getMessage() . ')');
        }
    }

    public function duplicate($id){
        $record = \App\Models\Record::findOrFail($id);
        $newRecord = $record->replicate();
        $newRecord->save();
        $rows = \App\Models\RecordRow::where('record_id', $id)->get();
        foreach($rows as $r)
        {
            $newRow = $r->replicate();
            $newRow->record_id = $newRecord->id;
            $newRow->save();
        }
        $this->edit($newRecord->id);
        $this->isDuplicate = true;
    }

    public function edit($id){
        if (!isset($_GET["from"]) && $this->fromPage == '')
            $this->fromPage = 'in';
        $this->emit('setEdit', true);
        //if ($this->hasFilter)
            $this->emit('hide-search');
        $this->emit('load-select');
        try {
            $record = \App\Models\Record::findOrFail($id);
            if( !$record) {
                session()->flash('error','Movimento non trovato');
            } else {
                $this->member_id = $record->member_id;
                $this->supplier_id = $record->supplier_id;
                $this->payment_method_id = $record->payment_method_id;
                $this->destination_id = $record->destination_id;
                $this->amount = $record->amount;
                $this->commercial = $record->commercial;
                $this->corrispettivo_fiscale = $record->corrispettivo_fiscale;
                $this->date = date("Y-m-d", strtotime($record->date));
                $this->type = $record->type;
                $this->deleted = $record->deleted;
                $this->financial_movement = $record->financial_movement;
                $this->dataId = $record->id;
                $this->update = true;
                $this->add = false;

                $this->rows = \App\Models\RecordRow::where('record_id', $this->dataId)->select('causal_id', 'note', 'commercial', 'when', 'amount', 'vat_id')->get()->toArray();
                foreach($this->rows as $i => $r)
                {
                    $this->rows[$i]['amount'] = formatPrice($this->rows[$i]['amount']);
                    $this->rows[$i]['vat_id'] = $this->rows[$i]['vat_id'];
                    $this->rows[$i]['when'] = json_decode($this->rows[$i]['when']);
                }

                $exist = \App\Models\Receipt::where('record_id', $id)->orderBy('id', 'DESC')->first();
                if ($exist != null)
                {
                    $this->currentReceip = $exist;
                    $this->parent = $this->currentReceip->parent;
                }
            }
        } catch (\Exception $ex) {
            session()->flash('error','Errore (' . $ex->getMessage() . ')');
        }
    }

    public function update($generate = false)
    {
        $this->emit('refresh');
        $rules = [
            'payment_method_id' => 'required',
            'rows.*.causal_id' => 'required',
            'rows.*.amount' => 'required'
        ];

        if(!$this->commercial)
            $rules["member_id"] = 'required';

        $this->validate($rules);

        try {

            \App\Models\Record::whereId($this->dataId)->update([
                'member_id' => $this->member_id,
                'supplier_id' => $this->supplier_id,
                'payment_method_id' => $this->payment_method_id,
                'destination_id' => $this->destination_id,
                'commercial' => $this->commercial,
                'corrispettivo_fiscale' => $this->corrispettivo_fiscale,
                'date' => date("Y-m-d", strtotime($this->date)),
                'type' => $this->type,
                'financial_movement' => $this->financial_movement,
                'deleted' => $this->deleted,
            ]);

            $no_receipt_causal = false;

            $tot = 0;
            $vat = 0;
            // Elimino le righe
            \App\Models\RecordRow::where('record_id', $this->dataId)->delete();
            // Inserisco le righe
            foreach($this->rows as $row)
            {
                foreach($row["when"] as $x => $y)
                {
                    $row["when"][$x]['period'] = $row["when"][$x]['month'] . "-" . $row["when"][$x]['year'];
                }
                \App\Models\RecordRow::create([
                    'record_id' => $this->dataId,
                    'causal_id' => $row["causal_id"],
                    'note' => $row["note"],
                    'vat_id' => $row["vat_id"],
                    'amount' => $this->currencyToDouble($row["amount"]),
                    'commercial' => $this->commercial,
                    'when' => json_encode($row["when"])
                ]);
                $tot += $this->currencyToDouble($row["amount"]);
                $vat += getVatValue($this->currencyToDouble($row["amount"]), $row["vat_id"]);

                $cau = \App\Models\Causal::findOrFail($row["causal_id"]);
                if ($cau->no_receipt)
                    $no_receipt_causal = true;

            }

            $rec = \App\Models\Record::findOrFail($this->dataId);
            $rec->amount = $tot;
            $rec->save();

            if (!$this->financial_movement)
            {
                $payment_method = \App\Models\PaymentMethod::findOrFail($this->payment_method_id);
                if (!$payment_method->money)
                {
                    if ($generate && !$no_receipt_causal)
                        $this->createReceipt();
                }
            }
            session()->flash('success','Movimento aggiornato');
            $this->resetFields();
            $this->update = false;
            $this->isDuplicate = false;
            $this->emit('setEdit', false);
        } catch (\Exception $ex) {
            session()->flash('error','Errore (' . $ex->getMessage() . ')');
        }
    }

    public function rigenerate()
    {
        $this->emit('refresh');

        try {

            $record = \App\Models\Record::findOrFail($this->dataId);
            $newRecord = $record->replicate();
            $newRecord->date = date("Y-m-d");
            $newRecord->save();

            $recordRows = \App\Models\RecordRow::where('record_id', $this->dataId)->get();
            // Inserisco le righe
            foreach($recordRows as $row)
            {
                $newRow = $row->replicate();
                $newRow->record_id = $newRecord->id;
                $newRow->save();
            }

            $this->dataId = $newRecord->id;

            $this->createReceipt();

            session()->flash('success','Movimento aggiornato');
            $this->resetFields();
            $this->update = false;
            $this->isDuplicate = false;
            $this->emit('setEdit', false);
        } catch (\Exception $ex) {
            session()->flash('error','Errore (' . $ex->getMessage() . ')');
        }
    }

    public function cancel()
    {
        // Se arrivo da duplica elimino
        if ($this->isDuplicate)
        {
            try{
                \App\Models\Record::find($this->dataId)->delete();
                session()->flash('success',"Movimento eliminato");
            }catch(\Exception $e){
                session()->flash('error','Errore (' . $e->getMessage() . ')');
            }
        }
        $this->isDuplicate = false;

        $this->add = false;
        $this->update = false;
        $this->resetFields();
        $this->emit('setEdit', false);
        return redirect()->to('/in');
    }

    public function delete($id)
    {
        try{

            $r = \App\Models\Record::find($id);

            // Annullo la ricevuta
            $receipt = \App\Models\Receipt::where('record_id', $r->id)->first();
            if($receipt)
            {
                $receipt->status = 99;
                sendReceiptDeleteEmail($receipt);
                $receipt->save();
            }

            if ($r->member_course_id > 0)
            {
                $months = json_decode($r->months);
                $c = \App\Models\MemberCourse::findOrFail($r->member_course_id);
                $xxx = json_decode($c->months);
                foreach($xxx as $idx => $mm)
                {
                    if (in_array($mm->m, $months))
                    {
                        $xxx[$idx]->status = "";
                    }
                }
                $c->months = json_encode($xxx);
                $c->save();
            }

            $r->deleted = true;
            $r->save();

            session()->flash('success','Movimento aggiornato');
            $this->resetFields();
            $this->update = false;
            $this->isDuplicate = false;
            $this->emit('setEdit', false);

            $this->emit('reload');

            //$this->emit('load-data-table');

        }catch(\Exception $ex){
            session()->flash('error','Errore (' . $ex->getMessage() . ')');
        }
    }

    public function multipleDelete()
    {
        try{
            foreach($this->multipleIds as $id)
            {
                \App\Models\Record::find($id)->delete();
            }
        }catch(\Exception $e){
            session()->flash('error','Errore (' . $e->getMessage() . ')');
        }
        $this->multipleAction = '';
    }

    public function createMember()
    {

        $this->newMemberFiscalCodeExist = false;
        $this->validate([
            // 'newMemberFiscalCode'=>'required|max:16',
            'newMemberFirstName'=>'required',
            'newMemberLastName'=>'required',
            //'newMemberEmail'=>'required',
        ]);

        // Check fiscal code exist
        $exist = false;
        if ($this->newMemberFiscalCode != '')
        {
            $check = \App\Models\Member::where('fiscal_code', $this->newMemberFiscalCode)
                ->where(function($query) {
                    $query->where('is_deleted', false)
                        ->orWhereNull('is_deleted');
                })->get();
            $exist = $check->count() > 0;
        }
        if (!$exist)
        {
            $member = \App\Models\Member::create([
                'first_name' => strtoupper($this->newMemberFirstName),
                'last_name' => strtoupper($this->newMemberLastName),
                'email' => strtoupper($this->newMemberEmail),
                'to_complete' => $this->newMemberToComplete,
                'fiscal_code' => $this->newMemberFiscalCode,
                'status' => true
            ]);
            $this->member_id = $member->id;
            $this->members = \App\Models\Member::select(['id', 'first_name', 'last_name', 'fiscal_code'])
                ->where(function($query) {
                    $query->where('is_archived', false)
                        ->orWhereNull('is_archived');
                })
                ->where(function($query) {
                    $query->where('is_deleted', false)
                        ->orWhereNull('is_deleted');
                })->get();
            // $this->emit('reloadMembers');
            $this->emit('refresh');
            $this->newMemberFirstName = '';
            $this->newMemberLastName = '';
            $this->newMemberEmail = '';
            $this->newMemberToComplete = false;
            $this->newMemberFiscalCode = '';
            $this->emit('saved');
            //$this->validate();
            $this->selectId++;
        }
        else
        {
            $this->newMemberFiscalCodeExist = true;
        }
    }

    public function createReceipt()
    {

        // Ulteriore controllo commerciale/non commerciale
        if (!$this->commercial)
        {
            $create = false;
            $receipt = \App\Models\Receipt::where('record_id', $this->dataId)->orderBy('id', 'DESC')->first();
            if ($receipt != null)
            {

                // Controllo lo stato, se 99 ne genero una nuova
                if ($receipt->status == 99)
                {
                    $create = true;
                }

            }
            else
            {
                $create = true;
            }

            if ($create)
            {
                $number = 1;
                $exist = \App\Models\Receipt::where('year', date("Y"))->orderBy('number', 'DESC')->first();
                if ($exist != null)
                    $number = $exist->number + 1;

                $receipt = \App\Models\Receipt::create([
                    'record_id' => $this->dataId,
                    'member_id' => $this->member_id,
                    'supplier_id' => $this->supplier_id,
                    'payment_method_id' => $this->payment_method_id,
                    'number' => $number,
                    'date' => $this->date,
                    'year' => date("Y"),
                    'type' => $this->type,
                    'parent' => $this->parent,
                    'status' => 1,
                ]);

                foreach($this->rows as $row)
                {
                    \App\Models\ReceiptRow::create([
                        'receip_id' => $receipt->id,
                        'causal_id' => $row["causal_id"],
                        'note' => $row["note"],
                        'vat_id' => $row["vat_id"],
                        'amount' => $this->currencyToDouble($row["amount"]),
                        'commercial' => $row["commercial"],
                        'when' => json_encode($row["when"])
                    ]);
                }

                $this->currentReceip = $receipt;

                sendReceiptEmail($receipt);

                /*

                // Invio mail
                $pdf = PDF::loadView('receipt', array('receipt' => $receipt));
                $pdfName = "ricevuta_" . $receipt->number . "_" . $receipt->year . ".pdf";
                Storage::put('public/pdf/' . $pdfName, $pdf->output());
                $email = \App\Models\Member::findOrFail($receipt->member_id)->email;
                if ($email != '')
                {
                    Mail::to($email)->send(new \App\Mail\ReceipEmail([
                        'pdf' => 'public/pdf/' . $pdfName,
                        'number' => $receipt->number . "/" . $receipt->year
                    ]));
                }

                */

                session()->flash('receipt',"Ricevuta " . $number . "/" . date("Y") . " creata correttamente");

                // Apro la ricevuta
                $this->emit('showReceipt', $this->currentReceip->id);

            }
        }


    }

    public function removeReceipt()
    {
        $receipt = \App\Models\Receipt::findOrFail($this->currentReceip->id);
        $receipt->status = 99;
        $receipt->save();
        
        // cancellazione record associato
        try{

            $record = \App\Models\Record::find($receipt->record_id);

            if ($record->member_course_id > 0)
            {
                $months = json_decode($record->months);
                $c = \App\Models\MemberCourse::findOrFail($record->member_course_id);
                $xxx = json_decode($c->months);
                foreach($xxx as $idx => $mm)
                {
                    if (in_array($mm->m, $months))
                    {
                        $xxx[$idx]->status = "";
                    }
                }
                $c->months = json_encode($xxx);
                $c->save();
            }

            $record->deleted = true;
            $record->save();

            $this->emit('success');

        } catch(\Exception $ex) {
            session()->flash('error','Errore (' . $ex->getMessage() . ')');
        }

        sendReceiptDeleteEmail($receipt);
        $this->currentReceip = $receipt;

    }

    function currencyToDouble($val)
    {
        $x = str_replace("€", "", $val);
        $x = str_replace(".", "", $x);
        $x = str_replace(",", ".", $x);
        return floatval(trim($x));
    }


    public function addRow()
    {
        $this->rows[] = array('causal_id' => null, 'when' => array(array('month' => date("n"), 'year' => date("Y"), 'period' => '')),  'amount' => null, 'vat_id' => null, 'note' => '', 'commercial' => 0);
        $this->emit('load-select');
    }

    public function delRow($idx)
    {
        unset($this->rows[$idx]);
        // $this->emit('load-select');
    }

    public function addPeriod($idx)
    {
        $x = sizeof($this->rows[$idx]['when']) - 1;
        $newDate = \Carbon\Carbon::create($this->rows[$idx]['when'][$x]["year"] . "-" . $this->rows[$idx]['when'][$x]["month"] . '-01')->addMonth();
        $this->rows[$idx]['when'][] = array('month' => $newDate->format("n"), 'year' => $newDate->format("Y"), 'period' => '');
    }

    public function delPeriod($idx, $xxx)
    {
        array_splice($this->rows[$idx]['when'], $xxx, $xxx);
        //unset($this->rows[$idx]['when'][$xxx]);
        // $this->emit('load-select');
    }

    public function getTotal()
    {
        $total = 0.00;
        foreach($this->rows as $r)
        {
            if ($r["amount"] != null && $r["amount"] != "")
            {
                $total += $this->currencyToDouble($r["amount"]);
                if ($r["vat_id"] > 0)
                    $total += getVatValue($this->currencyToDouble($r["amount"]), $r["vat_id"]);
            }
        }
        return formatPrice($total);
        // $this->emit('load-select');
    }

    public function getTotalCorrispettivo()
    {
        $total = 0.00;
        foreach($this->corrispettivo as $r)
        {
            $total += $this->currencyToDouble($r);
        }
        return formatPrice($total);
        // $this->emit('load-select');
    }

    public function getPrice()
    {
        $total = 0.00;
        foreach($this->rows as $r)
        {
            if ($r["amount"] != null && $r["amount"] != "")
                $total += $this->currencyToDouble($r["amount"]);
        }
        return formatPrice($total);
        // $this->emit('load-select');
    }

    public function getVat()
    {
        $total = 0.00;
        foreach($this->rows as $r)
        {
            if ($r["amount"] != null && $r["amount"] != "" && $r["vat_id"] > 0)
                $total += getVatValue($this->currencyToDouble($r["amount"]), $r["vat_id"]);
        }
        return formatPrice($total);
        // $this->emit('load-select');
    }

    public function getVats()
    {
        $vats = array();
        foreach($this->rows as $r)
        {
            if ($r["amount"] != null && $r["amount"] != "" && $r["vat_id"] > 0)
            {
                $vat = getVatValue($this->currencyToDouble($r["amount"]), $r["vat_id"]);
                $vatName = "";
                foreach($this->vats as $v)
                {
                    if ($v->id == $r["vat_id"])
                        $vatName = $v->name;
                }
                if (isset($vats[$vatName]))
                    $vats[$vatName] += $vat;
                else
                    $vats[$vatName] = $vat;
            }
        }
        return $vats;
        // $this->emit('load-select');
    }

    public function setCausal($id, $idx)
    {
        $this->rows[$idx]["causal_id"] = $id;
    }

    public function printReceipt()
    {
        //$pdf = PDF::loadView('pdf/receipt', array('datas' => $datas, 'from' => $x, 'to' => $y, 'who' => '', 'matricola' => $matricola));
        $pdf = PDF::loadView('receipt', array('receipt' => $this->currentReceip));//->output();
        $pdfName = "Ricevuta_" . $this->currentReceip->member->last_name . "_" . $this->currentReceip->number . "_" . $this->currentReceip->year . ".pdf";
        return $pdf->stream();
        /*return response()->streamDownload(
            fn () => print($pdf),
            "ricevuta_" . $this->currentReceip->number . "_" . $this->currentReceip->year . ".pdf"
        );*/
        /*return response()->streamDownload(function () {
            echo $pdf->stream();
        }, 'test.pdf');*/
    }

    public function multiPeriod()
    {
        $this->multiP = true;
    }

    public function multiPeriodCreate($idx)
    {

        $period = \Carbon\CarbonPeriod::create($this->multiYearFrom . '-' . $this->multiMonthFrom . '-01', '1 month', $this->multiYearTo . '-' . $this->multiMonthTo . '-01');
        $this->rows[$idx]['when'] = [];
        foreach ($period as $dt) {
            if (!in_array(array('month' => $dt->format("n"), 'year' => $dt->format("Y"), 'period' => ''), $this->rows[$idx]['when']))
                $this->rows[$idx]['when'][] = array('month' => $dt->format("n"), 'year' => $dt->format("Y"), 'period' => '');
        }

        $this->multiP = false;

    }

    public function multiPeriodCancel()
    {
        $this->multiP = false;
    }

    public function getMonth($m)
    {
        $ret = '';
        switch ($m) {
            case 1:
                $ret = 'Gennaio';
                break;
            case 2:
                $ret = 'Febbraio';
                break;
            case 3:
                $ret = 'Marzo';
                break;
            case 4:
                $ret = 'Aprile';
                break;
            case 5:
                $ret = 'Maggio';
                break;
            case 6:
                $ret = 'Giugno';
                break;
            case 7:
                $ret = 'Luglio';
                break;
            case 8:
                $ret = 'Agosto';
                break;
            case 9:
                $ret = 'Settembre';
                break;
            case 10:
                $ret = 'Ottobre';
                break;
            case 11:
                $ret = 'Novembre';
                break;
            case 12:
                $ret = 'Dicembre';
                break;
            default:
                $ret = '';
                break;
        }
        return $ret;
    }

    public function setYear($idx, $xxx)
    {
        $currentYear = date('Y');
        $currentMonth = date('n');

        $m = $this->rows[$idx]["when"][$xxx]["month"];

        if ($currentMonth > env('FISCAL_YEAR_MONTH_TO', 1) && $m > env('FISCAL_YEAR_MONTH_TO', 1)) { // current 9-12 && $m 9-12
            $currentYear = $currentYear;
        } elseif ($currentMonth > env('FISCAL_YEAR_MONTH_TO', 1) && $m < env('FISCAL_YEAR_MONTH_FROM', 1)) { // current 9-12 && $m 1-8
            $currentYear += 1;
        } elseif ($currentMonth < env('FISCAL_YEAR_MONTH_FROM', 1) && $m > env('FISCAL_YEAR_MONTH_TO', 1)) { // current 1-8 && $m 9-12
            $currentYear -= 1;
        } elseif ($currentMonth < env('FISCAL_YEAR_MONTH_FROM', 1) && $m < env('FISCAL_YEAR_MONTH_FROM', 1)) { // current 1-8 && $m 1-8
            $currentYear = $currentYear;
        }
        $this->rows[$idx]["when"][$xxx]["year"] = $currentYear;
    }

    public function updatedNewMemberFirstName()
    {
        $this->checkUserExists();
    }

    public function updatedNewMemberLastName()
    {
        $this->checkUserExists();
    }

    private function checkUserExists(): void
    {
        $first = trim((string) $this->newMemberFirstName);
        $last = trim((string) $this->newMemberLastName);

        if ($first === '' || $last === '') {
            $this->newMemberExists = false;
            return;
        }

        $first = mb_strtolower($first);
        $last  = mb_strtolower($last);

        $this->newMemberExists = \App\Models\Member::query()
            ->where(function ($q) {
                $q->where('is_deleted', false)
                ->orWhereNull('is_deleted');
            })
            ->whereRaw('LOWER(TRIM(first_name)) = ?', [$first])
            ->whereRaw('LOWER(TRIM(last_name))  = ?', [$last])
            ->exists();
    }
}
