package com.quansu.gaode.activity;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.animation.Animation;
import com.amap.api.maps.model.animation.TranslateAnimation;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.githang.statusbar.StatusBarCompat;

import com.jaeger.library.StatusBarUtil;
import com.quansu.gaode.R;
import com.quansu.gaode.adapter.SearchResultAdapter;
import com.quansu.gaode.view.SegmentedGroup;
import com.ysnows.base.ccretrofit.CCRetrofit;
import com.ysnows.base.model.PositionBean;
import com.ysnows.base.route.IApp;
import com.ysnows.base.utils.Toasts;
import com.ysnows.base.utils.UiSwitch;

import java.util.ArrayList;
import java.util.List;


public class GaodeActivity extends AppCompatActivity implements LocationSource,
        AMapLocationListener, GeocodeSearch.OnGeocodeSearchListener,

        PoiSearch.OnPoiSearchListener {


    private static final int REQUEST_SEARCH_CODE = 1;


    private ListView listView;
    AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (position != searchResultAdapter.getSelectedPosition()) {

                PoiItem poiItem = (PoiItem) searchResultAdapter.getItem(position);

                chosepoiItem = poiItem;
                LatLng curLatlng = new LatLng(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude());


                isItemClickAction = true;

                aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f));

                searchResultAdapter.setSelectedPosition(position);
                searchResultAdapter.notifyDataSetChanged();
            }
        }
    };


    private SegmentedGroup mSegmentedGroup;
    private AMap aMap;
    private MapView mapView;
    private OnLocationChangedListener mListener;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;


    private Marker locationMarker;

    private ProgressDialog progDialog = null;
    private GeocodeSearch geocoderSearch;

    private int currentPage = 0;// 当前页面，从0开始计数
    private PoiSearch.Query query;// Poi查询条件类
    private PoiSearch poiSearch;
    private List<PoiItem> poiItems;// poi数据

    private String searchType = "";
    private String searchKey = "";
    private LatLonPoint searchLatlonPoint;
    private LinearLayout currentLocation;//选择当前的定位位置 ：注意 可能只有经纬度


    private List<PoiItem> resultData;

    private SearchResultAdapter searchResultAdapter;

    private boolean isItemClickAction;


    private ImageView imgLeft;
    private TextView tvRight;

    private PoiItem chosepoiItem;//选择的地点


    private String adress = null;//地址

    private String s1 = "";//第二个参数传入null或者“”代表在全国进行检索，否则按照传入的city进行检索
    private TextView tv;

    private Double lat, lng;
    private String provincename;
    private String cityname;
    private String areaname;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        StatusBarCompat.setStatusBarColor(this, Color.parseColor("#00ffffff"));
        setStatusBar();

        super.setContentView(R.layout.activity_gaode);


        Bundle bundle = getIntent().getExtras();
        if (null != bundle) {
            adress = bundle.getString("adress");
        }
        mapView = (MapView) findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);
        init();

        initView();

        resultData = new ArrayList<>();

    }

    private LinearLayout llSearch;

    private void initView() {

        llSearch = findViewById(R.id.ll_search);
        tv = findViewById(R.id.tv);

        imgLeft = findViewById(R.id.img_left);
        tvRight = findViewById(R.id.tv_right);

        currentLocation = findViewById(R.id.current_location);

        listView = (ListView) findViewById(R.id.listview);
        searchResultAdapter = new SearchResultAdapter(GaodeActivity.this);
        listView.setAdapter(searchResultAdapter);

        listView.setOnItemClickListener(onItemClickListener);

        mSegmentedGroup = (SegmentedGroup) findViewById(R.id.segmented_group);
        mSegmentedGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                searchType = items[0];

                if (checkedId == R.id.radio0) {
                    searchType = items[0];
                } else if (checkedId == R.id.radio1) {
                    searchType = items[1];
                } else if (checkedId == R.id.radio2) {
                    searchType = items[2];
                } else if (checkedId == R.id.radio3) {
                    searchType = items[3];
                }

                geoAddress();
            }
        });


        geocoderSearch = new GeocodeSearch(this);
        geocoderSearch.setOnGeocodeSearchListener(this);
        progDialog = new ProgressDialog(this);


        imgLeft.setOnClickListener(view -> {
            finish();
        });

        tvRight.setOnClickListener(view -> {

            //  LatLng curLatlng = new LatLng(chosepoiItem.getLatLonPoint().getLatitude(), chosepoiItem.getLatLonPoint().getLongitude());

            Toast.makeText(this, "选择了" + chosepoiItem.getTitle(),Toast.LENGTH_SHORT).show();

            String latitude = String.valueOf(chosepoiItem.getLatLonPoint().getLatitude());
            String longitude = String.valueOf(chosepoiItem.getLatLonPoint().getLongitude());
            String provincename = chosepoiItem.getProvinceName();
            String cityname = chosepoiItem.getCityName();
            String areaname = chosepoiItem.getAdName();

            Log.e("-shy-", "provincename=: " + provincename + "/cityname=" + cityname + "/areaname=" + areaname);


            PositionBean positionBean = new PositionBean(chosepoiItem.getTitle(), latitude, longitude, provincename, cityname, areaname);

            CCRetrofit.instance()
                    .create(IApp.class)
                     .setDatas(positionBean)
                    .subscribe();

            finish();

        });


        if (!TextUtils.isEmpty(adress)) {

            tvRight.setVisibility(View.INVISIBLE);

        }

        llSearch.setOnClickListener(v -> {
            UiSwitch.singleRes(this, SearchAddressActivity.class, REQUEST_SEARCH_CODE);
        });


        currentLocation.setOnClickListener(v -> {

            if (null != searchLatlonPoint) {

                Toast.makeText(this, "选择了当前定位位置",Toast.LENGTH_SHORT).show();

                String latitude = String.valueOf(lat);
                String longitude = String.valueOf(lng);
                String title = "经度:" + longitude + "/维度:" + latitude;

                //省市区大概的位置是不会变的
                String provincename = chosepoiItem.getProvinceName();
                String cityname = chosepoiItem.getCityName();
                String areaname = chosepoiItem.getAdName();
                Log.e("-shy-", "provincename=: " + provincename + "/cityname=" + cityname + "/areaname=" + areaname);

                PositionBean positionBean = new PositionBean(title, latitude, longitude,
                        provincename, cityname, areaname);

                CCRetrofit.instance()
                        .create(IApp.class)
                        .setDatas(positionBean)
                        .subscribe();

                finish();

            } else {

                Toast.makeText(this, "无法获得当前位置",Toast.LENGTH_LONG).show();

            }

        });


    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_SEARCH_CODE && resultCode == 6) {
            PoiItem searchPonItem = data.getParcelableExtra("poiItem");
            LatLonPoint latLonPoint = searchPonItem.getLatLonPoint();
            //移动标志和地图
            // addmark(latLonPoint.getLatitude(),latLonPoint.getLongitude());
            aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude()), 14));
            //重新搜索附近
            //数据清空
            searchKey = searchPonItem.getCityName();
            String name = data.getStringExtra("name");
            tv.setText(name);
            searchLatlonPoint = new LatLonPoint(latLonPoint.getLatitude(), latLonPoint.getLongitude());

            doSearchQuery();

        }
    }

    private String[] items = {"", "学校", "楼宇", "商场"};

    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {
        aMap.getUiSettings().setZoomControlsEnabled(false);
        MyLocationStyle myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点，定位点依照设备方向旋转，并且会跟随设备移动。（1秒1次定位）如果不设置myLocationType，默认也会执行此种模式。
        myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔，只在连续定位模式下生效，单次定位模式下不会生效。单位为毫秒。
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style


        aMap.setLocationSource(this);// 设置定位监听
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
//        aMap.setInfoWindowAdapter(this);//将自定义的 InfoWindow 样式给map

    }

    //dip和px转换
    private static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    protected void setStatusBar() {
        StatusBarUtil.setDarkMode(this);
      StatusBarUtil.setColor(this, getResources().getColor(R.color.colorPrimary), 1);
    }

    /**
     * 初始化
     */
    private void init() {
        if (aMap == null) {
            aMap = mapView.getMap();
            setUpMap();
        }

        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {

            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {

                lat = cameraPosition.target.latitude;
                lng = cameraPosition.target.longitude;


                if (!isItemClickAction) {
                    geoAddress();
                    //todo:暂时去掉动画
                    //startJumpAnimation();
                }
                searchLatlonPoint = new LatLonPoint(cameraPosition.target.latitude, cameraPosition.target.longitude);

                isItemClickAction = false;
            }
        });

        aMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
            @Override
            public void onMapLoaded() {
                addMarkerInScreenCenter(null);
            }
        });
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
        deactivate();
    }

    /**
     * 激活定位
     */
    @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;
        if (mlocationClient == null) {
            mlocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mlocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setOnceLocation(true);
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mlocationClient.startLocation();
        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }


    /**
     * 响应逆地理编码
     */
    public void geoAddress() {
//        Log.i("MY", "geoAddress"+ searchLatlonPoint.toString());
        showDialog();
        if (searchLatlonPoint != null) {
            RegeocodeQuery query = new RegeocodeQuery(searchLatlonPoint, 200, GeocodeSearch.AMAP);// 第一个参数表示一个Latlng，第二参数表示范围多少米，第三个参数表示是火系坐标系还是GPS原生坐标系
            geocoderSearch.getFromLocationAsyn(query);
        }
    }


    /**
     * 开始进行poi搜索
     */
    protected void doSearchQuery() {
//        Log.i("MY", "doSearchQuery");
        currentPage = 0;//searchKey  searchType
        query = new PoiSearch.Query(searchKey, searchType, "");// 第一个参数表示搜索字符串，第二个参数表示poi搜索类型，第三个参数表示poi搜索区域（空字符串代表全国）
        query.setCityLimit(true);
        query.setPageSize(30);
        query.setPageNum(currentPage);

        if (searchLatlonPoint != null) {
            poiSearch = new PoiSearch(this, query);
            poiSearch.setOnPoiSearchListener(this);
            poiSearch.setBound(new PoiSearch.SearchBound(searchLatlonPoint, 1000, true));//
            poiSearch.searchPOIAsyn();
        }
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        if (null != mlocationClient) {
            mlocationClient.onDestroy();
        }
    }

    /**
     * POI搜索结果回调
     *
     * @param poiResult  搜索结果
     * @param resultCode 错误码
     */
    @Override
    public void onPoiSearched(PoiResult poiResult, int resultCode) {
        if (resultCode == AMapException.CODE_AMAP_SUCCESS) {
            if (poiResult != null && poiResult.getQuery() != null) {
                if (poiResult.getQuery().equals(query)) {
                    poiItems = poiResult.getPois();
                    if (poiItems != null && poiItems.size() > 0) {
                        updateListview(poiItems);
                    } else {
                        Toast.makeText(GaodeActivity.this, "无搜索结果", Toast.LENGTH_SHORT).show();
                    }
                }
            } else {
                Toast.makeText(GaodeActivity.this, "无搜索结果", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * 更新列表中的item
     *
     * @param poiItems
     */
    private void updateListview(List<PoiItem> poiItems) {
        resultData.clear();
        searchResultAdapter.setSelectedPosition(0);
        //todo:
        chosepoiItem = poiItems.get(0);
        // resultData.add(firstItem);
        resultData.addAll(poiItems);

        searchResultAdapter.setData(resultData);
        searchResultAdapter.notifyDataSetChanged();


        if (!TextUtils.isEmpty(adress)) {
            Toast.makeText(this, adress, Toast.LENGTH_SHORT).show();

            tvRight.setVisibility(View.INVISIBLE);


            adress = null;
        }
    }

    /**
     * 定位成功后回调函数
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation != null
                    && amapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(amapLocation);

                LatLng curLatlng = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude());

                searchLatlonPoint = new LatLonPoint(curLatlng.latitude, curLatlng.longitude);


                aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f));


            } else {
                String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                Log.e("AmapErr", errText);
            }
        }
    }

    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
        dismissDialog();
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getRegeocodeAddress() != null
                    && result.getRegeocodeAddress().getFormatAddress() != null) {
                String address = result.getRegeocodeAddress().getProvince() + result.getRegeocodeAddress().getCity() + result.getRegeocodeAddress().getDistrict() + result.getRegeocodeAddress().getTownship();
//                firstItem = new PoiItem("regeo", searchLatlonPoint, address, address);
//                chosepoiItem=firstItem;

                doSearchQuery();
            }
        } else {
            Toast.makeText(GaodeActivity.this, "error code is " + rCode, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }

    private void addMarkerInScreenCenter(LatLng locationLatLng) {
        LatLng latLng = aMap.getCameraPosition().target;
        Point screenPosition = aMap.getProjection().toScreenLocation(latLng);

        View markerView = getLayoutInflater().inflate(R.layout.gaode_item_marker, null);

        locationMarker = aMap.addMarker(new MarkerOptions()
                .anchor(0.5f, 0.5f)
                .title("当前位置")
                .visible(true)
                .icon(BitmapDescriptorFactory.fromView(markerView)));

        //.icon(BitmapDescriptorFactory.fromResource(R.drawable.purple_pin)));
        //设置Marker在屏幕上,不跟随地图移动
        locationMarker.setPositionByPixels(screenPosition.x, screenPosition.y);
        locationMarker.setZIndex(1);

    }

    private void addmark(double latitude, double longitude) {

        if (locationMarker == null) {
            locationMarker = aMap.addMarker(new MarkerOptions()
                    .position(new LatLng(latitude, longitude))
                    .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                            .decodeResource(getResources(), R.mipmap.poi_marker_1)))
                    .draggable(true));
        } else {
            locationMarker.setPosition(new LatLng(latitude, longitude));
        }
    }


    /**
     * 屏幕中心marker 跳动
     */
    public void startJumpAnimation() {

        if (locationMarker != null) {
            //根据屏幕距离计算需要移动的目标点
            final LatLng latLng = locationMarker.getPosition();
            Point point = aMap.getProjection().toScreenLocation(latLng);
            point.y -= dip2px(this, 125);
            LatLng target = aMap.getProjection()
                    .fromScreenLocation(point);
            //使用TranslateAnimation,填写一个需要移动的目标点
            Animation animation = new TranslateAnimation(target);
            animation.setInterpolator(new Interpolator() {
                @Override
                public float getInterpolation(float input) {
                    // 模拟重加速度的interpolator
                    if (input <= 0.5) {
                        return (float) (0.5f - 2 * (0.5 - input) * (0.5 - input));
                    } else {
                        return (float) (0.5f - Math.sqrt((input - 0.5f) * (1.5f - input)));
                    }
                }
            });
            //整个移动所需要的时间
            animation.setDuration(600);
            //设置动画
            locationMarker.setAnimation(animation);
            //开始动画
            locationMarker.startAnimation();

        } else {
            Log.e("ama", "screenMarker is null");
        }
    }

    public void showDialog() {
        progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progDialog.setIndeterminate(false);
        progDialog.setCancelable(true);
        progDialog.setMessage("正在加载...");
        progDialog.show();
    }

    public void dismissDialog() {
        if (progDialog != null) {
            progDialog.dismiss();
        }
    }


 //   View infoWindow = null;

//    @Override
//    public View getInfoWindow(Marker marker) {
//        if (infoWindow == null) {
//            infoWindow = LayoutInflater.from(this).inflate(R.layout.map_bubble_back, null);
//        }
//        TextView tvPosition = (TextView) infoWindow.findViewById(R.id.tv_position);
//        // TextView tvStreet = (TextView) infoWindow.findViewById(R.id.tv_street);
//
//        if (null != chosepoiItem) {
//
//            String title = "我在" + chosepoiItem.getTitle() + "附近";
//            Spannable sp = new SpannableString(title);
//            sp.setSpan(new AbsoluteSizeSpan(18, true),
//                    2, title.length() - 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//
//            sp.setSpan(new ForegroundColorSpan(Color.parseColor("#000000")), 2,
//                    title.length() - 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//            tvPosition.setText(sp);
//
//            // tvStreet.setText(chosepoiItem.getDirection());
//        }
//        return infoWindow;
//    }
//
//    @Override
//    public View getInfoContents(Marker marker) {
//        return null;
//    }
}
