package com.example.myapplication;

import static android.content.ContentValues.TAG;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

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

import com.example.myapplication.DataBase.DatabaseHelper;
import com.example.myapplication.api.ProjectApi;
import com.example.myapplication.model.ApiResponse;
import com.example.myapplication.model.Project;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


public class LoginActivity extends AppCompatActivity {
    private EditText etUsername, etPassword;
    private CheckBox cbRemember;
    private Button btnClearProject;
    private Button btnLogin;
    private DatabaseHelper dbHelper;
    private SharedPreferences sharedPreferences;
    private static final String PREFS_NAME = "LoginPrefs";
    private static final String PREF_USERNAME = "username";
    private static final String PREF_PASSWORD = "password";
    private static final String PREF_REMEMBER = "remember";
    private static final String PREF_PROJECT = "project"; // 新增项目键名
    private AutoCompleteTextView actvProject;
    private ArrayAdapter<Project> projectAdapter;
    private TextView tvSelectedProjectName;
    private TextView tvSelectedProjectId;
    private List<Project> projectList = new ArrayList<>();

    @SuppressLint("SuspiciousIndentation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        dbHelper = new DatabaseHelper(this);
        // 使用 Context.MODE_PRIVATE 替代 MODE_PRIVATE 常量
        sharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);

        initViews();
        setupListeners();
        loadSavedPreferences();
        loadProjects();
    }

    private void initViews() {
        etUsername = findViewById(R.id.etUsername);
        etPassword = findViewById(R.id.etPassword);
        actvProject = findViewById(R.id.etProject);
        cbRemember = findViewById(R.id.cbRemember);
        btnLogin = findViewById(R.id.btnLogin);
        btnClearProject = findViewById(R.id.btnClearProject);
        tvSelectedProjectName = findViewById(R.id.tvSelectedProjectName);
        tvSelectedProjectId = findViewById(R.id.tvSelectedProjectId);

        // 初始化项目下拉框
        initProjectDropdown();
    }

    private void setupListeners() {
        // 清空项目按钮点击事件
        btnClearProject.setOnClickListener(v -> {
            actvProject.setText("");
            tvSelectedProjectName.setText("项目名称：未选择");
            tvSelectedProjectId.setText("项目ID：未选择");
            loadProjects();
            projectAdapter.getFilter().filter("");
            actvProject.showDropDown();
        });

        btnLogin.setOnClickListener(v -> attemptLogin());
    }

    private void loadSavedPreferences() {
        boolean remember = sharedPreferences.getBoolean(PREF_REMEMBER, false);
        if (remember) {
            String savedUsername = sharedPreferences.getString(PREF_USERNAME, "");
            String savedPassword = sharedPreferences.getString(PREF_PASSWORD, "");
            String savedProject = sharedPreferences.getString(PREF_PROJECT, "");

            etUsername.setText(savedUsername);
            etPassword.setText(savedPassword);
            actvProject.setText(savedProject);

            if (!savedProject.isEmpty()) {
                try {
                    int lastBracketIndex = savedProject.lastIndexOf("(");
                    int closingBracketIndex = savedProject.lastIndexOf(")");

                    if (lastBracketIndex != -1 && closingBracketIndex != -1 && closingBracketIndex > lastBracketIndex) {
                        String projectName = savedProject.substring(0, lastBracketIndex).trim();
                        String projectId = savedProject.substring(lastBracketIndex + 1, closingBracketIndex).trim();

                        tvSelectedProjectName.setText("项目名称:" + projectName);
                        tvSelectedProjectId.setText("项目ID:" + projectId);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    tvSelectedProjectName.setText("解析错误");
                    tvSelectedProjectId.setText("");
                }
            }
            cbRemember.setChecked(true);
        }
    }

    private void attemptLogin() {
        String username = etUsername.getText().toString().trim();
        String password = etPassword.getText().toString().trim();
        String projectInput = actvProject.getText().toString().trim();

        if (username.isEmpty() || password.isEmpty() || projectInput.isEmpty()) {
            Toast.makeText(LoginActivity.this, "请填写所有字段", Toast.LENGTH_SHORT).show();
            return;
        }

        // 在后台线程执行数据库操作
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {
            try {
                // 解析项目ID和名称

                Pair<String, String> projectInfo = parseProjectInfo(projectInput);
                String projectId = projectInfo.first;
                String projectName = projectInfo.second;

                // 保存登录信息
                saveLoginPreferences(username, password, projectName, projectId);

                // 检查用户是否存在
                boolean userExists = dbHelper.userExists(username);

                runOnUiThread(() -> {
                    if (userExists) {
                        // 用户存在，验证密码
                        if (dbHelper.checkUser(username, password)) {
                            handleLoginSuccess(username, projectId, projectName);
                        } else {
                            Toast.makeText(LoginActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        // 用户不存在，自动注册
                        if (dbHelper.addUser(username, password, projectId, projectName)) {
                            handleLoginSuccess(username, projectId, projectName);
                        } else {
                            Toast.makeText(LoginActivity.this, "注册失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            } catch (Exception e) {
                runOnUiThread(() ->
                        Toast.makeText(LoginActivity.this, "登录出错: " + e.getMessage(), Toast.LENGTH_SHORT).show());
            }
        });
    }

    private Pair<String, String> parseProjectInfo(String projectInput) {
        String projectId = "";
        String projectName = "";

        Matcher matcher = Pattern.compile(".*\\((.*)\\)").matcher(projectInput);
        if (matcher.find()) {
            projectId = matcher.group(1).trim();
            projectName = projectInput.replace("(" + projectId + ")", "").trim();
        } else {
            for (Project project : projectList) {
                if (project.getProjectName().equals(projectInput) ||
                        project.getProjectId().equals(projectInput)) {
                    projectId = project.getProjectId();
                    projectName = project.getProjectName();
                    break;
                }
            }

            if (projectId.isEmpty()) {
                projectName = projectInput;
            }
        }
        return new Pair<>(projectId, projectName);
    }

    private void saveLoginPreferences(String username, String password, String projectName, String projectId) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (cbRemember.isChecked()) {
            editor.putString(PREF_USERNAME, username);
            editor.putString(PREF_PASSWORD, password);
            String projectDisplayText = projectId.isEmpty() ? projectName :
                    (projectName + " (" + projectId + ")");
            editor.putString(PREF_PROJECT, projectDisplayText);
            editor.putBoolean(PREF_REMEMBER, true);
        } else {
            editor.clear();
        }
        editor.apply();
    }

    private void handleLoginSuccess(String username, String projectId, String projectName) {
        dbHelper.updateUserProject(username, projectId, projectName);
        Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
        intent.putExtra("username", username);
        intent.putExtra("projectId", projectId);
        intent.putExtra("projectName", projectName);
        startActivity(intent);
        finish();
    }

    private void initProjectDropdown() {
        projectAdapter = new ArrayAdapter<Project>(this,
                R.layout.custom_dropdown_item,
                projectList) {
            @NonNull
            @Override
            public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                TextView textView = view.findViewById(android.R.id.text1);
                Project project = getItem(position);
                if (project != null) {
                    textView.setText(project.getProjectName() + " (" + project.getProjectId() + ")");
                    textView.setSingleLine(false);
                    textView.setMaxLines(3);
                    textView.setEllipsize(null);
                }
                return view;
            }

            @Override
            public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                return getView(position, convertView, parent);
            }

            @Override
            public Filter getFilter() {
                return new Filter() {
                    @Override
                    protected FilterResults performFiltering(CharSequence constraint) {
                        FilterResults results = new FilterResults();
                        List<Project> filteredList = new ArrayList<>();

                        if (constraint != null && constraint.length() > 0) {
                            String filterPattern = constraint.toString().toLowerCase().trim();
                            DatabaseHelper dbHelper = new DatabaseHelper(LoginActivity.this);
                            filteredList = dbHelper.searchProjects(filterPattern);
                        } else {
                            filteredList.addAll(projectList);
                        }

                        results.values = filteredList;
                        results.count = filteredList.size();
                        return results;
                    }

                    @Override
                    protected void publishResults(CharSequence constraint, FilterResults results) {
                        clear();
                        if (results.values != null) {
                            addAll((List<Project>) results.values);
                        }
                        notifyDataSetChanged();
                    }
                };
            }
        };

        actvProject.setAdapter(projectAdapter);
        actvProject.setThreshold(0);
        actvProject.setDropDownBackgroundResource(android.R.color.white);

        actvProject.setOnItemClickListener((parent, view, position, id) -> {
            Object item = parent.getItemAtPosition(position);
            if (item instanceof Project) {
                Project selectedProject = (Project) item;
                tvSelectedProjectName.setText("项目名称：" + selectedProject.getProjectName());
                tvSelectedProjectId.setText("项目ID：" + selectedProject.getProjectId());
                actvProject.setText(selectedProject.getProjectName() + " (" + selectedProject.getProjectId() + ")");
            } else {
                Log.e("TYPE_ERROR", "Expected Project but got: " + item.getClass());
                Toast.makeText(this, "数据格式错误", Toast.LENGTH_SHORT).show();
            }
        });
    }


    private void loadProjects() {
        String BASE_URL = "http://pms.dtyx.net:9158/";

        try {
            // 1. 验证接口定义
            if (!validateApiDefinition()) {
                return;
            }

            // 2. 初始化Retrofit
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(new OkHttpClient.Builder()
                            .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
                            .connectTimeout(30, TimeUnit.SECONDS)
                            .build())
                    .build();

            // 3. 创建API服务
            ProjectApi projectApi = retrofit.create(ProjectApi.class);

            // 4. 执行网络请求
            executeProjectRequest(projectApi);

        } catch (Exception e) {
            showErrorOnUI("初始化失败", getErrorMessage(e));
            logErrorToFile(e);
        }
    }

    private boolean validateApiDefinition() {
        try {
            Method method = ProjectApi.class.getMethod("getProjectList");
            Type returnType = method.getGenericReturnType();

            // 预期的完整类型签名
            String expectedType = "retrofit2.Call<com.example.myapplication.model.ApiResponse<java.util.List<com.example.myapplication.model.Project>>>";

            if (!returnType.toString().equals(expectedType)) {
                String errorMsg = "接口定义错误！\n\n当前定义:\n" + returnType +
                        "\n\n应修改为:\n@GET(\"project/list\")\nCall<ApiResponse<List<Project>>> getProjectList();";

                new Handler(Looper.getMainLooper()).post(() -> {
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("API接口定义不合法")
                            .setMessage(errorMsg)
                            .setPositiveButton("复制定义", (d, w) -> copyToClipboard(errorMsg))
                            .setNegativeButton("关闭", null)
                            .show();
                });
                return false;
            }
            return true;
        } catch (Exception e) {
            showErrorOnUI("接口验证失败", e.getMessage());
            return false;
        }
    }

    private void executeProjectRequest(ProjectApi projectApi) {
        Call<ApiResponse<List<Project>>> call = projectApi.getProjectList();

        call.enqueue(new Callback<ApiResponse<List<Project>>>() {
            @Override
            public void onResponse(Call<ApiResponse<List<Project>>> call, Response<ApiResponse<List<Project>>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    handleSuccessResponse(response.body().getData());
                } else {
                    handleApiError(response);
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<List<Project>>> call, Throwable t) {
                handleNetworkError(t);
            }
        });
    }

    // === 错误处理方法 ===
    private void handleSuccessResponse(List<Project> projects) {
        runOnUiThread(() -> {
            try {
                dbHelper.saveProjects(projects);
                projectList.clear();
                projectList.addAll(projects);
                projectAdapter.notifyDataSetChanged();
            } catch (Exception e) {
                showErrorOnUI("数据处理错误", e.getMessage());
            }
        });
    }

    private void handleApiError(Response<?> response) {
        String errorMsg = "服务器响应错误: " + response.code();
        try {
            if (response.errorBody() != null) {
                errorMsg += "\n" + response.errorBody().string();
            }
        } catch (IOException e) {
            errorMsg += "\n无法读取错误详情";
        }

        showErrorOnUI("API请求失败", errorMsg);
        loadCachedProjects();
    }

    private void handleNetworkError(Throwable t) {
        String errorMsg = "网络错误: " + t.getMessage();
        if (t instanceof SocketTimeoutException) {
            errorMsg = "连接超时，请检查网络";
        } else if (t instanceof UnknownHostException) {
            errorMsg = "无法解析主机，请检查URL";
        }

        showErrorOnUI("网络连接失败", errorMsg);
        loadCachedProjects();
    }

    // === 工具方法 ===
    private void showErrorOnUI(String title, String message) {
        runOnUiThread(() -> {
            // 在界面底部显示错误面板
            ViewGroup rootView = findViewById(android.R.id.content);
            LinearLayout errorPanel = new LinearLayout(this);
            errorPanel.setOrientation(LinearLayout.VERTICAL);
            errorPanel.setBackgroundColor(0x33FF0000);
            errorPanel.setPadding(32, 16, 32, 16);

            TextView tvError = new TextView(this);
            tvError.setTextColor(Color.RED);
            tvError.setText(title);

            TextView tvMsg = new TextView(this);
            tvMsg.setText(message);

            errorPanel.addView(tvError);
            errorPanel.addView(tvMsg);
            rootView.addView(errorPanel);

            // 5秒后自动消失
            new Handler().postDelayed(() -> rootView.removeView(errorPanel), 5000);
        });
    }

    private void copyToClipboard(String text) {
        ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
        clipboard.setPrimaryClip(ClipData.newPlainText("错误定义", text));
        Toast.makeText(this, "定义已复制", Toast.LENGTH_SHORT).show();
    }

    private String getErrorMessage(Exception e) {
        if (e instanceof IllegalArgumentException) {
            return "参数错误: " + e.getMessage();
        } else if (e instanceof NullPointerException) {
            return "空指针异常: " + e.getMessage();
        } else {
            return "未知错误: " + e.getClass().getSimpleName();
        }
    }

    private void logErrorToFile(Exception e) {
        String log = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) +
                "\nError: " + e.getClass().getName() +
                "\nMessage: " + e.getMessage() +
                "\nStack Trace:\n" + Log.getStackTraceString(e);

        try {
            File file = new File(getExternalFilesDir(null), "error_log.txt");
            FileWriter writer = new FileWriter(file, true);
            writer.append(log).append("\n\n");
            writer.close();
        } catch (IOException ioException) {
            Log.e("FileLog", "无法写入错误日志", ioException);
        }
    }

    private void loadCachedProjects() {
        new Thread(() -> {
            List<Project> cachedProjects = dbHelper.getAllProjects();
            runOnUiThread(() -> {
                projectList.clear();
                projectList.addAll(cachedProjects);
                projectAdapter.notifyDataSetChanged();
                Toast.makeText(this, "已加载本地缓存数据", Toast.LENGTH_LONG).show();
            });
        }).start();
    }

}