package com.howon.lifepass;

import android.content.Intent;
import android.location.Geocoder;
import android.location.Address;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

public class WeatherActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private static final String BASE_URL = "https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtFcst";
    private static final String API_KEY = "Fs6M7dvVzeQSLddcjUN%2BK4W7xKn1xgEGRjUb%2BKzl55HYUspnqGrjIM8jWgZ%2BsYfRbtJFzC4lkY6iXAhQ%2F2%2F96Q%3D%3D";
    private Marker currentMarker;
    private Handler handler = new Handler();
    private LocationManager locationManager;
    private Location currentLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather);

        // 상태바와 내비게이션 바 숨김
        hideSystemUI();

        // 현재 위치를 얻기 위해 LocationManager 초기화
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        requestLocationUpdates();

        // 하단바 버튼 초기화
        ImageButton bottomButton1 = findViewById(R.id.bottomButton1);
        ImageButton bottomButton2 = findViewById(R.id.bottomButton2);
        ImageButton bottomButton3 = findViewById(R.id.bottomButton3);
        ImageButton bottomButton4 = findViewById(R.id.bottomButton4);

        // 버튼 클릭 이벤트 설정
        View.OnClickListener bottomButtonListener = v -> {
            int id = v.getId();
            if (id == R.id.bottomButton1) {
                Toast.makeText(WeatherActivity.this, "현재 페이지입니다.", Toast.LENGTH_SHORT).show();
            } else if (id == R.id.bottomButton2) {
                startActivity(new Intent(WeatherActivity.this, AlertActivity.class));
            } else if (id == R.id.bottomButton3) {
                startActivity(new Intent(WeatherActivity.this, NotificationActivity.class));
            } else if (id == R.id.bottomButton4) {
                startActivity(new Intent(WeatherActivity.this, DisasterActivity.class));
            }
        };

        bottomButton1.setOnClickListener(bottomButtonListener);
        bottomButton2.setOnClickListener(bottomButtonListener);
        bottomButton3.setOnClickListener(bottomButtonListener);
        bottomButton4.setOnClickListener(bottomButtonListener);

        // 지도 유형 전환 버튼 초기화
        Button toggleMapTypeButton = findViewById(R.id.toggleMapTypeButton);
        toggleMapTypeButton.setOnClickListener(v -> {
            if (mMap != null) {
                if (mMap.getMapType() == GoogleMap.MAP_TYPE_HYBRID) {
                    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                    Toast.makeText(WeatherActivity.this, "일반 지도로 전환되었습니다.", Toast.LENGTH_SHORT).show();
                } else {
                    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                    Toast.makeText(WeatherActivity.this, "하이브리드 지도로 전환되었습니다.", Toast.LENGTH_SHORT).show();
                }
            }
        });

        EditText searchEditText = findViewById(R.id.searchEditText);

        // EditText에 클릭 리스너 설정
        searchEditText.setOnClickListener(v -> {
            // 돋보기 아이콘을 클릭했을 때만 검색 실행
            String address = searchEditText.getText().toString();
            if (address.isEmpty()) {
                Toast.makeText(WeatherActivity.this, "주소를 입력해주세요.", Toast.LENGTH_SHORT).show();
            } else {
                searchLocation(address); // 주소 검색 실행
            }
        });

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        if (mapFragment != null) {
            mapFragment.getMapAsync(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // 지도 유형을 하이브리드 모드로 설정
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        // 대한민국 남한 중앙 위치 설정 및 확대 축소 가능하게 설정
        LatLng koreaSouthCenter = new LatLng(35.8, 127.5);
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(koreaSouthCenter, 7.0f));
        mMap.getUiSettings().setZoomControlsEnabled(false); // 확대 축소 버튼 비활성화

        // 호원대학교 정보통시관 위치 설정 및 자연스러운 줌아웃 애니메이션 추가
        LatLng howonUniversity = new LatLng(35.9646437, 126.8631629);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(howonUniversity, 13.0f), 3000, new GoogleMap.CancelableCallback() {
            @Override
            public void onFinish() {
                // 로딩 후 약간의 지연시간 추가
                handler.postDelayed(() -> {
                    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(35.9646437, 127.0), 9.0f), 12000, null);
                }, 1000); // 1초 지연 후 애니메이션 시작
            }

            @Override
            public void onCancel() {
                // 애니메이션이 취소되었을 때의 동작 정의 (필요하다면 구현 가능)
            }
        });

        mMap.setOnMapClickListener(this::fetchWeatherInfo);
    }

    private void searchLocation(String address) {
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        try {
            List<Address> addresses = geocoder.getFromLocationName(address, 1);
            if (addresses != null && !addresses.isEmpty()) {
                Address location = addresses.get(0);
                LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15.0f));
                fetchWeatherInfo(latLng);
            } else {
                Toast.makeText(this, "주소를 찾을 수 없습니다.", Toast.LENGTH_SHORT).show();
            }
        } catch (IOException e) {
            Log.e("WeatherActivity", "주소 검색 실패: " + e.getMessage());
            Toast.makeText(this, "주소 검색에 실패했습니다.", Toast.LENGTH_SHORT).show();
        }
    }

    private void fetchWeatherInfo(LatLng latLng) {
        // 대한민국 남한 영역 이외의 클릭을 무시하도록 설정
        if (latLng.latitude < 33.0 || latLng.latitude > 38.5 || latLng.longitude < 124.0 || latLng.longitude > 130.7) {
            Toast.makeText(WeatherActivity.this, "대한민국 남한 내의 지역을 선택해주세요.", Toast.LENGTH_SHORT).show();
            return;
        }

        if (currentMarker != null) {
            currentMarker.remove();
        }

        new Thread(() -> {
            try {
                // 현재 날짜와 시간을 가져와서 API 요청에 사용
                Calendar calendar = Calendar.getInstance();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
                String currentDate = dateFormat.format(calendar.getTime());

                // 격자 좌표 설정 (위도, 경도를 정수로 변환하여 간략히 적용)
                int nx = (int) Math.round(latLng.latitude); // 위도를 격자 X로 변환
                int ny = (int) Math.round(latLng.longitude); // 경도를 격자 Y로 변환

                // 요청 URL 구성
                String urlStr = BASE_URL + "?serviceKey=" + API_KEY + "&pageNo=1&numOfRows=1000&dataType=json&base_date=" + currentDate + "&base_time=0600&nx=" + nx + "&ny=" + ny;
                Log.d("WeatherActivity", "Request URL: " + urlStr); // 요청 URL 로그 추가

                // API 요청 수행
                HttpURLConnection connection = (HttpURLConnection) new URL(urlStr).openConnection();
                connection.setRequestMethod("GET");
                connection.setRequestProperty("Accept", "application/json");

                int responseCode = connection.getResponseCode();
                if (responseCode != HttpURLConnection.HTTP_OK) {
                    Log.e("WeatherActivity", "HTTP error code: " + responseCode);
                    throw new IOException("HTTP error code: " + responseCode);
                }

                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuilder response = new StringBuilder();
                String output;
                while ((output = br.readLine()) != null) {
                    response.append(output);
                }

                String responseData = response.toString();
                Log.d("WeatherActivity", "Response Data:\n" + responseData); // 응답 데이터 전체 로그 추가

                // JSON 데이터 파싱
                String temperature = "온도 정보 없음";
                String windSpeed = "풍속 정보 없음";
                String humidity = "습도 정보 없음";
                String rainfall = "강수량 정보 없음";

                try {
                    JSONObject jsonObject = new JSONObject(responseData);
                    JSONObject responseObj = jsonObject.getJSONObject("response");
                    JSONObject body = responseObj.getJSONObject("body");
                    JSONArray itemsArray = body.getJSONObject("items").getJSONArray("item");

                    for (int i = 0; i < itemsArray.length(); i++) {
                        JSONObject item = itemsArray.getJSONObject(i);
                        String category = item.getString("category");
                        String value = item.getString("fcstValue");
                        switch (category) {
                            case "T1H":
                                temperature = value + "°C";
                                break;
                            case "WSD":
                                windSpeed = value + "m/s";
                                break;
                            case "REH":
                                humidity = value + "%";
                                break;
                            case "RN1":
                                rainfall = value + "mm";
                                break;
                        }
                    }

                    // 파싱된 각 데이터에 대한 로그 추가
                    Log.d("WeatherActivity", "Temperature: " + temperature);
                    Log.d("WeatherActivity", "Wind Speed: " + windSpeed);
                    Log.d("WeatherActivity", "Humidity: " + humidity);
                    Log.d("WeatherActivity", "Rainfall: " + rainfall);
                } catch (JSONException e) {
                    Log.e("WeatherActivity", "JSON 파싱 오류: " + e.getMessage());
                }

                // Geocoder를 사용해 주소 가져오기
                Geocoder geocoder = new Geocoder(WeatherActivity.this, Locale.getDefault());
                String addressText = "위치 정보 없음";
                try {
                    List<Address> addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);
                    if (addresses != null && !addresses.isEmpty()) {
                        Address address = addresses.get(0);
                        addressText = "\uD83C\uDFE0 주소: " + address.getAddressLine(0);
                    }
                } catch (IOException e) {
                    Log.e("WeatherActivity", "주소를 가져오는 데 실패했습니다: " + e.getMessage());
                }

                final String weatherInfo = addressText + "\n" +
                        String.format("\uD83C\uDF21 온도: %-10s \uD83D\uDCA8 풍속: %-10s\n", temperature, windSpeed) +
                        String.format("\uD83D\uDCA7 습도: %-10s \u2614 강수량: %-10s", humidity, rainfall);

                runOnUiThread(() -> {
                    // 이전 마커 제거 및 새로운 마커 추가
                    if (currentMarker != null) {
                        currentMarker.remove();
                    }
                    currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));

                    // 사용자 정의 TextView로 날씨 정보를 표시
                    TextView weatherTextView = new TextView(WeatherActivity.this);
                    weatherTextView.setText(weatherInfo);
                    weatherTextView.setBackgroundColor(0xAAFFFAF0); // 연한 배경 색상 (아이보리 톤)
                    weatherTextView.setTextColor(getResources().getColor(android.R.color.black)); // 검정색 텍스트
                    weatherTextView.setTextSize(14); // 텍스트 크기
                    weatherTextView.setPadding(20, 20, 20, 20); // 여백을 더 줘서 더 깔끔하게
                    weatherTextView.setGravity(Gravity.LEFT | Gravity.TOP); // 텍스트 왼쪽 상단 정렬
                    weatherTextView.setAlpha(0.8f); // 투명도를 80%로 설정
                    weatherTextView.setBackgroundResource(R.drawable.weather_toast_border); // 이 부분은 xml로 테두리 디자인

                    final Toast toast = new Toast(WeatherActivity.this);
                    toast.setView(weatherTextView);
                    toast.setDuration(Toast.LENGTH_LONG); // 기본 길게 표시
                    toast.setGravity(Gravity.TOP, 0, 200);
                    toast.show();
                });
            } catch (IOException e) {
                Log.e("WeatherActivity", "날씨 데이터를 가져오는 데 실패했습니다: " + e.getMessage());
                runOnUiThread(() -> Toast.makeText(WeatherActivity.this, "날씨 데이터를 가져오는 데 실패했습니다. 다시 시도해주세요.", Toast.LENGTH_SHORT).show());
            }
        }).start();
    }

    // 현재 위치 업데이트 요청
    private void requestLocationUpdates() {
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != android.content.pm.PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 1);
        } else {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    currentLocation = location;
                }

                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) {
                }

                @Override
                public void onProviderEnabled(String provider) {
                }

                @Override
                public void onProviderDisabled(String provider) {
                }
            });
        }
    }

    // Immersive Fullscreen Mode 설정
    private void hideSystemUI() {
        getWindow().setDecorFitsSystemWindows(false);
        WindowInsetsController insetsController = getWindow().getInsetsController();
        if (insetsController != null) {
            insetsController.hide(WindowInsets.Type.navigationBars());
            insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
            getWindow().setStatusBarColor(android.graphics.Color.TRANSPARENT); // 상태바를 투명하게 설정
        }
    }

    // 사용자가 화면 상단/하단을 스와이프했을 때 UI 복원
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideSystemUI();
        }
    }
}
