<?php

namespace Tobuli\Importers;

use Tobuli\Entities\User;
use Tobuli\Exceptions\ValidationException;
use Tobuli\Importers\Readers\ReaderInterface;
use Validator;
use Cache;

abstract class Importer implements ImporterInterface
{
    const STOP_ON_FAIL = 'stop_on_fail';

    protected $reader;
    protected $stop_on_fail = true;

    abstract protected function getDefaults();
    abstract protected function getValidationRules();
    abstract protected function importItem($data, $additionals = []);

    public function __construct(ReaderInterface $reader)
    {
        $this->reader = $reader;
    }

    public function import($file, $additionals = [])
    {
        $items = $this->reader->read($file);

        if (empty($items)) {
            throw new ValidationException(trans('front.unsupported_format'));
        }

        $this->stop_on_fail = array_pull($additionals, self::STOP_ON_FAIL, true);

        foreach ($items as $item) {
            $this->importItem($item, $additionals);
        }
    }

    protected function mergeDefaults($data)
    {
        $defaults = $this->getDefaults();

        foreach ($defaults as $key => $value) {
            if (isset($data[$key]) && empty($data[$key])) {
                unset($data[$key]);
            }
        }

        return empty($data) ? $defaults : array_merge($defaults, $data);
    }

    protected function setUser($data, $additionals)
    {
        if (isset($data['user_id'])) {
            $id = $data['user_id'];

            $user = Cache::store('array')->rememberForever("importer.user.$id", function() use ($id) {
                return User::find($id);
            });

            $data['user_id'] = $user ? $user->id : null;
        }

        if (empty($data['user_id']) && isset($additionals['user_id'])) {
            $id = $additionals['user_id'];

            $user = Cache::store('array')->rememberForever("importer.user.$id", function() use ($id) {
                return User::find($id);
            });

            $data['user_id'] = $user ? $user->id : null;
        }

        if (empty($data['user_id']))
            $data['user_id'] = auth()->id();

        return $data;
    }

    protected function validate($data)
    {
        $validator = Validator::make($data, $this->getValidationRules());

        if ( ! $validator->fails()) {
            return true;
        }

        if ($this->stop_on_fail === true) {
            throw new ValidationException($validator->messages());
        }

        return false;
    }
}