<?php

namespace Ignite\Core\Http\Controllers\Admin;

use Exception;
use Ignite\Core\Models\Grid\AbstractTable;
use Ignite\Core\Models\Grid\Scopes\FilterFactory;
use Ignite\Core\Entities\Report;
use Ignite\Core\Models\Grid\ReportTable;
use Ignite\Core\Traits\QueuesReportDownloads;
use Ignite\Flash\Facades\Flash;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class ReportController extends Controller
{
    use QueuesReportDownloads;

    /**
     * Display a listing of the resource.
     *
     * @param  ReportTable $table
     * @param  Request     $request
     * @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
     */
    public function index(ReportTable $table, Request $request)
    {
        if ($request->wantsJson()) {
            return $table->ajax();
        }

        return $table->render('Core::admin.report.index');
    }

    /**
     * Show the specified resource.
     *
     * @param int $id
     * @param Request $request
     * @param FilterFactory $filterFactory
     *
     * @return \Illuminate\Http\JsonResponse|RedirectResponse
     */
    public function show($id, Request $request, FilterFactory $filterFactory)
    {
        /** @var Report $report */
        $report = Report::find((int) $id);

        if ($report->isUnpublished() || $report->isSensitive()) {
            Flash::error(sprintf(
                "The requested report `%s` is not available. Please contact I.T to request access.",
                $report->getName()
            ));
            return redirect()->route('admin.reports.index');
        }

        /** @var AbstractTable $table */
        $table = $report->getReportClassInstance();
        $tableClass = get_class($table);
        $tableKey = md5($tableClass);

        // Report filters are submitted through the page form, while DataTables
        // sends sorting/search/export requests separately. Persist filters in the
        // session so ajax table refreshes and exports use the same report scope.
        if ($request->isMethod('post') && $request->has('filters')) {
            $request->session()->put($tableKey, $request->input("filters", []));
        }

        $table = $filterFactory->apply($table, $requestFilters = $request->session()->get($tableKey));

        // Large CSV exports are converted into background report downloads. Smaller
        // exports intentionally fall through to Yajra's normal inline CSV response.
        $queuedCsvResponse = $this->queuedDataTableCsvExportResponse(
            $request,
            'admin.reports.export',
            $report->class,
            $report->getName(),
            (array) $report->params,
            (array) $requestFilters
        );
        if ($queuedCsvResponse) {
            return $queuedCsvResponse;
        }

        if ($request->wantsJson()) {
            return $table->ajax();
        }

        $filters = $filterFactory->collect();

        return $table->render('Core::admin.report.show', compact('report', 'filters', 'requestFilters'));
    }

    /**
     * Clear the filter for the given report.
     *
     * @param $id
     * @param Request $request
     *
     * @return RedirectResponse
     */
    public function clear($id, Request $request)
    {
        /** @var Report $report */
        $report = Report::find((int) $id);

        $request->session()->forget(md5($report->class));

        return redirect()->back();
    }

    /**
     * Send the report.
     *
     * @todo   Move to SecureReportController@store
     * @param  int $id
     *
     * @return RedirectResponse
     * @throws Exception
     */
    public function send($id)
    {
        /** @var Report $report */
        $report = Report::find((int) $id);

        if (! $report->isSensitive()) {
            Flash::error(
                "The requested report `{$report->getName()}` does not contain sensitive information, " .
                "you are free to view via the web interface."
            );
            return redirect()->route('admin.reports.show', $report);
        }

        /** @var AbstractTable $table */
        $table = $report->getReportClassInstance();

        $table->storeAsExcel($filepath = $report->getFilename('reports'));

        //return new TaxReport($filepath);
        // TODO: Implement the logic to send the sensitive file to Box.com via their API.
    }
}
