<?php

namespace App\Services;

use App\Models\Account\Account;
use App\Models\Gallery\Gallery;
use App\Models\Gallery\GalleryItem;
use App\Models\Gallery\GallerySection;
use App\Models\Gallery\ImageItem;
use DB;
use Batch;
use Storage;

/**
 * Provides Gallery business logic (creation, update, etc)
 */
class GalleryService
{
    public function getGalleries(Account $account, Array $filters)
    {
        $query = $account->galleries();

        if (!empty($filters['isFavourite'])) {
            $query->where('is_favourite', true);
        }

        if ($filters['state'] !== '') {
            $query->where('state', $filters['state']);
        }

        $count = $query->count();

        $list = $query->limit($filters['limit'])
            ->offset($filters['offset'])
            ->get();

        return [
            'results' => $list,
            'pagination' => [
                'limit' => $filters['limit'],
                'offset' => $filters['offset'],
                'total' => $count
            ]
        ];
    }

    public function createGallery(Account $account = null)
    {
        $gallery = null;
        DB::transaction(function () use ($account, &$gallery) {
            $gallery = new Gallery();
            $gallery->uid = \Str::random(config('app.uid_length'));
            $gallery->state = Gallery::STATE_ACTIVE;
            $gallery->header_settings = [];
            $gallery->is_favourite = false;
            if ($account) {
                // If account gallery, checks limits (TODO)
                $gallery->account()->associate($account);
            }
            $gallery->save();

            // Creates default section
            $defaultSection = new GallerySection();
            $defaultSection->uid = \Str::random(config('app.uid_length'));
            $defaultSection->gallery()->associate($gallery);
            $defaultSection->position = 0;
            $defaultSection->save();
        });
        return $gallery;
    }

    public function createGalleryItem(Gallery $gallery, GallerySection $section, $file, $position)
    {
        $galleryItem = null;
        DB::transaction(function () use ($gallery, $section, $file, $position, &$galleryItem) {
            $accountUid = $gallery->account->uid;
            $galleryUid = $gallery->uid;
            $itemUid = \Str::random(7);
            $filenameParts = explode('.', $file['name']);
            $generatedFilename = $itemUid . '.' . strtolower(array_pop($filenameParts));
            $key = "a/$accountUid/g/$galleryUid/i/" . $generatedFilename;

            $imageItem = new ImageItem();
            $imageItem->uid = \Str::random(7);
            $imageItem->original_filename = $file['name'];
            $imageItem->file_size = $file['size'];
            $imageItem->key = $key;
            $imageItem->save();

            $galleryItem = new GalleryItem();
            $galleryItem->uid = $itemUid;
            $galleryItem->gallery()->associate($gallery);
            $galleryItem->gallerySection()->associate($section);
            $galleryItem->type = GalleryItem::TYPE_IMAGE;
            $galleryItem->status = GalleryItem::STATUS_NEW;
            $galleryItem->columns = 1;
            $galleryItem->is_recommended = 0;
            $galleryItem->position = $position;
            $galleryItem->imageItem()->associate($imageItem);
            $galleryItem->save();
        });
        return $galleryItem;
    }

    public function updateGalleryItem(GalleryItem $item, $data)
    {
        if (isset($data['status']) && $data['status'] !== $item->status) {
            if ($data['status'] === GalleryItem::STATUS_READY) {
                //$item->gallery->
            }
            $item->status = $data['status'];
        }
        if (isset($data['columns'])) {
            $item->columns = $data['columns'];
        }
        $item->save();
        return $item;
    }

    public function deleteGalleryItem(GalleryItem $item)
    {
        DB::transaction(function () use ($item) {
            if ($item->type === GalleryItem::TYPE_IMAGE) {
                $imageItem = $item->imageItem;
                if ($imageItem !== null) {
                    Storage::disk('s3')->delete($imageItem->key);
                }
                $imageItem->delete();
            }
            $item->delete();
        });
    }

    public function updateGallery(Gallery $gallery, $data)
    {
        if (isset($data['state']) && $data['state'] !== $gallery->state) {
            // Updates gallery state
            $gallery->state = $data['state'];
        }
        $gallery->save();
    }

    public function deleteGallery(Gallery $gallery)
    {
        // TODO all related clean up
        $gallery->delete();
    }

    public function setItemMeta(GalleryItem $galleryItem, $metadata)
    {
        $imageItem = $galleryItem->imageItem;
        $imageItem->width = $metadata['width'];
        $imageItem->height = $metadata['height'];
        $imageItem->metadata = $metadata;
        $imageItem->save();
    }

    public function updateGallerySection(GallerySection $section, $data)
    {
        if (isset($data['name'])) {
            $section->name = $data['name'];
        }
        if (isset($data['description'])) {
            $section->name = $data['description'];
        }
        if (isset($data['settings'])) {
            $section->settings = $data['settings'];
        }
        $section->save();
    }

    public function updateGallerySectionOrder(GallerySection $section, $orderData)
    {
        foreach($orderData as $idx => $item) {
            $orderData[$idx]['gallery_section_id'] = $section->id;
        }

        $model = new GalleryItem;
        Batch::updateWithTwoIndex($model, $orderData, 'gallery_section_id', 'uid');
    }
}
