package com.mogo.cloud.netty.server;

import static android.widget.Toast.LENGTH_SHORT;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.mogo.cloud.R;
import com.mogo.cloud.netty.LogBean;
import com.mogo.telematic.MogoProtocolMsg;
import com.mogo.telematic.NSDNettyManager;
import com.mogo.telematic.NetworkUtils;
import com.mogo.telematic.server.bean.ClientChanel;
import com.mogo.telematic.server.netty.NettyServerListener;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import io.netty.channel.Channel;

public class NettyServerActivity extends AppCompatActivity implements View.OnClickListener, NettyServerListener<MogoProtocolMsg> {

    private static final String TAG = "NettyServerActivity";

    private Button mClearLog;
    private Button mSendBtn;
    private Button startServer;
    private EditText mSendET;
    private RecyclerView mSendList;
    private RecyclerView mReceList;

    private LogAdapter mSendLogAdapter = new LogAdapter();
    private LogAdapter mReceLogAdapter = new LogAdapter();
    private TextView receiveTv;

    List<ClientChanel> clientChanelArray = new ArrayList<>(); //储存客户端通道信息
    private Spinner mSpinner;
    private CustomSpinnerAdapter spinnerAdapter;
    private TextView mIpView;

    private final byte[] sendByte =  new byte[]{0x55, 0x54, 0x72, 0x21};

    private final MogoProtocolMsg mogoProtocolMsg = new MogoProtocolMsg(MogoProtocolMsg.NORMAL_DATA, 3, new byte[]{0x11, 0x12, 0x13});

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

