<?php

declare(strict_types=1);

namespace KupShop\UserBundle\Feed\Wrapper;

use KupShop\FeedsBundle\Wrapper\BaseWrapper;
use KupShop\FeedsBundle\Wrapper\LanguageWrapper;
use KupShop\KupShopBundle\Context\CountryContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\UserBundle\Feed\FeedUserCollection;
use Query\Operator;

class UserWrapper extends BaseWrapper
{
    protected FeedUserCollection $users;

    protected array $feedRow;

    /** @var \User */
    protected $object;

    /** @private */
    public function setFeedRow(array $feedRow): void
    {
        $this->feedRow = $feedRow;
    }

    /** @private */
    public function setUsers(FeedUserCollection $users): void
    {
        $this->users = $users;
    }

    /** ID uživatele */
    public function field_id(): int
    {
        return $this->object->id;
    }

    /** Datum registrace */
    public function field_date_registered(): ?\DateTimeInterface
    {
        if (isset($this->object->date_reg)) {
            return new \DateTime($this->object->date_reg);
        }

        return null;
    }

    /**
     * Jazyk uživatele.
     *
     * @deprecated use field_language
     */
    public function field_id_language(): ?string
    {
        return $this->object->id_language;
    }

    /** Jazyk uživatele */
    public function field_language(): ?LanguageWrapper
    {
        $language = null;
        if ($this->object->id_language) {
            $language = Contexts::get(LanguageContext::class)->getAll()[$this->object->id_language] ?? null;
        }

        return $language ? LanguageWrapper::wrap($language) : null;
    }

    /** E-mail */
    public function field_email(): string
    {
        return $this->object->email;
    }

    /** Viditelnost */
    public function field_figure(): string
    {
        return $this->object->figure;
    }

    /** Přihlášení k newsletteru */
    public function field_newsletter_subscribe(): string
    {
        return $this->object->get_news ?? 'N';
    }

    /** Datum přihlášení k newsletteru */
    public function field_newsletter_date_subscribe(): ?\DateTimeInterface
    {
        if (isset($this->object->date_subscribe)) {
            return new \DateTime($this->object->date_subscribe);
        }

        return null;
    }

    /** Datum odhlášení od newsletteru */
    public function field_newsletter_date_unsubscribe(): ?\DateTimeInterface
    {
        if (isset($this->object->date_unsubscribe)) {
            return new \DateTime($this->object->date_unsubscribe);
        }

        return null;
    }

    /** Pohlaví */
    public function field_gender(): ?string
    {
        return $this->object->gender;
    }

    /** Jméno */
    public function field_name(): string
    {
        return $this->object->name ?? '';
    }

    /** Přijmení */
    public function field_surname(): string
    {
        return $this->object->surname ?? '';
    }

    /** Firma */
    public function field_firm(): string
    {
        return $this->object->firm ?? '';
    }

    /** Ulice */
    public function field_street(): string
    {
        return $this->object->street ?? '';
    }

    /** Město */
    public function field_city(): string
    {
        return $this->object->city ?? '';
    }

    /** PSČ */
    public function field_zip(): string
    {
        return $this->object->zip ?? '';
    }

    /** Telefon */
    public function field_phone(): string
    {
        return $this->object->phone ?? '';
    }

    /** Země */
    public function field_country(): string
    {
        $countryContext = Contexts::get(CountryContext::class);

        if ($countryContext->getAll()[$this->object->country ?? ''] ?? false) {
            return $countryContext->getAll()[$this->object->country]->getName();
        }

        return $this->object->country ?? '';
    }

    /** IČO */
    public function field_ico(): string
    {
        return $this->object->ico ?? '';
    }

    /** DIČ */
    public function field_dic(): string
    {
        return $this->object->dic ?? '';
    }

    /** Doručovací jméno */
    public function field_delivery_name(): string
    {
        return $this->object->delivery_name ?? '';
    }

