<?php

namespace Tobuli\Importers\Geofence;

use Facades\Repositories\GeofenceRepo;
use Tobuli\Entities\GeofenceGroup;
use Tobuli\Exceptions\ValidationException;
use Tobuli\Importers\Importer;

class GeofenceImporter extends Importer
{
    protected $defaults = [
        'active'        => 1,
        'type'          => 'polygon',
        'polygon_color' => '#ffffff',
    ];

    protected function getDefaults()
    {
        return $this->defaults;
    }

    protected function importItem($data, $attributes = [])
    {
        $data = $this->mergeDefaults($data);
        $data = $this->setUser($data, $attributes);

        if ( ! $this->validate($data)) {
            return;
        }

        $this->normalize($data);

        if ($this->getGeofence($data)) {
            return;
        }

        $this->create($data);
    }

    private function normalize(& $data)
    {
        $last_point = last($data['polygon']);
        $first_point = head($data['polygon']);

        if ($last_point != $first_point) {
            array_push($data['polygon'], $first_point);
        }

        $data['coordinates'] = json_encode($data['polygon'], JSON_NUMERIC_CHECK);

        return $data;
    }

    private function getGeofence($data)
    {
        unset($data['polygon']);
        unset($data['group']);

        return GeofenceRepo::first($data);
    }

    private function create($data)
    {
        beginTransaction();
        try {
            if ( ! empty($data['group'])) {
                $this->createGroup($data);
            }

            GeofenceRepo::create($data);
        } catch (\Exception $e) {
            rollbackTransaction();
            throw new ValidationException(['id' => trans('global.unexpected_db_error')]);
        }
        commitTransaction();
    }

    private function createGroup(& $data)
    {
        $group = GeofenceGroup::firstOrCreate([
            'title'   => $data['group'],
            'user_id' => $data['user_id']
        ]);

        $data['group_id'] = $group->id;

        unset($data['group']);
    }

    protected function getValidationRules()
    {
        return [
            'name'          => 'required',
            'type'          => 'required|in:polygon,circle',
            'polygon'       => 'required_if:type,polygon|array',
            'polygon.*.lat' => 'lat',
            'polygon.*.lng' => 'lng',
            'radius'        => 'required_if:type,circle|numeric',
            'center'        => 'required_if:type,circle',
            'center.lat'    => 'lat',
            'center.lng'    => 'lng',
        ];
    }
}
