<?php

namespace Banyo\TrackOrder\Plugin\Customer;

use Magento\Customer\Controller\Account\CreatePost as CustomerCreatePost;
use Magento\Framework\Controller\Result\RedirectFactory;
use Magento\Customer\Model\Session as CustomerSession;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Api\SearchCriteriaBuilder;

class CreatePost
{
    protected $customerSession;
    protected $resultRedirectFactory;
    protected $orderRepository;
    protected $messageManager;
    protected $searchCriteriaBuilder;

    public function __construct(
        CustomerSession $customerSession,
        RedirectFactory $resultRedirectFactory,
        OrderRepositoryInterface $orderRepository,
        ManagerInterface $messageManager,
        SearchCriteriaBuilder $searchCriteriaBuilder
    ) {
        $this->customerSession = $customerSession;
        $this->resultRedirectFactory = $resultRedirectFactory;
        $this->orderRepository = $orderRepository;
        $this->messageManager = $messageManager;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
    }

    public function afterExecute(CustomerCreatePost $subject, $result)
    {
        // Init temporary Zend logger
        $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/trackorder.log');
        $logger = new \Zend_Log();
        $logger->addWriter($writer);
        $logger->info('TrackOrder Plugin: afterExecute triggered');

        if (!$this->customerSession->isLoggedIn()) {
            $logger->info('Customer is not logged in');
            return $result;
        }

        $trackOrderData = $this->customerSession->getTrackOrderRedirect();
        $logger->info('Track order session data: ' . json_encode($trackOrderData));

        if (!$trackOrderData || !isset($trackOrderData['order_id']) || !isset($trackOrderData['email'])) {
            $logger->info('Missing order_id or email in session');
            return $result;
        }

        $incrementId = $trackOrderData['order_id'];
        $email = $trackOrderData['email'];
        $customerId = $this->customerSession->getCustomerId();

        try {
            $logger->info("Loading order with increment ID: $incrementId");

            $searchCriteria = $this->searchCriteriaBuilder
                ->addFilter('increment_id', $incrementId, 'eq')
                ->create();

            $orderList = $this->orderRepository->getList($searchCriteria)->getItems();
            $order = reset($orderList);

            if (!$order) {
                $logger->info("No order found with increment ID: $incrementId");
                $this->messageManager->addErrorMessage(__('The order you are trying to access does not exist.'));
                return $result;
            }

            if (!$order->getCustomerId() &&
                strtolower($order->getCustomerEmail()) === strtolower($email)) {

                $logger->info("Linking guest order to customer ID: $customerId");
                $this->linkOrderToCustomer($order, $customerId);
                $this->customerSession->unsTrackOrderRedirect();

                $this->messageManager->addSuccessMessage(
                    __('Your order has been linked to your account.')
                );

                $logger->info("Order successfully linked to customer ID: $customerId");

                return $this->resultRedirectFactory->create()
                    ->setPath('sales/order/view', ['order_id' => $order->getEntityId()]);
            } else {
                $logger->info("Order already has a customer or email mismatch");
            }

        } catch (NoSuchEntityException $e) {
            $logger->err("Order not found: " . $e->getMessage());
            $this->messageManager->addErrorMessage(__('The order you are trying to access does not exist.'));
        } catch (\Exception $e) {
            $logger->err("Error while linking order: " . $e->getMessage());
            $this->messageManager->addErrorMessage(__('An error occurred while processing your request.'));
        }

        $this->customerSession->unsTrackOrderRedirect();
        return $result;
    }

    private function linkOrderToCustomer(OrderInterface $order, int $customerId): void
    {
        $order->setCustomerId($customerId);
        $order->setCustomerIsGuest(0);
        $this->orderRepository->save($order);
    }
}