    /** Doručovací přijmení */
    public function field_delivery_surname(): string
    {
        return $this->object->delivery_surname ?? '';
    }

    /** Doručovací firma */
    public function field_delivery_firm(): string
    {
        return $this->object->delivery_firm ?? '';
    }

    /** Doručovací ulice */
    public function field_delivery_street(): string
    {
        return $this->object->delivery_street ?? '';
    }

    /** Doručovací město */
    public function field_delivery_city(): string
    {
        return $this->object->delivery_city ?? '';
    }

    /** Doručovací PSČ */
    public function field_delivery_zip(): string
    {
        return $this->object->delivery_zip ?? '';
    }

    /** Doručovací telefon */
    public function field_delivery_phone(): string
    {
        return $this->object->delivery_phone ?? '';
    }

    /** Doručovací země */
    public function field_delivery_country(): string
    {
        $countryContext = Contexts::get(CountryContext::class);

        if ($countryContext->getAll()[$this->object->delivery_country ?? ''] ?? false) {
            return $countryContext->getAll()[$this->object->delivery_country]->getName();
        }

        return $this->object->delivery_country ?? '';
    }

    public function field_birthdate(): ?\DateTimeInterface
    {
        if (isset($this->object->birthdate)) {
            return new \DateTime($this->object->birthdate);
        }

        return null;
    }

    /** Uživatelské skupiny */
    public function field_groups(): array
    {
        return $this->object->getGroups();
    }

    /** Cenová hladina uživatele */
    public function field_price_level(): array
    {
        if ($priceLevel = $this->object->getPriceLevel()) {
            return [
                'id' => $priceLevel->getId(),
                'name' => $priceLevel->getName(),
            ];
        }

        return [];
    }

    /** Počet objednávek */
    public function field_orders_count(): int
    {
        if (!$this->users->ordersCountFetched) {
            $qb = sqlQueryBuilder()
                ->select('id_user, COUNT(*) as count')
                ->from('orders')
                ->where(Operator::inIntArray($this->users->getKeys(), 'id_user'))
                ->groupBy('id_user')
                ->orderBy('id_user');
            foreach ($qb->execute() as $row) {
                if (isset($this->users[$row['id_user']])) {
                    $this->users[$row['id_user']]->orders_count = $row['count'];
                }
            }
            $this->users->ordersCountFetched = true;
        }

        return $this->object->orders_count ?? 0;
    }

    /** Průměrná cena objednávky */
    public function field_average_order_price(): float
    {
        if (!$this->users->averageOrderPriceFetched) {
            $qb = sqlQueryBuilder()
                ->select('id_user, AVG(total_price) as avg_price')
                ->from('orders')
                ->where(Operator::inIntArray($this->users->getKeys(), 'id_user'))
                ->groupBy('id_user')
                ->orderBy('id_user');

            foreach ($qb->execute() as $row) {
                if (isset($this->users[$row['id_user']])) {
                    $this->users[$row['id_user']]->average_order_price = round((float) $row['avg_price'], 2);
                }
            }
            $this->users->averageOrderPriceFetched = true;
        }

        return $this->object->average_order_price ?? 0.0;
    }

    /** Datum poslední objednávky */
    public function field_newest_order_date(): ?\DateTimeInterface
    {
        if (!$this->users->newestOrderDateFetched) {
            $qb = sqlQueryBuilder()
                ->select('id_user, MAX(date_created) as newest_date')
                ->from('orders')
                ->where(Operator::inIntArray($this->users->getKeys(), 'id_user'))
                ->groupBy('id_user');

            foreach ($qb->execute() as $row) {
                if (isset($this->users[$row['id_user']])) {
                    $this->users[$row['id_user']]->newest_order_date = $row['newest_date'] ? new \DateTime($row['newest_date']) : null;
                }
            }
            $this->users->newestOrderDateFetched = true;
        }

        return $this->object->newest_order_date ?? null;
    }
}
