<?php

namespace App\Libs\Services;

use App\Facades\ContentTypes;
use App\Models\GenericBackoffice\WebsiteObject;
use App\Models\Theme;
use App\Models\Access;
use App\Models\Classification;
use App\Models\Typology;
use App\Models\PropertyType;
use App\Models\Location;
use App\Models\Property;
use App\Models\Chronology;
use App\Models\Epigraph;
use App\Models\GenericBackoffice\WebsiteObjectLanguage;
use App\Facades\Services\BackofficeService;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use App\Exceptions\ImportException;
use Exception;
use Illuminate\Support\Facades\DB;
use RequestContext;
use Illuminate\Support\Facades\Cache;

class CleanImportService
{
    public function showerData($types)
    {
        $langs = getAvailableLanguages();
        $properties = RequestContext::get('importPropertyIds');
        $epigraphs = RequestContext::get('importEpigraphIds');
        $propertyIds = [];
        $epigraphIds = [];
        if (!is_null($properties) && count($properties) > 0) {
            $propertyModels = Property::select('id')->whereNotIn('external_id', $properties)->get();
            $propertyIds = $propertyModels->pluck("id")->toArray();
            WebsiteObject::where('content_type', 'properties')->whereIn('object_id', $propertyIds)->delete();
            Property::destroy($propertyIds);
        }
        if (!is_null($epigraphs) && count($epigraphs) > 0) {
            $epigraphModels = Epigraph::select('id')->whereNotIn('external_id', $epigraphs)->get();
            $epigraphIds = $epigraphModels->pluck("id")->toArray();
            WebsiteObject::where('content_type', 'epigraphs')->whereIn('object_id', $epigraphIds)->delete();
            Epigraph::destroy($epigraphIds);
        }
        foreach ($types as $type) {
            $modelClass = '';
            $relations = [];
            $contentType = '';
            switch ($type) {
                case 'Themes':
                    $modelClass = Theme::class;
                    $relations = ['epigraphs', 'properties'];
                    $contentType = 'themes';
                break;
                case 'Accesses':
                    $modelClass = Access::class;
                    $relations = ['properties'];
                    $contentType = 'accesses';
                break;
                case 'Classifications':
                    $modelClass = Classification::class;
                    $relations = ['epigraphs', 'properties'];
                    $contentType = 'classifications';
                break;
                case 'Typologies':
                    $modelClass = Typology::class;
                    $relations = ['properties'];
                    $contentType = 'typologies';
                break;
                case 'PropertyTypes':
                    $modelClass = PropertyType::class;
                    $relations = ['property'];
                    $contentType = 'propertytypes';
                break;
                case 'Locations':
                    $modelClass = Location::class;
                    $relations = ['property'];
                    $contentType = 'locations';
                break;
                case 'Chronologies':
                    $modelClass = Chronology::class;
                    $relations = ['properties', 'epigraphs'];
                    $contentType = 'chronologies';
                break;
            }
            if ($modelClass && count($relations) > 0 && $contentType) {
                $this->_deleteNonRelated($modelClass, $relations, $contentType);
            }
            foreach ($langs as $lang => $value) {
                Cache::forget("properties-{$lang}");
            }
        }
    }

    private function _deleteNonRelated(String $model, array $relations, String $contentType)
    {
        DB::beginTransaction();
        try {
            $query = $model::full();
            foreach ($relations as $relation) {
                $query->doesntHave($relation);
            }
            $query->get();
            $idsToDelete = $query->pluck('id');
            $websiteIdsToDelete = [];
            foreach ($idsToDelete as $id) {
                $websiteObject = $this->factoryFind("GenericBackoffice\WebsiteObject", [
                    'object_id'    => $id,
                    'object_type'  => $model,
                    'content_type' => $contentType,
                ]);
                $websiteIdsToDelete[] = $websiteObject->id;
            }
            $model::destroy($idsToDelete);
            WebsiteObject::destroy($websiteIdsToDelete);
            DB::commit();
        } catch (Exception $e) {
            DB::rollback();
            throw new ImportException($e);
        }
    }

    private function factoryFind($type, $searchArguments, $findAll = false)
    {
        $class = "App\Models\\".$type;
        if ($findAll) {
            return $class::where($searchArguments)->get();
        } else {
            return $class::where($searchArguments)->first();
        }
    }
}
