@extends('app.app')
@section('title')
    Add Zone
@endsection
@section('customcss')
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" integrity="sha512-gc3xjCmIy673V6MyOAZhIW93xhM9ei1I+gLbmFjUHIjocENRsLX/QUE1htk5q1XV2D/iie/VQ8DXI6Vu8bexvQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vanilla-picker@2.12.1/dist/vanilla-picker.csp.css" integrity="sha256-ITHmamcImsZ/Je1xrdtDLZVvRSpj1Zokb6uHXORB824=" crossorigin="anonymous">
@endsection
@section('content')
    <div class="container-fluid">
        <div class="content">
            <div class="row">
                <div class="col-sm-12">
                    <div class="card bg-light">
                        <div class="card-header">
                            <p class="card-title text-bold mb-0">Add New Zone</p>
                        </div>
                        <div class="card-body">
                            <div class="row">
                                <div class="col-sm-5">
                                    <h6>Zone Information</h6>
                                    <div class="mb-3">
                                        <label for="add-zone_name" class="form-label">Name</label>
                                        <input type="text" class="form-control form-control-sm" name="add-zone_name" id="add-zone_name">
                                    </div>
                                    @if ($is_su)
                                        <div class="mb-3">
                                            <label for="add-zone_client" class="form-label">Company</label>
                                            <select name="add-zone_client" id="add-zone_client" class="form-control select2">
                                                <option value="">Choose</option>
                                                @foreach ($clients as $client)
                                                    <option value="{{ $client->id }}" selected>{{ $client->name }}</option>
                                                @endforeach
                                            </select>
                                        </div>
                                    @endif
                                    <div class="mb-3">
                                        <label for="add-zone_type" class="form-label">Zone Type</label>
                                        <select name="add-zone_type" id="add-zone_type" class="form-control select2">
                                            <option value="">Choose</option>
                                            @foreach ($types as $type)
                                                <option value="{{ $type->id }}">{{ $type->name }}</option>
                                            @endforeach
                                        </select>
                                    </div>
                                    <div class="mb-3">
                                        <label for="add-workflow_zone_type" class="form-label">Workflow Zone
                                            Type</label>
                                        <select name="add-workflow_zone_type" id="add-workflow_zone_type" class="form-control select2">
                                            <option value="">Choose</option>
                                            @foreach ($workflows as $workflow)
                                                <option value="{{ $workflow->id }}">{{ $workflow->name }}</option>
                                            @endforeach
                                        </select>
                                    </div>
                                    {{-- <div class="mb-3">
                                        <label for="add-shiptocode" class="form-label">Kode Pos</label>
                                        <input type="number" class="form-control form-control-sm" name="add-shiptocode" id="add-shiptocode" placeholder="postcode">
                                    </div>
                                    <div class="mb-3">
                                        <label for="add-prid" class="form-label">Provinsi</label>
                                        <select class="form-control form-control-sm select2" name="add-prid" id="add-prid">
                                            <option value="">Select Province</option>
                                            @foreach ($provs as $prov)
                                                <option value="{{ $prov->kodeProv }}">
                                                    {{ $prov->nmProvinsiKel }}</option>
                                            @endforeach
                                        </select>
                                    </div>
                                    <div class="mb-3">
                                        <label for="add-ktid" class="form-label">Kabupaten/Kota</label>
                                        <select class="form-control form-control-sm select2" name="add-ktid" id="add-ktid">
                                            <option value="">Select City</option>
                                        </select>
                                    </div>
                                    <div class="mb-3">
                                        <label for="add-kcid" class="form-label">Kecamatan</label>
                                        <select class="form-control form-control-sm select2" name="add-kcid" id="add-kcid">
                                            <option value="">Select District</option>
                                        </select>
                                    </div>
                                    <div class="mb-3">
                                        <label for="add-klid" class="form-label">Desa/Kelurahan</label>
                                        <select class="form-control form-control-sm select2" name="add-klid" id="add-klid">
                                            <option value="">Select Village</option>
                                        </select>
                                    </div> --}}
                                    <div class="mb-4">
                                        <label for="add-fulladdress" class="form-label">Full Address</label>
                                        <textarea name="add-fulladdress" id="add-fulladdress" class="form-control form-control-sm" rows="3"></textarea>
                                    </div>
                                    <h6>Lainnya</h6>
                                    <div class="mb-4">
                                        <label for="add-status" class="form-label">Status</label>
                                        <div class="form-check form-switch">
                                            <input class="form-check-input" type="checkbox" id="add-status">
                                            <label class="form-check-label" for="add-status"><span class="text-dark" id="add-txtStatus">Inactive</span></label>
                                        </div>
                                    </div>
                                </div>
                                <div class="col-sm-7">
                                    <h6>Draw Zone</h6>
                                    <div class="mb-3">
                                        <div class="row">
                                            <div class="col-3">
                                                <label for="add-boundary_color" class="form-label">Color</label>
                                                <input type="color" class="form-control form-control-sm" name="add-boundary_color" id="add-boundary_color" placeholder="hex codes">
                                            </div>
                                            <div class="col-9">
                                                <label for="add-boundary_hex" class="form-label">&nbsp;</label>
                                                <input type="text" class="form-control form-control-sm" name="add-boundary_hex" id="add-boundary_hex" value="#000000" placeholder="hex codes">
                                            </div>
                                        </div>
                                    </div>
                                    <div class="mb-3">
                                        <div class="row">
                                            <div class="col-6">
                                                <label for="add-boundary_type" class="form-label">Boundary</label>
                                                <select id="add-boundary_type" name="add-boundary_type" class="form-control select2">
                                                    <option value="">Choose</option>
                                                    @foreach ($boundarys as $boundary)
                                                        @php
                                                            if ($boundary['id'] == \App\Models\Zone::ZONE_BOUNDARY_POLYGON) {
                                                                continue;
                                                            }
                                                        @endphp
                                                        <option value="{{ $boundary['id'] }}">{{ $boundary['name'] }}</option>
                                                    @endforeach
                                                </select>
                                            </div>
                                            <div class="add-group_boundary_circle col-6 mb-3 d-none">
                                                <label for="add-boundary_radius" class="form-label">Radius
                                                    (meter)</label>
                                                <input type="text" class="form-control form-control-sm" name="add-boundary_radius" id="add-boundary_radius">
                                            </div>
                                            <div class="add-group_boundary_circle col-6 d-none">
                                                <label for="add-boundary_lat" class="form-label">Latitude</label>
                                                <input type="text" class="form-control form-control-sm" name="add-boundary_lat" id="add-boundary_lat">
                                            </div>
                                            <div class="add-group_boundary_circle col-6 d-none">
                                                <label for="add-boundary_lng" class="form-label">Longitude</label>
                                                <input type="text" class="form-control form-control-sm" name="add-boundary_lng" id="add-boundary_lng">
                                            </div>
                                        </div>
                                    </div>
                                    <div id="mapDraw" style="width:55vw;height:50vh;"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="col-sm-12">
                    <a href="{{ route('view_zone') }}" class="btn btn-sm btn-secondary">Cancel</a>
                    <button id="btnSubmitNewZone" class="btn btn-sm btn-danger">Save Zone</button>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('customjs')
    <script src="{{ asset('assets/vendor/leaflet-1.7.1/leaflet-src.js') }}"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js" integrity="sha512-ozq8xQKq6urvuU6jNgkfqAmT7jKN2XumbrX1JiB3TnF7tI48DPI4Gy1GXKD/V3EExgAs1V+pRO7vwtS1LHg0Gw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdn.jsdelivr.net/npm/vanilla-picker@2.12.1/dist/vanilla-picker.min.js" integrity="sha256-V1zh/sQiwo4NO4mg4WqQF9j79hDt7MBbTi3klxV3ZK4=" crossorigin="anonymous"></script>
    <script>
        'use strict'

        const State = {
            isDrawPolygonManual: 0,
            storage_lara: "{{ asset('storage') }}/",
            zone_status: {
                active: "{{ App\Models\Zone::STATUS_ACTIVE }}",
                inactive: "{{ App\Models\Zone::STATUS_INACTIVE }}",
            },
            boundary_type: {
                circle: "{{ App\Models\Zone::ZONE_BOUNDARY_CIRCLE }}",
                polygon: "{{ App\Models\Zone::ZONE_BOUNDARY_POLYGON }}",
                rectangle: "{{ App\Models\Zone::ZONE_BOUNDARY_RECTANGLE }}",
            },
            boundary_type_choose: null,
            boundary_latlngs: null, // [{lat,lng}].
            boundary_radius: null, // in meters. only circle
            boundary_bounds: null, // {northEast:{lat,lng},southWest:{lat,lng}}. only polygon,rectangle
            delay_typing: 1500,
            eventRemoveToolbarDraw: null,
        };

        const Wrapper = {
            activate: function() {
                Wrapper.event();
                Leaflet.activate();
                ZNew.activate();
            },
            event: function() {
                $('#add-status').bind('change', function() {
                    if ($(this).is(':checked'))
                        $('#add-txtStatus').html('Active')
                    else
                        $('#add-txtStatus').html('Inactive')
                });
            },
        };

        const Req = {
            geo_addr: function(data, isAlert = false, cb = null) {
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: "{{ route('api_osm_geo_addr') }}",
                        method: 'POST',
                        crossDomain: true,
                        processData: true,
                        headers: {
                            'x-api-key': Helper.getCookie('_trtk'),
                            'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
                        },
                        data: data,
                        success: (resp, textStatus, jqXHR) => {
                            if (cb) cb(resp);
                            if (resp.meta.type != 'success') {
                                resolve({
                                    type: 'fail'
                                });
                                if (isAlert) Helper.toast('Warning', 'just now', resp.meta
                                    .message);
                                return false;
                            }
                            resolve({
                                type: 'success',
                                resp: resp,
                            });
                        },
                        error: (jqXHR, textStatus, error) => {
                            if (cb) cb(jqXHR.responseJSON);
                            if (jqXHR.status >= 500) {
                                if (isAlert) Helper.toast('Error', 'just now',
                                    'please try again');
                            } else {
                                if (isAlert) Helper.toast('Error', 'just now', jqXHR
                                    .responseJSON.meta.message);
                            }
                            resolve({
                                type: 'error'
                            });
                        }
                    })
                })
            },
            list_city: function(data, isAlert = false, cb = null) {
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: "{{ route('api_region_list_city') }}",
                        method: 'GET',
                        crossDomain: true,
                        processData: true,
                        headers: {
                            'x-api-key': Helper.getCookie('_trtk'),
                            'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
                        },
                        data: data,
                        success: (resp, textStatus, jqXHR) => {
                            if (cb) cb(resp);
                            if (resp.meta.type != 'success') {
                                resolve({
                                    type: 'fail',
                                    msg: resp.meta.message,
                                });
                                if (isAlert) Helper.toast('Warning', 'just now', resp.meta
                                    .message);
                                return false;
                            }
                            resolve({
                                type: 'success',
                                resp: resp,
                            });
                        },
                        error: (jqXHR, textStatus, error) => {
                            if (cb) cb(jqXHR.responseJSON);
                            if (jqXHR.status >= 500) {
                                if (isAlert) Helper.toast('Error', 'just now',
                                    'please try again');
                            } else {
                                if (isAlert) Helper.toast('Error', 'just now', jqXHR
                                    .responseJSON.meta.message);
                            }
                            resolve({
                                type: 'error',
                                msg: jqXHR.responseJSON.meta.message,
                            });
                        }
                    })
                })
            },
            list_district: function(data, isAlert = false, cb = null) {
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: "{{ route('api_region_list_district') }}",
                        method: 'GET',
                        crossDomain: true,
                        processData: true,
                        headers: {
                            'x-api-key': Helper.getCookie('_trtk'),
                            'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
                        },
                        data: data,
                        success: (resp, textStatus, jqXHR) => {
                            if (cb) cb(resp);
                            if (resp.meta.type != 'success') {
                                resolve({
                                    type: 'fail',
                                    msg: resp.meta.message,
                                });
                                if (isAlert) Helper.toast('Warning', 'just now', resp.meta
                                    .message);
                                return false;
                            }
                            resolve({
                                type: 'success',
                                resp: resp,
                            });
                        },
                        error: (jqXHR, textStatus, error) => {
                            if (cb) cb(jqXHR.responseJSON);
                            if (jqXHR.status >= 500) {
                                if (isAlert) Helper.toast('Error', 'just now',
                                    'please try again');
                            } else {
                                if (isAlert) Helper.toast('Error', 'just now', jqXHR
                                    .responseJSON.meta.message);
                            }
                            resolve({
                                type: 'error',
                                msg: jqXHR.responseJSON.meta.message,
                            });
                        }
                    })
                })
            },
            list_village: function(data, isAlert = false, cb = null) {
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: "{{ route('api_region_list_village') }}",
                        method: 'GET',
                        crossDomain: true,
                        processData: true,
                        headers: {
                            'x-api-key': Helper.getCookie('_trtk'),
                            'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
                        },
                        data: data,
                        success: (resp, textStatus, jqXHR) => {
                            if (cb) cb(resp);
                            if (resp.meta.type != 'success') {
                                resolve({
                                    type: 'fail',
                                    msg: resp.meta.message,
                                });
                                if (isAlert) Helper.toast('Warning', 'just now', resp.meta
                                    .message);
                                return false;
                            }
                            resolve({
                                type: 'success',
                                resp: resp,
                            });
                        },
                        error: (jqXHR, textStatus, error) => {
                            if (cb) cb(jqXHR.responseJSON);
                            if (jqXHR.status >= 500) {
                                if (isAlert) Helper.toast('Error', 'just now',
                                    'please try again');
                            } else {
                                if (isAlert) Helper.toast('Error', 'just now', jqXHR
                                    .responseJSON.meta.message);
                            }
                            resolve({
                                type: 'error',
                                msg: jqXHR.responseJSON.meta.message,
                            });
                        }
                    })
                })
            },
        }

        const Leaflet = {
            map: null,
            activate: function() {
                // centering java archipelago => .setView([-7.1451449, 109.9776078], 6.5);
                // centering indonesia country => .setView([-1.38116, 117.6168817], 5.4);
                Leaflet.map = L.map('mapDraw').setView([-8.90507, 125.9945732], 9);
                L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
                    attribution: 'Map data &copy; <a href="https://www.mapbox.com/feedback/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
                    maxZoom: 20,
                    minZoom: 4,
                    id: 'mapbox/streets-v11',
                    tileSize: 512,
                    zoomOffset: -1,
                    accessToken: 'pk.eyJ1IjoibWV1c2luZmlybWFyeSIsImEiOiJja3lsd2xveDAydGhqMnVxaHJsZ2ZncG8yIn0.f7MJAyawHUdCegw7sWjrww',
                }).addTo(Leaflet.map);
                Leaflet.events();
            },
            events: function() {
                Leaflet.map.on('click', function(e) {
                    if (State.isDrawPolygonManual) {
                        Leaflet.drawPolygon(e.latlng.lat, e.latlng.lng, {});
                    }
                })
            },
            addCircles: function(locs = [], cb = null) {
                if (locs.constructor === Array) {
                    let circles = [];
                    for (let i = 0; i < locs.length; i++) {
                        let circle = L.circle([locs[i].lat, locs[i].lng], locs[i]?.options);
                        circle.bindPopup(locs[i]?.label || '');
                        circle.bindTooltip(locs[i]?.label || '');
                        circles.push(circle);
                        if (cb) cb(circle);
                        circle.addTo(Leaflet.map);
                    }
                    return circles;
                } else if (locs.constructor === Object) {
                    let circle = L.circle([locs.lat, locs.lng], locs?.options);
                    circle.bindPopup(locs?.label || '');
                    circle.bindTooltip(locs?.label || '');
                    if (cb) cb(circle);
                    circle.addTo(Leaflet.map);
                    return circle;
                }
            },
            addPolylines: function(locs = [], cb = null) {
                let latLngs = [];
                for (let i = 0; i < locs.length; i++) {
                    latLngs.push([locs[i].lat, locs[i].lng]);
                }
                let polyline = L.polyline(latLngs, locs[0]?.options).addTo(Leaflet.map);

                if (cb) cb(polyline);
                return polyline;
            },
            addPolygons: function(locs = [], cb = null) {
                let latLngs = [];
                for (let i = 0; i < locs.length; i++) {
                    latLngs.push([locs[i].lat, locs[i].lng]);
                }
                let polygon = L.polygon(latLngs, locs[0]?.options).addTo(Leaflet.map);

                if (cb) cb(polygon);
                return polygon;
            },
            drawPolygon: function(lat, lng, options = {}) {
                let polygon = L.polygon([
                    [lat, lng]
                ], options).addTo(Leaflet.map);
                return polygon;
            },
            // draw boundary by mouse
            createDrawLayer: function() {
                let drawnItems = new L.FeatureGroup().addTo(Leaflet.map);
                return drawnItems;
            },
            createDrawControl: function(options) {
                // example
                // let options = {
                //     edit: {
                //         featureGroup: drawnItems,
                //         poly: {
                //             allowIntersection: true, // draw while moving
                //         },
                //     },
                //     draw: {
                //         polygon: {
                //             allowIntersection: true, // draw while moving
                //             showArea: true,
                //         },
                //         marker: false,
                //         circlemarker: false,
                //         polyline: false,
                //     },
                // };

                let drawControl = new L.Control.Draw(options);
                return drawControl;
            },
            createDrawToolbar: function(drawnItems, drawControl) {
                // after finish not saved
                Leaflet.map.addControl(drawControl);

                Leaflet.map.on(L.Draw.Event.CREATED, function(e) {
                    // validate can create 1 shape only
                    if (!State.boundary_type_choose) { // if null
                        drawnItems.addLayer(e.layer);
                        ZNew.handleBoundaryDraw(e);
                    }
                });

                Leaflet.map.on(L.Draw.Event.EDITED, function(e) {
                    ZNew.handleBoundaryDraw(e);
                });

                Leaflet.map.on(L.Draw.Event.DELETED, function(e) {
                    ZNew.handleBoundaryDraw(e);
                });

                // remove marker, circle, event listener and all about this marker
                State.eventRemoveToolbarDraw = new CustomEvent('eventRemoveToolbarDraw', {
                    drawnItems,
                    drawControl,
                });
                window.addEventListener('eventRemoveToolbarDraw', function handler(e) {
                    Leaflet.map.removeEventListener(L.Draw.Event.CREATED);
                    Leaflet.map.removeEventListener(L.Draw.Event.EDITED);
                    Leaflet.map.removeEventListener(L.Draw.Event.DELETED);
                    Leaflet.map.removeControl(drawControl);
                    Leaflet.map.removeLayer(drawnItems);
                    e.currentTarget.removeEventListener(e.type,
                        handler); // window.removeEventListener('remove', this.handler, true);
                    State.eventRemoveToolbarDraw = null;
                    State.boundary_type_choose = null;
                    State.boundary_latlngs = null;
                    ZNew.toggleInputCircle(false, false);
                });
            },
            injectShapeToLDraw: function(obj) {
                /**@argument
                 * create shape / vector layer
                 * convert the layer toGeoJSON/toGeoJson with precision default is 6
                 * set L.Draw toolbar/control layer
                 * convert the geoJSON shape/vector layer to leaflet geoJSON format
                 * add the shape/vector leaflet geoJSON format layer to L.Draw toolbar/control layer
                 **/

                // for L.Draw
                let shapeOpts = {
                    color: obj.boundary_hex_color,
                    fillOpacity: 0.4,
                    showRadius: true,
                };
                let drawnItems = Leaflet.createDrawLayer();
                let drawControlOpts = {
                    edit: {
                        featureGroup: drawnItems,
                    },
                    draw: {
                        polygon: false,
                        marker: false,
                        circle: false,
                        rectangle: false,
                        circlemarker: false,
                        polyline: false,
                    },
                };
                // for layer (Shape / Vector)
                let fitBounds = [],
                    circle = null,
                    polygon = null,
                    shapeGeoJSON = null;
                let label = `<b>${obj.name}</b><br>${obj.fulladdress}`;
                let boundaryOpts = {
                    mdata: obj,
                    color: obj.boundary_hex_color,
                    fillColor: obj.boundary_hex_color,
                    radius: obj.boundary_radius,
                };
                // for geoJSON
                let style = {
                    color: obj.boundary_hex_color,
                    fillColor: obj.boundary_hex_color,
                    fillOpacity: 0.4,
                    radius: obj.boundary_radius,
                    showRadius: true,
                }

                // initDate
                State.boundary_latlngs = obj.boundary_latlngs
                State.boundary_radius = obj.boundary_radius
                State.boundary_bounds = obj.boundary_bounds

                // about shape/vector layer
                if (obj.boundary_type == State.boundary_type.circle) {
                    State.boundary_type_choose = State.boundary_type.circle;
                    circle = L.circle([obj.boundary_latlngs[0].lat, obj.boundary_latlngs[0]
                        .lng
                    ], boundaryOpts);
                    shapeGeoJSON = circle.toGeoJSON(6);
                    shapeGeoJSON.properties.radius = circle.getRadius();
                    let corner = L.latLng(obj.boundary_latlngs[0].lat, obj.boundary_latlngs[0]
                        .lng);
                    fitBounds.push(L.latLngBounds(corner, corner));
                    drawControlOpts.draw.circle = {
                        shapeOptions: {
                            ...shapeOpts
                        },
                    };
                } else if (obj.boundary_type == State.boundary_type.polygon) {
                    State.boundary_type_choose = State.boundary_type.polygon;
                    let latLngs = [];
                    for (let latLng of obj.boundary_latlngs) {
                        latLngs.push([latLng.lat, latLng.lng]);
                        let corner = L.latLng(latLng.lat, latLng.lng);
                        fitBounds.push(L.latLngBounds(corner, corner));
                    }
                    polygon = L.polygon(latLngs, boundaryOpts);
                    shapeGeoJSON = polygon.toGeoJSON(6);
                    drawControlOpts.draw.polygon = {
                        shapeOptions: {
                            ...shapeOpts
                        },
                    };
                } else if (obj.boundary_type == State.boundary_type.rectangle) {
                    State.boundary_type_choose = State.boundary_type.polygon;
                    let latLngs = [];
                    for (let latLng of obj.boundary_latlngs) {
                        latLngs.push([latLng.lat, latLng.lng]);
                        let corner = L.latLng(latLng.lat, latLng.lng);
                        fitBounds.push(L.latLngBounds(corner, corner));
                    }
                    polygon = L.polygon(latLngs, boundaryOpts);
                    shapeGeoJSON = polygon.toGeoJSON(6);
                    drawControlOpts.draw.rectangle = {
                        shapeOptions: {
                            ...shapeOpts
                        },
                    };
                } else {
                    Helper.toast('Error', 'just now', 'unknown boundary type');
                    return false;
                }

                // about L.Draw control/toolbar layer
                let drawControl = Leaflet.createDrawControl(drawControlOpts);
                Leaflet.createDrawToolbar(drawnItems, drawControl);

                // about convert shape/vector geoJSON to leaflet geoJSON format
                let layers = [];
                let geoJsonGroup = L.geoJSON(shapeGeoJSON, {
                    style: style,
                    pointToLayer: (feature, latlng) => {
                        if (feature.properties.radius) {
                            return new L.Circle(latlng, feature.properties.radius);
                        } else {
                            return new L.Marker(latlng);
                        }
                    },
                    onEachFeature: (feature, layer) => {
                        layers.push(layer);
                    },
                });

                // add shape/vector layer to L.Draw control/toolbar layer
                // Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
                function addNonGroupLayers(sourceLayer, targetGroup) {
                    if (sourceLayer instanceof L.LayerGroup) {
                        sourceLayer.eachLayer(function(layer) {
                            addNonGroupLayers(layer, targetGroup);
                        });
                    } else {
                        targetGroup.addLayer(sourceLayer);
                    }
                }
                addNonGroupLayers(geoJsonGroup, drawnItems);

                // set center
                Leaflet.map.fitBounds(fitBounds);
            },
            clearLayer: function(type = 'all', cb = null) {
                if (type == 'all') {
                    if (State.eventRemoveToolbarDraw) window.dispatchEvent(State.eventRemoveToolbarDraw);
                    if (cb) cb();
                } else if (type == 'eventRemoveToolbarDraw') {
                    if (State.eventRemoveToolbarDraw) {
                        window.dispatchEvent(State.eventRemoveToolbarDraw);
                        if (cb) cb();
                    }
                }
            }
        };

        const ZNew = {
            activate: function() {
                ZNew.event();
            },
            event: function() {
                $('#btnSubmitNewZone').on('click', function() {
                    let data = ZNew.getData();
                    let oneKmInMeters = 2000; // 1000 meters
                    let squareKminSquareMeter = 2000000; // 100 hectare || 1000000 square meter | 1 square kilometer
                    // if (data.boundary_type == State.boundary_type.circle) {
                    //     if (data.boundary_diameter > oneKmInMeters) {
                    //         Helper.toast('Warning', 'just now', 'Maksimal diameter 1 Km');
                    //         return false;
                    //     }
                    // } else if (data.boundary_type == State.boundary_type.rectangle) {
                    //     if (data.boundary_area > squareKminSquareMeter) {
                    //         Helper.toast('Warning', 'just now', 'Maksimal area 1 Km');
                    //         return false;
                    //     }
                    // } else if (data.boundary_type == State.boundary_type.polygon) {
                    //     if (data.boundary_area > squareKminSquareMeter) {
                    //         Helper.toast('Warning', 'just now', 'Maksimal area 1 Km');
                    //         return false;
                    //     }
                    // }
                    ZNew.submitData(data);
                });

                $('#add-boundary_type').on('change', function(e) {
                    Leaflet.clearLayer('eventRemoveToolbarDraw');

                    let type = $('#add-boundary_type').val();
                    let options = {},
                        shapeOptions = {};
                    let drawnItems = Leaflet.createDrawLayer();

                    shapeOptions.color = $('#add-boundary_hex').val();
                    shapeOptions.fillOpacity = 0.4;
                    shapeOptions.showRadius = true;

                    if (type == State.boundary_type.circle) {
                        options = {
                            edit: {
                                featureGroup: drawnItems,
                            },
                            draw: {
                                circle: {
                                    shapeOptions: {
                                        ...shapeOptions
                                    },
                                },
                                marker: false,
                                polygon: false,
                                rectangle: false,
                                circlemarker: false,
                                polyline: false,
                            },
                        };
                        ZNew.toggleInputCircle(true, false);
                    } else if (type == State.boundary_type.polygon) {
                        options = {
                            edit: {
                                featureGroup: drawnItems,
                            },
                            draw: {
                                polygon: {
                                    shapeOptions: {
                                        ...shapeOptions
                                    },
                                },
                                marker: false,
                                circle: false,
                                rectangle: false,
                                circlemarker: false,
                                polyline: false,
                            },
                        };
                    } else if (type == State.boundary_type.rectangle) {
                        options = {
                            edit: {
                                featureGroup: drawnItems,
                            },
                            draw: {
                                rectangle: {
                                    shapeOptions: {
                                        ...shapeOptions
                                    },
                                },
                                marker: false,
                                polygon: false,
                                circle: false,
                                circlemarker: false,
                                polyline: false,
                            },
                        };
                    } else {
                        Helper.toast('Warning', 'just now', 'please choose boundary type');
                        return false;
                    }

                    let drawControl = Leaflet.createDrawControl(options);
                    Leaflet.createDrawToolbar(drawnItems, drawControl);
                });

                let addrChangeTimeout = null;
                $('#add-fulladdress').on('keyup', async function(e) {
                    clearTimeout(addrChangeTimeout);
                    // do ajax and set center
                    addrChangeTimeout = setTimeout(() => {
                        let data = {
                            address: $('#add-fulladdress').val(),
                            country_code: 'id',
                        }
                        Req.geo_addr(data, false, function(resp) {
                            if (resp.meta.type == 'success' && resp.data) {
                                if (resp.data.lat && resp.data.lng) {
                                    Leaflet.map.setView([resp.data.lat, resp.data.lng], 16);
                                }
                            }
                        });
                    }, State.delay_typing);
                });
                $('#add-boundary_color').on('input', function(e) {
                    $('#add-boundary_hex').val(this.value);
                });
                $('#add-boundary_hex').on('input', function(e) {
                    $('#add-boundary_color').val(this.value);
                });

                function createPOI() {
                    let rad = $('#add-boundary_radius').val();
                    let lat = $('#add-boundary_lat').val();
                    let lng = $('#add-boundary_lng').val();
                    if (rad.length < 1 || lat.length < 1 || lng.length < 1) return false;
                    Leaflet.clearLayer('eventRemoveToolbarDraw');
                    const obj = {
                        boundary_hex_color: $('#add-boundary_hex').val(),
                        name: '',
                        fulladdress: '',
                        boundary_radius: Number(rad),
                        boundary_latlngs: [{
                            lat: lat,
                            lng: lng,
                        }, ],
                        boundary_bounds: '',
                        boundary_type: State.boundary_type.circle,
                        createDrawToolbar: State.createDrawToolbar,
                    };
                    Leaflet.injectShapeToLDraw(obj);
                    ZNew.toggleInputCircle(true, rad, {
                        lat,
                        lng
                    });
                }
                let radTimeout = null;
                $('#add-boundary_radius').on('keyup', function() {
                    radTimeout = setTimeout(() => {
                        createPOI();
                    }, State.delay_typing);
                });
                let latTimeout = null;
                $('#add-boundary_lat').on('keyup', function() {
                    latTimeout = setTimeout(() => {
                        createPOI();
                    }, State.delay_typing);
                });
                let lngTimeout = null;
                $('#add-boundary_lng').on('keyup', function() {
                    lngTimeout = setTimeout(() => {
                        createPOI();
                    }, State.delay_typing);
                });

                $('#add-prid').on('change', async function(e) {
                    let list_city = await Req.list_city({
                        kodeProv: $('#add-prid').val(),
                    }, true);
                    if (list_city.type == 'success') {
                        $('#add-ktid').html('<option value="">Select City</option>');
                        $('#add-kcid').html('<option value="">Select District</option>');
                        $('#add-klid').html('<option value="">Select Village</option>');
                        for (let city of list_city.resp.data) {
                            $('#add-ktid').append('<option value="' + city.kodeKab + '">' + city.nmKotamadyaKel + '</option>');
                        }
                    }
                });
                $('#add-ktid').on('change', async function(e) {
                    let list_district = await Req.list_district({
                        kodeKab: $('#add-ktid').val(),
                    }, true);
                    if (list_district.type == 'success') {
                        $('#add-kcid').html('<option value="">Select District</option>');
                        for (let district of list_district.resp.data) {
                            $('#add-kcid').append('<option value="' + district.kodeKec + '">' + district.nmKecamatanKel + '</option>');
                        }
                    }
                });
                $('#add-kcid').on('change', async function(e) {
                    let list_village = await Req.list_village({
                        kodeKec: $('#add-kcid').val(),
                    }, true);
                    if (list_village.type == 'success') {
                        $('#add-klid').html('<option value="">Select Village</option>');
                        for (let village of list_village.resp.data) {
                            $('#add-klid').append('<option value="' + village.kodeKel + '">' + village.nmKelurahan + '</option>');
                        }
                    }
                });
            },
            getData: function() {
                let data = {};
                data.zone_name = $('#add-zone_name').val();
                data.zone_client = $('#add-zone_client').val();
                data.zone_type = $('#add-zone_type').val();
                data.workflow_zone_type = $('#add-workflow_zone_type').val();
                data.shiptocode = $('#add-shiptocode').val();
                data.prid = $('#add-prid').val();
                data.ktid = $('#add-ktid').val();
                data.kcid = $('#add-kcid').val();
                data.klid = $('#add-klid').val();
                data.fulladdress = $('#add-fulladdress').val();
                data.boundary_hex_color = $('#add-boundary_hex').val();
                data.boundary_type = $('#add-boundary_type').val();

                if (State.boundary_latlngs) {
                    data.boundary_latlngs = [...State.boundary_latlngs];
                } else {
                    data.boundary_latlngs = null;
                }
                data.boundary_bounds = State.boundary_bounds;
                data.boundary_radius = State.boundary_radius;

                // https://gist.github.com/takvol/f4288261fba112030fb0fbfe11724f04
                if (data.boundary_type == State.boundary_type.circle) {
                    data.boundary_diameter = data.boundary_radius * 2;
                    data.boundary_area = 0;
                    data.boundary_ha = 0;
                } else if (data.boundary_type == State.boundary_type.rectangle) {
                    data.boundary_radius = 0;
                    data.boundary_diameter = 0;
                    data.boundary_area = L.GeometryUtil.geodesicArea(data.boundary_latlngs); // in square meter
                    data.boundary_ha = L.GeometryUtil.readableArea(data.boundary_area, true).replace(' ha', ''); // in ha
                } else if (data.boundary_type == State.boundary_type.polygon) {
                    data.boundary_radius = 0;
                    data.boundary_diameter = 0;
                    data.boundary_area = L.GeometryUtil.geodesicArea(data.boundary_latlngs); // in square meter
                    data.boundary_ha = L.GeometryUtil.readableArea(data.boundary_area, true).replace(' ha', ''); // in ha
                } else {
                    data.boundary_radius = 0;
                    data.boundary_diameter = 0;
                    data.boundary_area = 0;
                    data.boundary_ha = 0;
                }

                if ($('#add-status').prop('checked')) {
                    data.status = State.zone_status.active;
                } else {
                    data.status = State.zone_status.inactive;
                }
                return data;
            },
            submitData: async function(data) {
                return new Promise((resolve, reject) => {
                    if (typeof $('#btnSubmitNewZone').attr('disabed') != 'undefined') {
                        resolve({
                            type: 'fail'
                        });
                        return false;
                    }
                    $('#btnSubmitNewZone').attr('disabed', true);
                    $.ajax({
                        url: "{{ route('api_add_zone') }}",
                        method: 'POST',
                        crossDomain: true,
                        processData: true,
                        headers: {
                            'x-api-key': Helper.getCookie('_trtk'),
                            'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
                        },
                        data: data,
                        success: (data, textStatus, jqXHR) => {
                            $('#btnSubmitNewZone').removeAttr('disabed');
                            if (data.meta.type != 'success') {
                                resolve({
                                    type: 'fail'
                                });
                                Helper.toast('Warning', 'just now', data.meta.message);
                                return false;
                            }
                            Helper.toast('Success', 'just now', 'success add new zone');
                            window.location.href = "{{ route('view_zone') }}"
                            resolve({
                                type: 'success'
                            });
                        },
                        error: (jqXHR, textStatus, error) => {
                            $('#btnSubmitNewZone').removeAttr('disabed');
                            if (jqXHR.status >= 500) {
                                Helper.toast('Error', 'just now', 'please try again');
                            } else {
                                Helper.toast('Error', 'just now', jqXHR.responseJSON.meta
                                    .message);
                            }
                            resolve({
                                type: 'error'
                            });
                        }
                    })
                })
            },
            handleBoundaryDraw: function(e) {
                if (e.type == L.Draw.Event.CREATED) {

                } else if (e.type == L.Draw.Event.EDITED) {
                    e.layerType = State.boundary_type_choose;
                    e.layer = e.layers._layers[Object.keys(e.layers._layers)[0]];
                } else if (e.type == L.Draw.Event.DELETED) {
                    State.boundary_type_choose = null;
                    State.boundary_latlngs = null;
                    State.boundary_radius = null;
                    State.boundary_bounds = null;
                    return true;
                }

                if (e.layerType == State.boundary_type.circle) {
                    State.boundary_type_choose = State.boundary_type.circle;
                    State.boundary_latlngs = [{
                        lat: e.layer._latlng.lat,
                        lng: e.layer._latlng.lng,
                    }];
                    State.boundary_radius = e.layer._mRadius;
                    ZNew.toggleInputCircle(true, State.boundary_radius, {
                        lat: e.layer._latlng.lat,
                        lng: e.layer._latlng.lng
                    });
                } else if (e.layerType == State.boundary_type.polygon) {
                    State.boundary_type_choose = State.boundary_type.polygon;
                    State.boundary_latlngs = [];
                    for (let i in e.layer._latlngs[0]) {
                        State.boundary_latlngs.push({
                            lat: e.layer._latlngs[0][i].lat,
                            lng: e.layer._latlngs[0][i].lng,
                        })
                    }
                    State.boundary_bounds = {
                        northEast: {
                            lat: e.layer._bounds._northEast.lat,
                            lng: e.layer._bounds._northEast.lng,
                        },
                        southWest: {
                            lat: e.layer._bounds._southWest.lat,
                            lng: e.layer._bounds._southWest.lng,
                        },
                    };
                } else if (e.layerType == State.boundary_type.rectangle) {
                    State.boundary_type_choose = State.boundary_type.rectangle;
                    State.boundary_latlngs = [];
                    for (let i in e.layer._latlngs[0]) {
                        State.boundary_latlngs.push({
                            lat: e.layer._latlngs[0][i].lat,
                            lng: e.layer._latlngs[0][i].lng,
                        })
                    }
                    State.boundary_bounds = {
                        northEast: {
                            lat: e.layer._bounds._northEast.lat,
                            lng: e.layer._bounds._northEast.lng,
                        },
                        southWest: {
                            lat: e.layer._bounds._southWest.lat,
                            lng: e.layer._bounds._southWest.lng,
                        },
                    };
                }
            },
            toggleInputCircle: function(isShow = null, rad = null, opt = {}) {
                if (isShow) {
                    $('.add-group_boundary_circle').removeClass('d-none');
                } else {
                    $('.add-group_boundary_circle').addClass('d-none');
                }

                if (rad) {
                    $('#add-boundary_radius').val(rad);
                } else {
                    $('#add-boundary_radius').val('');
                }

                if (opt.lat) {
                    $('#add-boundary_lat').val(opt.lat);
                } else {
                    $('#add-boundary_lat').val('');
                }

                if (opt.lng) {
                    $('#add-boundary_lng').val(opt.lng);
                } else {
                    $('#add-boundary_lng').val('');
                }
            },
        }

        Wrapper.activate();
    </script>
@endsection
