<?php

namespace App\Http\Controllers;

use App\Template;
use App\Translation;
use Illuminate\Support\Arr;
use Illuminate\Http\Request;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Storage;
use App\Http\Resources\Templates as TemplateCollection;

class ApiController extends Controller
{
    public $cache_key;
    public $filename;
    private $defaultLocale = 'en';

    public function exports(Request $request)
    {
        $page = $request->page;
        $resutls = $request->results;
        $exportTo = $request->export;
        $keyCache = "export-{$request->type}-{$page}";

        Cache::forever($keyCache, $resutls);

        return $this->getCache($keyCache);
    }

    public function templates()
    {
        return TemplateCollection::collection(Template::all());
    }

    public function buildExportFile(Request $request)
    {
        $datas = $request->all();
        $datas['key'] = "export-{$request->type}-";

        if ($request->exportTo == 'blogspot') {
            return $this->blogspot($datas);
        }

        return $this->wordpress($datas);
    }

    private function blogspot(Array $data)
    {
        if ($data['type'] == 'movie') {
            return $this->blogspotMovie($data);
        }

        return $this->blogspotTv($data);
    }

    private function blogspotMovie(Array $data)
    {
        $templates = new Template();
        $filename = $data['key'].now()->timestamp.".xml";
        $view = view('export-file-components.blogspot', compact(['data', 'templates']))->render();
        Storage::disk('publish')->put($filename, $view);

        return response()->json($filename);
    }

    private function blogspotTv(Array $data)
    {
        $templates = new Template();
        $filename = $data['key'].now()->timestamp.".xml";
        $view = view('export-file-components.blogspot', compact(['data', 'templates']))->render();
        Storage::disk('publish')->put($filename, $view);

        return response()->json($filename);
    }

    private function wordpress(Array $data)
    {
        if ($data['type'] == 'movie') {
            return $this->wordpressMovie($data);
        }

        return $this->wordpressTv($data);
    }

    private function wordpressMovie(Array $data)
    {
        $templates = new Template();
        $filename = $data['key'].now()->timestamp.".wrx";
        $view = view('export-file-components.wordpress', compact(['data', 'templates']))->render();
        Storage::disk('publish')->put($filename, $view);

        return response()->json($filename);
    }

    private function wordpressTv(Array $data)
    {
        $templates = new Template();
        $filename = $data['key'].now()->timestamp.".wrx";
        $view = view('export-file-components.wordpress', compact(['data', 'templates']))->render();
        Storage::disk('publish')->put($filename, $view);

        return response()->json($filename);
    }

    public function downloadFile(Request $request)
    {
        $url = Storage::disk('publish')->url($request->filename);

        if ($stream = fopen($url, 'r')) {
            echo file_get_contents($url);
            fclose($stream);
        }
    }

    public function clearExport(Request $request)
    {
        $page_range = range($request->start_page, $request->finish_page);

        for ($i=1; $i <= count($page_range); $i++) {
            $keyCache = "export-{$request->type}-{$i}";
            Cache::forget($keyCache);
        }

        Storage::disk('publish')->delete($request->filename);
        return "clear success";
    }

    private function getCache($key)
    {
        return Cache::get($key);
    }

    private function forgetCache($key)
    {
        Cache::forget($key);
    }

    public function languages()
    {
        return array_keys(config('app.locales'));
    }

    public function translations($language)
    {
        $files       = new Filesystem;
        $lang_path   = resource_path('lang');
        $directories = $files->directories($lang_path);

        foreach ($directories as $directory) {
            $files = basename($directory);
            if ($files === $language) {
                $this->loadDirectory($directory, $language, '*');
            }
        }
    }

    private function loadDirectory($path, $locale, $namespace = '*', $group = '')
    {
        // Load all files inside subdirectories:
        $files = new Filesystem;

        // Load all files in root:
        $files = $files->files($path);
        foreach ($files as $file) {
            $this->loadFile($file, $locale, $namespace, $group);
        }
    }

    private function loadFile($file, $locale, $namespace = '*', $group = '')
    {
        $files = new Filesystem;
        $group = $group . basename($file, '.php');

        if ($group !== 'index') {
            $translations = $files->getRequire($file);
            $this->loadArray($translations, $locale, $group, $namespace);
        }
    }

    private function loadArray(array $lines, $locale, $group, $namespace = '*')
    {
        // Transform the lines into a flat dot array:
        $lines = Arr::dot($lines);
        foreach ($lines as $item => $text) {
            if (is_string($text)) {
                // Check if the entry exists in the database:
                $translation = Translation::whereLocale($locale)
                    ->whereNamespace($namespace)
                    ->whereGroup($group)
                    ->whereItem($item)
                    ->first();

                // If the translation already exists, we update the text:
                if ($translation && !$translation->isLocked()) {
                    $translation->text = $text;
                    $saved             = $translation->save();
                    if ($saved && $translation->locale === $this->defaultLocale) {
                        $this->flagAsUnstable($namespace, $group, $item);
                    }
                }
                // If no entry was found, create it:
                else {
                    $this->create(compact('locale', 'namespace', 'group', 'item', 'text'));
                }
            }
        }

    }

    private function flagAsUnstable($namespace, $group, $item)
    {
        Translation::whereNamespace($namespace)
                    ->whereGroup($group)
                    ->whereItem($item)
                    ->where('locale', '!=', $this->defaultLocale)
                    ->update(['unstable' => '1']);
    }

    private function create(array $attributes)
    {
        return $this->myValidate($attributes) ? Translation::create($attributes) : null;
    }

    private function myValidate(array $attributes)
    {
        $table     = (new Translation())->getTable();
        $locale    = Arr::get($attributes, 'locale', '');
        $namespace = Arr::get($attributes, 'namespace', '');
        $group     = Arr::get($attributes, 'group', '');
        $rules     = [
            'locale'    => 'required',
            'namespace' => 'required',
            'group'     => 'required',
            'item'      => "required|unique:{$table},item,NULL,id,locale,{$locale},namespace,{$namespace},group,{$group}",
            'text'      => '', // Translations may be empty
        ];
        $validator = app()->validator->make($attributes, $rules);
        if ($validator->fails()) {
            $this->errors = $validator->errors();
            return false;
        }
        return true;
    }
}
