<?php

namespace App\Http\Livewire;

use App\Http\Middleware\TenantMiddleware;
use Livewire\Component;

class FinancialMovements extends Component
{
    public $origins = [];
    public $destinations = [];

    public $date;
    public $origin_id;
    public $destination_id;
    public $causal_id;
    public $amount;
    public $amountFormatted;
    public $notes;

    public $causal_name;

    public $add = false;
    public $update = false;

    public $isDuplicate = false;

    public $dataId;

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

    protected function rules()
    {
        return [
            'date' => ['required', 'date'],
            'origin_id' => ['required', 'integer', 'exists:banks,id'],
            'destination_id' => ['required', 'integer', 'exists:banks,id', 'different:origin_id',],
            'amount' => ['required', 'numeric', 'gt:0'],
            'notes' => ['nullable', 'string', 'max:5000'],
        ];
    }

    protected $messages = [
        'date.required' => "La data dell'operazione è obbligatoria.",
        'origin_id.required' => "Seleziona un conto di origine.",
        'origin_id.exists' => "Il conto di origine selezionato non è valido.",
        'destination_id.required' => "Seleziona un conto di destinazione.",
        'destination_id.exists' => "Il conto di destinazione selezionato non è valido.",
        'destination_id.different' => "Origine e destinazione devono essere diversi.",
        'amount.required' => "Inserisci un importo.",
        'amount.numeric' => "L'importo deve essere un numero.",
        'amount.gt' => "L'importo deve essere maggiore di zero.",
    ];

    public function boot()
    {
        app(TenantMiddleware::class)->setupTenantConnection();
    }

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

    public function resetFields()
    {
        $this->date = date("Y-m-d");
        $this->origin_id = null;
        $this->destination_id = null;
        $this->amount = null;
        $this->amountFormatted = null;
        $this->notes = null;

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

    public function mount()
    {
        $this->origins = \App\Models\Bank::where('enabled', true)->whereIn('visibility', ['ALL', 'OUT'])->orderBy('name')->get();
        $this->destinations = \App\Models\Bank::where('enabled', true)->whereIn('visibility', ['ALL', 'IN'])->orderBy('name')->get();

        $this->causal_name = "Movimento finanziario";
        $this->causal_id = \App\Models\Causal::where('name', $this->causal_name)->value('id');
        if (!$this->causal_id) {
            $causal = new \App\Models\Causal();
            $causal->name = $this->causal_name;
            $causal->type = "IN";
            $causal->parent_id = null;
            $causal->money = false;
            $causal->corrispettivo_fiscale = false;
            $causal->no_receipt = false;
            $causal->user_status = false;
            $causal->no_first = false;
            $causal->no_records = true;
            $causal->no_reports = true;
            $causal->enabled = true;
            $causal->save();

            $this->causal_id = $causal->id;
        }
    }

    public function render()
    {
        return view('livewire.financial_movements');
    }

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

        $this->resetFields();

        $this->dataId = 0;
        $this->add = true;
        $this->update = false;

        $this->emit('setEdit', true);
    }

    public function store()
    {
        if ($this->validate()) {
            try {
                $financial_movement = \App\Models\FinancialMovement::create([
                    'date' => $this->date,
                    'origin_id' => $this->origin_id,
                    'destination_id' => $this->destination_id,
                    'causal_id' => $this->causal_id,
                    'amount' => $this->amount,
                    'notes' => $this->notes,
                ]);
                $this->dataId = $financial_movement->id;

                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)
    {
        $financial_movement = \App\Models\FinancialMovement::findOrFail($id);
        $new_financial_movement = $financial_movement->replicate();
        $new_financial_movement->save();

        $this->edit($new_financial_movement->id);

        $this->isDuplicate = true;
    }

    public function edit($id)
    {
        $this->emit('setEdit', true);

        $this->emit('load-select');
        try {
            $financial_movement = \App\Models\FinancialMovement::findOrFail($id);
            if (!$financial_movement) {
                session()->flash('error', 'Movimento non trovato');
            } else {
                $this->date = date("Y-m-d", strtotime($financial_movement->date));;
                $this->origin_id = $financial_movement->origin_id;
                $this->destination_id = $financial_movement->destination_id;
                $this->amount = $financial_movement->amount;
                $this->amountFormatted = formatPrice($this->amount);
                $this->notes = $financial_movement->notes;

                $this->dataId = $financial_movement->id;
                $this->update = true;
                $this->add = false;
            }
        } catch (\Exception $ex) {
            session()->flash('error', 'Errore (' . $ex->getMessage() . ')');
        }
    }

    public function update()
    {
        if ($this->validate()) {
            try {
                \App\Models\FinancialMovement::whereId($this->dataId)->update([
                    'date' => $this->date,
                    'origin_id' => $this->origin_id,
                    'destination_id' => $this->destination_id,
                    'causal_id' => $this->causal_id,
                    'amount' => $this->amount,
                    'notes' => $this->notes,
                ]);
    
                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()
    {
        if ($this->isDuplicate) {
            try {
                \App\Models\FinancialMovement::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('/financial_movements');
    }

    public function delete($id)
    {
        try {
            $fm = \App\Models\FinancialMovement::find($id);
            $fm->deleted = true;
            $fm->save();

            session()->flash('success', 'Movimento eliminato');

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

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

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

    public function updatedAmountFormatted($value)
    {
        $clean = str_replace(['€', '.', ' '], '', $value);
        $clean = str_replace(',', '.', $clean);

        $this->amount = is_numeric($clean) ? (float) $clean : null;
    }

    public function updatedOriginId()
    {
        if ($this->origin_id && $this->destination_id && $this->origin_id == $this->destination_id) {
            $this->destination_id = null;
        }
    }

    public function updatedDestinationId()
    {
        if ($this->origin_id && $this->destination_id && $this->origin_id == $this->destination_id) {
            $this->destination_id = null;
        }
    }
}