        findViews();
        initData();
        initListener();
    }

    private void initListener() {

        spinnerAdapter = new CustomSpinnerAdapter(this, clientChanelArray);

        mSpinner.setAdapter(spinnerAdapter);
        mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                ClientChanel clientChanel = spinnerAdapter.getItem(position);
                Toast.makeText(NettyServerActivity.this, "onItemSelected:" + clientChanel.getClientIp(), Toast.LENGTH_LONG).show();
                NSDNettyManager.getInstance().selectChannel(clientChanel.getChannel());
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                NSDNettyManager.getInstance().selectChannel(null);
                Toast.makeText(NettyServerActivity.this, "onNothingSelected", Toast.LENGTH_LONG).show();
            }
        });
    }

    private void initData() {
        LinearLayoutManager manager1 = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        mSendList.setLayoutManager(manager1);
        mSendList.setAdapter(mSendLogAdapter);

        LinearLayoutManager manager2 = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        mReceList.setLayoutManager(manager2);
        mReceList.setAdapter(mReceLogAdapter);
    }

    private void findViews() {
        mSendList = findViewById(R.id.send_list);
        mReceList = findViewById(R.id.rece_list);
        mSendET = findViewById(R.id.send_et);
        mSendBtn = findViewById(R.id.send_btn);
        mClearLog = findViewById(R.id.clear_log);
        startServer = findViewById(R.id.startServer);
        receiveTv = findViewById(R.id.receiveTv);
        mSpinner = findViewById(R.id.spinner);
        mIpView = findViewById(R.id.tv_ip);

        startServer.setOnClickListener(this);
        mSendBtn.setOnClickListener(this);
        mClearLog.setOnClickListener(this);
        mSendET.setText(Arrays.toString(mogoProtocolMsg.getBody()));
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        mIpView.setText(NetworkUtils.getIPAddress(this) + "(切换网络后不会刷新!)");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.startServer:
                NSDNettyManager.getInstance().startNSDNettyServer(this, this);
                break;

            case R.id.send_btn:
                if (!NSDNettyManager.getInstance().isServerStart()) {
                    Toast.makeText(getApplicationContext(), "未连接,请先连接", LENGTH_SHORT).show();
                } else {
//                    NSDNettyManager.getInstance().sendMogoProtocolMsgToClient(mogoProtocolMsg, channelFuture -> {
//                        if (channelFuture.isSuccess()) {
//                            Log.d(TAG, "Write auth successful");
//                            logSend(Arrays.toString(mogoProtocolMsg.getBody()));
//                        } else {
//                            Log.d(TAG, "Write auth error");
//                        }
//                    });
                    NSDNettyManager.getInstance().sendMsgToAllClients(mogoProtocolMsg);
                    logSend(Arrays.toString(mogoProtocolMsg.getBody()));
                    mSendET.setText(Arrays.toString(mogoProtocolMsg.getBody()));
                }
                break;

            case R.id.clear_log:
                mReceLogAdapter.getDataList().clear();
                mSendLogAdapter.getDataList().clear();
                mReceLogAdapter.notifyDataSetChanged();
                mSendLogAdapter.notifyDataSetChanged();
                break;
        }
    }

    @Override
    public void onMessageResponseServer(MogoProtocolMsg msg, Channel channel) {
        Log.e(TAG,"onMessageResponseServer:channelId:" + channel.id().asShortText());

        String result = msg.toString();
        Log.e(TAG, "onMessageResponse:" + result);
        logRece(result);
    }

    @Override
    public void onChannelConnect(final Channel channel) {

        String socketStr = channel.remoteAddress().toString();
        final ClientChanel clientChanel = new ClientChanel(socketStr, channel, channel.id().asShortText());

        synchronized (clientChanelArray) {
            clientChanelArray.add(clientChanel);
            runOnUiThread(() -> {
                Toast.makeText(NettyServerActivity.this, clientChanel.getClientIp() + " 建立连接", Toast.LENGTH_LONG).show();
                spinnerAdapter.notifyDataSetChanged();
            });
        }

    }

    @Override
    public void onChannelDisConnect(Channel channel) {
        Log.d(TAG, "onChannelDisConnect:ChannelId is:" + channel.id().asShortText());

        for (int i = 0; i < clientChanelArray.size(); i++) {
            final ClientChanel clientChanel = clientChanelArray.get(i);
            if (clientChanel.getShortId().equals(channel.id().asShortText())) {

                /**
                 * 当Spinner里第一个item被remove，不会触发onItemSelected，（因为 mSelectedPosition != mOldSelectedPosition）
                 */
                if (i == 0) {
                    try {
                        Field field = AdapterView.class.getDeclaredField("mOldSelectedPosition");
                        field.setAccessible(true);  //设置mOldSelectedPosition可访问
                        field.setInt(mSpinner, AdapterView.INVALID_POSITION); //设置mOldSelectedPosition的值
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                synchronized (clientChanelArray) {
                    clientChanelArray.remove(clientChanel);
                    runOnUiThread(() -> {
                        Log.e(TAG, "disconncect " + clientChanel.getClientIp());
                        Toast.makeText(NettyServerActivity.this, clientChanel.getClientIp() + " 断开连接", Toast.LENGTH_LONG).show();
                        spinnerAdapter.notifyDataSetChanged();
                    });
                }

                return;
            }
        }

    }

    @Override
    public void onStartServer() {
        Log.e(TAG, "onStartServer");
        runOnUiThread(() -> startServer.setText("stopServer"));
    }

    @Override
    public void onStopServer() {
        Log.e(TAG, "onStopServer");
        runOnUiThread(() -> startServer.setText("startServer"));
    }

    private void logSend(String log) {
        runOnUiThread(() -> {
            LogBean logBean = new LogBean(System.currentTimeMillis(), log);
            mSendLogAdapter.getDataList().add(0, logBean);
            mSendLogAdapter.notifyDataSetChanged();
        });
    }

    private void logRece(String log) {
        runOnUiThread(() -> {
            LogBean logBean = new LogBean(System.currentTimeMillis(), log);
            mReceLogAdapter.getDataList().add(0, logBean);
            mReceLogAdapter.notifyDataSetChanged();
        });
    }
}
