<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder as QueryBuilder;
use MtcPharmacy\Multisite\Classes\MultisiteConstants;
use MtcPharmacy\Multisite\Classes\MultisiteManager;
use MtcPharmacy\Multisite\Classes\MultisiteSite;
use Mtc\Cms\Models\Page as CmsPage;
use Mtc\Shop\Brand as ShopBrand;
use Mtc\Shop\Category as ShopCategory;
use Mtc\Shop\Item as ShopItem;
use Spatie\Sitemap\Sitemap;


class GenerateSitemapCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'sitemap:generate';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Generate sitemap';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $sites = MultisiteSite::all();

        foreach ($sites as $site) {
            $sitemap = Sitemap::create();

            $this->info("### SITE {$site->name} ###");

            $this->generateForCms($site, $sitemap);
            $this->generateForProducts($site, $sitemap);
            $this->generateForCategories($site, $sitemap);
            $this->generateForBrands($site, $sitemap);

            $sitemap->writeToFile(SITE_PATH . $site->getSitemapFilePath());
        }

        return Command::SUCCESS;
    }


    private function generateForCms(MultisiteSite $site, Sitemap $sitemap)
    {
        $root_page = CmsPage::find(CMS_ROOT_PAGE_ID);
        $mm = new MultisiteManager($root_page);
        $base_entity = $mm->getBaseEntity();

        foreach ($base_entity->custom_entities as $custom_entity) {
            if ($custom_entity->site->id != $site->id) { continue; }

            $parent_page = $custom_entity->getConcreteEntity();
            $records = $parent_page->getAllDescendants();

            $count = $records->count();
            $this->info("Found {$count} pages to add:");

            foreach ($records as $record) {
                if ($record->type != 'default') continue;
                if (! $record->published) continue;

                $this->info(" -- id:{$record->id} [{$record->slug}],");
                $sitemap->add($record);
            }

            $this->info(" - all CMS pages done.");
        }
    }


    private function generate(MultisiteSite $site, Sitemap $sitemap, QueryBuilder $query, string $entity_type)
    {
        MultisiteManager::decorateQueryWithMultisiteInfo($query, $entity_type);

        switch ($entity_type) {
            case MultisiteConstants::ENTITY_TYPE_SHOP_ITEM:
                $query->addSelect('items.*');
                break;
            case MultisiteConstants::ENTITY_TYPE_SHOP_CATEGORY:
                $query->addSelect('categories.*');
                break;
            case MultisiteConstants::ENTITY_TYPE_SHOP_BRAND:
                $query->addSelect('brands.*');
                break;
        }

        $query->having('ms_site_id', '=', $site->id);
        $query->orHaving('ms_mode', '=', MultisiteConstants::MODE_SINGLE_SITE);

        $records = $query->get();

        $count = $records->count();
        $this->info("Found {$count} records to add:");

        foreach ($records as $record) {
            $this->info(" -- id:{$record->id} [{$record->name}],");
            $record->sitemap_site = $site;
            $sitemap->add($record);
        }

        $this->info(" - all records done.");
    }


    private function generateForProducts(MultisiteSite $site, Sitemap $sitemap)
    {
        $query = ShopItem::active();
        $this->generate($site, $sitemap, $query, MultisiteConstants::ENTITY_TYPE_SHOP_ITEM);
    }


    private function generateForCategories(MultisiteSite $site, Sitemap $sitemap)
    {
        $query = ShopCategory::active();
        $this->generate($site, $sitemap, $query, MultisiteConstants::ENTITY_TYPE_SHOP_CATEGORY);
    }


    private function generateForBrands(MultisiteSite $site, Sitemap $sitemap)
    {
        $query = ShopBrand::active();
        $this->generate($site, $sitemap, $query, MultisiteConstants::ENTITY_TYPE_SHOP_BRAND);
    }
}
