<?php

namespace App\Http\Controllers;

use App\Exports\SeoDataExport;
use App\Http\Requests\ImportSeoDataRequest;
use App\Http\Requests\StoreSeoDataRequest;
use App\Http\Requests\UpdateSeoDataRequest;
use App\Http\Resources\SeoDataResource;
use App\Imports\SeoDataImport;
use App\Models\BulkImportLog;
use Carbon\Carbon;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use Mtc\ContentManager\Facades\Media;
use Mtc\MercuryDataModels\SeoData;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class SeoDataController extends Controller
{
    public function __construct()
    {
        $this->middleware([
//            'permission:edit-seo',
        ]);
    }

    /**
     * List Seo Data entries
     *
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function index(Request $request): LengthAwarePaginator
    {
        return SeoData::query()
            ->select(['id', 'path', 'title', 'description'])
            ->setSortBy($request->input('sort_by', 'id_desc'))
            ->when(
                $request->filled('search_term'),
                fn($query) => $query->where('path', 'like', "%" . $request->input('search_term') . "%")
            )
            ->paginate();
    }

    /**
     * Store seo entry
     *
     * @param StoreSeoDataRequest $request
     * @param SeoData $data
     * @return SeoDataResource
     */
    public function store(StoreSeoDataRequest $request, SeoData $data): SeoDataResource
    {
        $data->fill($request->input())->save();
        return new SeoDataResource($data);
    }


    public function show(SeoData $data): SeoDataResource
    {
        return new SeoDataResource($data);
    }

    /**
     * Update seo entry
     *
     * @param UpdateSeoDataRequest $request
     * @param SeoData $data
     * @return SeoDataResource
     */
    public function update(UpdateSeoDataRequest $request, SeoData $data): SeoDataResource
    {
        $data->update($request->input());
        $this->attachContentMedia($data);
        return new SeoDataResource($data);
    }

    /**
     * Delete seo entry
     *
     * @param SeoData $seoData
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function destroy(Request $request, SeoData $data)
    {
        $data->delete();
        return $this->index($request);
    }

    /**
     * Import seo data from file
     *
     * @param ImportSeoDataRequest $request
     * @return bool[]
     */
    public function import(ImportSeoDataRequest $request): array
    {
        $tmpName = 'meta-import-' . Carbon::now()->format('Y_m_d_H_i_s') . '.'
            . $request->file('file')->getClientOriginalExtension();
        $path_to_file = 'meta-import/' . $tmpName;

        Storage::disk('file-storage')->put($path_to_file, $request->file('file')->getContent());
        BulkImportLog::query()
            ->create([
                'user_id' => Auth::id(),
                'object_type' => 'seo-meta',
                'automations' => collect([
                    'remove-existing' => $request->input('truncate'),
                ])->filter(),
                'filename' => $path_to_file,
            ]);
        if ($request->input('truncate')) {
            SeoData::query()->update([
                'title' => null,
                'description' => null,
            ]);
        }

        Excel::import(new SeoDataImport(), $path_to_file, 'file-storage');
        return [
            'success' => true,
        ];
    }

    /**
     * Export seo data to excel file
     *
     * @return BinaryFileResponse
     */
    public function export()
    {
        return Excel::download(new SeoDataExport(), 'seo_data.xlsx');
    }

    /**
     * Bulk delete seo entry
     *
     * @return JsonResponse
     */
    public function bulkDestroy(Request $request): JsonResponse
    {
        if ($request->has('ids')) {
            SeoData::query()
                ->whereIn('id', $request->input('ids'))
                ->delete();

            return response()->json([
                'success' => true,
            ]);
        }

        return response()->json([
            'success' => false,
        ]);
    }

    /**
     * Make sure media file values are synced
     * @return void
     */
    private function attachContentMedia(SeoData $data)
    {
        $mediaFiles = collect();
        $this->getMediaFilesFromStructure(collect($data->content ?? []), $mediaFiles);
        Media::setUsesForModel($mediaFiles->flatten()->unique()->toArray(), $data);
    }

    private function getMediaFilesFromStructure(Collection $group, Collection $mediaFiles): void
    {
        $group->each(function ($content) use ($mediaFiles) {
            if (($content['field_type'] ?? '') === 'image' || ($content['fieldId'] ?? '') === 'image') {
                $mediaFiles->push($content['content'] ?? []);
            }
            if (!empty($content['children'])) {
                $this->getMediaFilesFromStructure(collect($content['children']), $mediaFiles);
            }
        });
    }
}
