<?php
/**
 * _             _       _
 * | |____      _| | __ _| |__
 * | '_ \ \ /\ / / |/ _` | '_ \
 * | |_) \ V  V /| | (_| | |_) |
 * |_.__/ \_/\_/ |_|\__,_|_.__/.
 *
 * @author    Bwlab di Luigi Massa <info@bwlab.it>
 * @copyright since 2014 Bwlab
 * @license   proprietary
 */

declare(strict_types=1);

namespace Bwlab\Withdrawal\Controller\Admin;

if (!defined('_PS_VERSION_')) {
    exit;
}

use Bwlab\Withdrawal\Entity\WithdrawalRequest;
use Bwlab\Withdrawal\Service\WithdrawalRequestService;
use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteria;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class AdminWithdrawalRequestsController extends FrameworkBundleAdminController
{
    public function indexAction(Request $request): Response
    {
        $gridFactory = $this->get('bwwithdrawal_grid_withdrawal_request_factory');

        $filters = $request->query->all('withdrawal_request_filter') ?: [];
        $searchCriteria = new SearchCriteria(
            $filters,
            $request->query->get('orderBy', 'date_add'),
            $request->query->get('orderWay', 'DESC'),
            (int) $request->query->get('offset', 0),
            (int) $request->query->get('limit', 50)
        );

        $grid = $gridFactory->getGrid($searchCriteria);

        return $this->render(
            '@Modules/bwwithdrawal/views/templates/admin/requests-list.html.twig',
            ['grid' => $this->presentGrid($grid)]
        );
    }

    public function viewAction(int $requestId): Response
    {
        $em = $this->getDoctrine()->getManager();
        $withdrawalRequest = $em->getRepository(WithdrawalRequest::class)->find($requestId);

        if ($withdrawalRequest === null) {
            throw $this->createNotFoundException("Withdrawal request #{$requestId} not found.");
        }

        return $this->render(
            '@Modules/bwwithdrawal/views/templates/admin/request-detail.html.twig',
            ['withdrawal_request' => $withdrawalRequest]
        );
    }

    public function updateStatusAction(Request $request, int $requestId): Response
    {
        if (!$request->isMethod('POST')) {
            return $this->redirectToRoute('admin_bwwithdrawal_requests_index');
        }

        $status = $request->request->get('status', '');
        $note = $request->request->get('note', '');
        $customerNote = $request->request->get('customer_note', '');

        if (!in_array($status, WithdrawalRequest::STATUSES, true)) {
            $this->addFlash('error', $this->trans('Invalid status.', [], 'Modules.Bwwithdrawal.Admin'));

            return $this->redirectToRoute('admin_bwwithdrawal_requests_view', ['requestId' => $requestId]);
        }

        try {
            /** @var WithdrawalRequestService $service */
            $service = $this->get('bwwithdrawal.service.withdrawal_request');
            $service->updateStatus($requestId, $status, $note ?: null, $customerNote ?: null, (int) $this->getContext()->employee->id);
            $this->addFlash('success', $this->trans('Status updated successfully.', 'Modules.Bwwithdrawal.Admin', []));
        } catch (\RuntimeException $e) {
            $this->addFlash('error', $e->getMessage());
        }

        return $this->redirectToRoute('admin_bwwithdrawal_requests_view', ['requestId' => $requestId]);
    }

    public function configAction(Request $request): Response
    {
        $formHandler = $this->get('bwwithdrawal.handler.withdrawal_configuration_text_form_data_handler');
        $form = $formHandler->getForm();
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $errors = $formHandler->save($form->getData());
            empty($errors)
                ? $this->addFlash('success', $this->trans('Successful update.', [], 'Admin.Notifications.Success'))
                : $this->flashErrors($errors);
        }

        return $this->render(
            '@Modules/bwwithdrawal/views/templates/admin/configuration.html.twig',
            ['configForm' => $form->createView()]
        );
    }

    public function exportAction(Request $request): StreamedResponse
    {
        $gridFactory = $this->get('bwwithdrawal_grid_withdrawal_request_factory');
        $filters = $request->query->all('withdrawal_request_filter') ?: [];
        $searchCriteria = new SearchCriteria($filters, 'date_add', 'DESC', 0, 10000);
        $grid = $gridFactory->getGrid($searchCriteria);
        $records = $grid->getData()->getRecords()->all();

        $response = new StreamedResponse(function () use ($records) {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, ['ID', 'Order', 'Customer', 'Email', 'Status', 'Date', 'Deadline', 'Operator']);
            foreach ($records as $row) {
                fputcsv($handle, [
                    $row['id_withdrawal_request'],
                    $row['order_reference'],
                    $row['customer_name'],
                    $row['customer_email'],
                    $row['status'],
                    $row['date_add'],
                    $row['withdrawal_deadline'],
                    $row['employee_name'] ?? '',
                ]);
            }
            fclose($handle);
        });

        $response->headers->set('Content-Type', 'text/csv');
        $response->headers->set('Content-Disposition', 'attachment; filename="withdrawal-requests.csv"');

        return $response;
    }
}
