<?php

namespace TotalSurvey\Actions\Entries;
! defined( 'ABSPATH' ) && exit();


use TotalSurvey\Capabilities\UserCanExportEntries;
use TotalSurvey\Capabilities\UserCanViewOthersSurveys;
use TotalSurvey\Exceptions\Entries\EntryNotFound;
use TotalSurvey\Exceptions\Surveys\SurveyNotFound;
use TotalSurvey\Filters\Entries\ExportFilter;
use TotalSurvey\Tasks\Entries\ExportCSV;
use TotalSurvey\Tasks\Entries\ExportCSVAsync;
use TotalSurvey\Tasks\Entries\ExportJSON;
use TotalSurvey\Tasks\Entries\GetEntries;
use TotalSurveyVendors\TotalSuite\Foundation\Action;
use TotalSurveyVendors\TotalSuite\Foundation\Exceptions\Exception;
use TotalSurveyVendors\TotalSuite\Foundation\Http\Response;
use TotalSurveyVendors\TotalSuite\Foundation\Support\Collection;

class Export extends Action
{
    /**
     * @param $format
     *
     * @return mixed
     * @throws Exception
     */
    public function execute($format)
    {
        $filters             = $this->request->getParsedBody();
        $filters['per_page'] = null;

        if (empty($filters['survey_uid'])) {
            SurveyNotFound::throw();
        }

        if (!UserCanViewOthersSurveys::checkSurveyUid($filters['survey_uid'])) {
            EntryNotFound::throw();
        }

        if ($format === 'async') {
            return $this->exportAsync($filters);
        }

        $entries = GetEntries::invoke($filters, false);

        return $this->export($entries, $format);
    }

    /**
     * @param  Collection  $entries
     * @param            $format
     *
     * @return mixed|void
     * @throws Exception
     */
    protected function export(Collection $entries, $format)
    {
        $export = ExportFilter::apply($format);

        if ($export instanceof Response) {
            return $export;
        }

        switch ($format) {
            case 'json' :
            {
                return ExportJSON::invoke($entries);
            }
            case 'csv' :
            {
                return ExportCSV::invoke($entries);
            }
            default :
            {
                Exception::throw('Invalid export format');
            }
        }
    }

    /**
     * @inheritDoc
     */
    public function authorize(): bool
    {
        return UserCanExportEntries::check();
    }

    /**
     * @return array
     */
    public function getParams(): array
    {
        return [
            'format' => [
                'expression'        => '(?<format>([\w]+))',
                'sanitize_callback' => static function ($format) {
                    return (string) $format;
                },
            ],
        ];
    }

    public function exportAsync($filters)
    {
        $filters['per_page'] = 20;
        $entries             = Collection::create(GetEntries::invoke($filters, true)->getItems());
        $lines               = ExportCSVAsync::invoke($entries);

        if (!empty($filters['page']) && $filters['page'] > 1) {
            array_splice($lines, 0, 1);
        }

        return $lines;
    }
}
