<?php

namespace Ignite\Core\Http\Controllers\Admin;

use Ignite\Core\Contracts\Repositories\ImportRepository;
use Ignite\Core\Http\Controllers\Controller;
use Ignite\Flash\Facades\Flash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;

class RunController extends Controller
{
    /**
     * @var ImportRepository
     */
    protected $importRepository;

    /**
     * ImportController constructor.
     *
     * @param ImportRepository $importRepository
     */
    public function __construct(ImportRepository $importRepository)
    {
        $this->importRepository = $importRepository;
    }

    /**
     * Perform an actual or dry-run of an import.
     *
     * @param int $id
     * @param Request $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store($id, Request $request)
    {
        $userId = auth()->user()->getKey();
        $dryRun = (bool)$request->input('dry_run', false);
        $shouldQueue = config('core.import.queue', true);
        $timeLimit = (int)config('core.import.timeout', 120); // 2 minutes
        $queueConnection = config('core.import.queue_connection', '');

        $params = [
            '--id' => $id,
            '--user' => $userId,
            '--no-interaction' => true,
        ];

        if ($dryRun) {
            $params['--dry-run'] = $dryRun;
        }

        if (app()->runningInConsole()) {
            $params['-vvv'] = '1';
        }

        if (! app()->runningInConsole()) {
            set_time_limit($timeLimit);
        }

        if ($shouldQueue) {
            $exit = Artisan::queue('ignite:import', $params)->onQueue($queueConnection);
        } else {
            $exit = Artisan::call('ignite:import', $params);
        }

        Flash::success(sprintf(
            'The %s is %s',
            $dryRun ? 'dry run' : 'import',
            $shouldQueue ? 'queued.' : 'complete. Please consult the log.',
        ));

        return redirect()->route('admin.import.show', [
            'id' => $id,
            'dryRun' => $dryRun,
            'onlyErrors' => true,
            'queued' => $shouldQueue,
        ]);
    }

    /**
     * Preview a single record.
     *
     * @param int $id
     * @param int $offset
     * @return \Illuminate\Http\JsonResponse
     */
    public function preview($id, $offset = 1)
    {
        $import = $this->importRepository->find($id);

        $data = [
            'record' => [],
            'errors' => [],
            'exception' => '',
        ];

        try {
            $importer = $import->resolveType();
            $importer->prepare();
            $record = $importer->preview($offset);
            $validator = $importer->validate($record);

            $data['record'] = $record;
            if ($validator->fails()) {
                $data['errors'] = $validator->errors()->toArray();
            }

            $data['record'] = $importer->transform($record);
        } catch (\Exception $e) {
            $data['exception'] = $e->getMessage();
        }

        return response()->json($data, 200);
    }

    /**
     * Download the stored file.
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function download($id)
    {
        $import = $this->importRepository->find($id);

        return $import->disk()->download($import->file);
    }

    /**
     * Generate an import for the given type.
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function generate($id)
    {
        $import = $this->importRepository->find($id);

        $importer = $import->resolveType();

        $importer->prepare();

        return response($importer->generate(10000)->getContent(), 200, [
            'Content-Encoding' => 'none',
            'Content-Type' => 'text/csv; charset=UTF-8',
            'Content-Disposition' => sprintf('attachment; filename="%s-%s.csv"', $import->label, now()->format('YmdHis')),
            'Content-Description' => 'File Transfer',
        ]);
    }
}
