<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

use Mtc\Cms\Models\Page as CmsPage;
use Mtc\Shop\Brand;
use Mtc\Shop\Category;
use Mtc\Shop\Item as ShopItem;

use MtcPharmacy\Multisite\Classes\MultisiteConstants;
use MtcPharmacy\Multisite\Classes\MultisiteManager;

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);
        return $multisite_manager->getDisplayEntity();
    }

    

    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, ',', escape: '\\')) !== 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 = '';

        return match ($entity_type) {
            MultisiteConstants::ENTITY_TYPE_SHOP_BRAND => Brand::class,
            MultisiteConstants::ENTITY_TYPE_SHOP_CATEGORY => Category::class,
            MultisiteConstants::ENTITY_TYPE_SHOP_ITEM => ShopItem::class,
            MultisiteConstants::ENTITY_TYPE_CMS_PAGE => CmsPage::class,
            default => $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,
        );

        return $categories_query->get();
    }
}
