<?php

namespace Ignite\Core\Contracts;

use Ignite\Core\Entities\Import;
use Ignite\Core\Exceptions\ImportException;
use Illuminate\Validation\Validator;
use Throwable;

interface Importable
{
    /**
     * Assign the import data record for this import.
     *
     * @param  Import $record
     * @return self
     */
    public function record(Import $record);

    /**
     * Prepare any dependencies for each iteration of the import process.
     *
     * @return void
     */
    public function prepare();

    /**
     * The total number of records to be imported.
     *
     * @return int
     */
    public function count() : int;

    /**
     * Display the html for previewing the data.
     *
     * @return string
     */
    public function html() : string;

    /**
     * Attempt to map the correct fields from the provided headers.
     *
     * @return array
     */
    public function getHeaders() : array;

    /**
     * Preview a single line at the given offset.
     *
     * @param  int $offset
     * @return array
     */
    public function preview($offset = 1) : array;

    /**
     * Process the file and return the iterator.
     *
     * @return iterable
     */
    public function process() : iterable;

    /**
     * Validate a single line.
     *
     * @param  array $data
     * @return Validator
     */
    public function validate(array $data) : Validator;

    /**
     * Transform the data for a single line.
     *
     * @param  array $data
     * @return array
     */
    public function transform(array $data) : array;

    /**
     * Format an import message.

     * @param int   $line
     * @param array $data
     * @return string
     */
    public function formatImportMessage(int $line, array $data) : string;

    /**
     * Format a reject message.
     *
     * @param  int        $line
     * @param  array      $data
     * @param  Throwable $error
     * @return string
     */
    public function formatRejectMessage(int $line, array $data, Throwable $error) : string;

    /**
     * Process the data for a single line.
     *
     * @param  array $data
     * @return bool
     * @throws ImportException|Throwable
     */
    public function save(array $data) : bool;

    /**
     * Process the data for a single line during dry-run.
     *
     * @param  array  $data
     * @return bool
     */
    public function drySave(array $data): bool;

    /**
     * Returns true if we need to handle row as error if it could not save.
     *
     * @return boolean
     */
    public function isErrorOnFailedSave(): bool;

    /**
     * Set the result string.
     *
     * @param string $value
     *
     * @return $this
     */
    public function setResultColumn($value);

    /**
     * The value for the result column.
     *
     * @return string|null
     */
    public function getResultColumn();

    /**
     * Runs any needed steps after import is complete.
     *
     * @param  array  $params
     * @return void
     */
    public function postImport(array $params);
}
