<?php

namespace Ignite\Core\Http\Controllers\Admin;

use Ignite\Core\Http\Controllers\Controller;
use Ignite\Core\Contracts\Repositories\ImportRepository;
use Ignite\Flash\Facades\Flash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
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;
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  int $id
     * @param  Request $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store($id, Request $request)
    {
        $dryRun = (bool) $request->input('dry_run', false);

        $params = [
            '--id' => $id,
            '--user' => auth()->user()->getKey(),
            '--no-interaction' => '1'
        ];

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

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

        if (! app()->runningInConsole()) {
            set_time_limit((int) config('core.import.timeout', 120)); // 2 minutes
        }

        DB::transaction(function () use ($params) {
            $exit = Artisan::call('ignite:import', $params);
        });

        Flash::success('The ' . ($dryRun ? 'dry run' :  'import') . ' is complete. Please consult the log.');

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

    /**
     * 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' => '',
        ];

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

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

        try {
            $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',
        ]);
    }
}
