<?php

namespace App;

use MtcPharmacy\Multisite\Classes\MultisiteManager;
use MtcPharmacy\Multisite\Classes\MultisiteConstants;
use Mtc\Cms\Models\Page as CmsPage;
use Mtc\Shop\Item as ShopItem;
use Mtc\Shop\Brand;
use Mtc\Shop\Category;
use Illuminate\Database\Eloquent\Model;
use MtcPharmacy\Multisite\Classes\MultisiteBaseEntity;
use Illuminate\Support\Collection;


class MultisiteHelper
{

    public static function getCmsPageToDisplay($requested_id)
    {
        $seed = CmsPage::find($requested_id);

        if(!empty($seed)) {
            return self::getObjectToDisplay($seed);
        }

        return null;
    }


    public static function getProductToDisplay($requested_id)
    {
        $seed = ShopItem::find($requested_id);

        return self::getObjectToDisplay($seed);
    }


    public static function getBrandToDisplay($requested_id)
    {
        $seed = Brand::find($requested_id);

        return self::getObjectToDisplay($seed);
    }


    public static function getCategoryToDisplay($requested_id)
    {
        $seed = Category::find($requested_id);

        return self::getObjectToDisplay($seed);
    }


    private static function getObjectToDisplay(Model $seed)
    {
        $obj_to_display = null;

        $multisite_manager = new MultisiteManager($seed);
        $obj_to_display = $multisite_manager->getDisplayEntity();

        return $obj_to_display;
    }


    /***/


    public static function export(string $entity_type, array $params)
    {
        $config = self::getExportConfigFromEntityType($entity_type);

        MultisiteManager::decorateQueryWithMultisiteInfo($config->query, $entity_type);
        if (isset($params['multisite__site_id'])) {
            $config->query->having('ms_site_id', '=', $params['multisite__site_id']);
            $config->query->orHaving('ms_mode', '=', MultisiteConstants::MODE_SINGLE_SITE);
        }


        $config->query->addSelect($config->fields_to_select);

        $rows = $config->query->get()->toArray();
        $csv = array_to_csv($rows);

        $ts = date('Ymd_His');
        \Util::force_download("{$config->file_name}__site:{$params['multisite__site_id']}__{$ts}.csv", $csv);

        exit;
    }


    private static function getExportConfigFromEntityType($entity_type)
    {
        $config = new \stdClass();

        switch ($entity_type) {
            case MultisiteConstants::ENTITY_TYPE_SHOP_BRAND:
                $config->fields_to_select = Brand::getExportableFields();
                $config->query = Brand::query()->where('brands.deleted', false);
                $config->file_name = 'brands';
                break;
            case MultisiteConstants::ENTITY_TYPE_SHOP_CATEGORY:
                $config->fields_to_select = Category::getExportableFields();
                $config->query = Category::query()->where('deleted', false);
                $config->file_name = 'categories';
                break;
            case MultisiteConstants::ENTITY_TYPE_SHOP_ITEM:
                $config->fields_to_select = ShopItem::getExportableFields();
                $config->query = ShopItem::query();
                $config->file_name = 'shop_items';
                break;
            case MultisiteConstants::ENTITY_TYPE_CMS_PAGE:
                $config->fields_to_select = CmsPage::getExportableFields();
                $config->query = CmsPage::query();
                $config->file_name = 'cms_pages';
                break;
        }

        return $config;
    }


    public static function import(string $entity_type, array $params)
    {
        $result = validate_csv_upload('import');

        $update_log = [
            'updated' => [],
            'failed' => [],
            'not_found' => [],
        ];

        if (! $result['errors']) {
            $class_name = self::getClassNameFromEntityType($entity_type);

            $first = true;
            while (($csv_data = fgetcsv($result['handle'], null, ',')) !== false) {
                if ($first) {
                    $columns = $csv_data;
                    $first = false;
                } else {
                    $data = array_combine($columns, $csv_data);

                    $temp_page = ($class_name)::find($data['id']);
                    if ($temp_page) {
                        $temp_page->fill($data);
                        if ($temp_page->save()) {
                            $update_log['updated'][] = $temp_page->id;
                        } else {
                            $update_log['failed'][] = $temp_page->id;
                        }
                    } else {
                        $update_log['not_found'][] = $data['id'];
                    }
                }
            }

        }

        return [
            'errors' => $result['errors'],
            'success' => self::createSuccessMessage($update_log),
        ];
    }


    private static function getClassNameFromEntityType(string $entity_type)
    {
        $class_name = '';

        switch ($entity_type) {
            case MultisiteConstants::ENTITY_TYPE_SHOP_BRAND:
                $class_name = Brand::class;
                break;
            case MultisiteConstants::ENTITY_TYPE_SHOP_CATEGORY:
                $class_name = Category::class;
                break;
            case MultisiteConstants::ENTITY_TYPE_SHOP_ITEM:
                $class_name = ShopItem::class;
                break;
            case MultisiteConstants::ENTITY_TYPE_CMS_PAGE:
                $class_name = CmsPage::class;
                break;
        }

        return $class_name;
    }


    private static function createSuccessMessage(array $update_log)
    {
        $updated_count = count($update_log['updated']);
        $msg = "Updated {$updated_count} records.<br />";

        $failed_records = implode(', ', $update_log['failed']);
        if ($failed_records) {
            $msg .= "Could not update the following records: {$failed_records}.<br />";
        }

        $notfound_records = implode(', ', $update_log['not_found']);
        if ($notfound_records) {
            $msg .= "Could not find the following records: {$notfound_records}.<br />";
        }

        return $msg;
    }


    public static function ensureProductMultisiteReady(ShopItem $product)
    {
        $mm = new MultisiteManager($product);
        $mm->getBaseEntity();

        foreach ($product->categories as $category) {
            $mm = new MultisiteManager($category);
            $mm->getBaseEntity();
        }

        foreach ($product->brands as $brand) {
            $mm = new MultisiteManager($brand);
            $mm->getBaseEntity();
        }
    }


    public static function getCategoriesToDisplay($parent_category_id = 0, ?callable $modify_query = null)
    {
        $categories_query = \Mtc\Shop\Category::query()
            ->selectRaw('categories.*')
            ->active()
            ->where('sub_id', $parent_category_id)
            ->orderBy('name')
        ;

        if ($modify_query) {
            $modify_query($categories_query);
        }

        MultisiteManager::decorateQueryWithMultisiteInfo(
            $categories_query,
            MultisiteConstants::ENTITY_TYPE_SHOP_CATEGORY,
            true
        );

        $categories = $categories_query->get();

        return $categories;
    }

}
