package com.tomas.pcs_asi.lib;

import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.widget.Toast;

import androidx.documentfile.provider.DocumentFile;

import com.tomas.pcs_asi.ListData.User_Lists;
import com.tomas.pcs_asi.R;
import com.tomas.pcs_asi.lib.common.AsyncFtpClient;
import com.tomas.pcs_asi.lib.common.AsyncHttpClient;
import com.tomas.pcs_asi.lib.common.FileUtil;
import com.tomas.pcs_asi.lib.common.Utils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Settings {

    private static Context context;

    private static final String SETTING_PATH = "skt";
    private static final String LOG_PATH = "log";

    private static final String MANAGEMENT_INFO = "MngInfo.csv";
    private static final String SETTING_INFO = "Settings.csv";
    private static final String USER_INFO = "UserInfo.csv";

    private static Map<String, String> mgmtList = new HashMap<String, String>();
    private static Map<String, String> settingList = new HashMap<String, String>();
    private static Map<String, String> usrList = new HashMap<String, String>();
    private static Map<String, User_Lists>map_user = new HashMap<String, User_Lists>();

    private static User loginUser;
    private static String PROCESS;
    private static String STATUS;
    private static String ICS;
    private static String JOB_ORDER;
    private static String LOT_NO;
    private static String OVERDUE_DT;
    private static String OVERDUE_TITLE;
    private static String MC_TYPE;
    private static String ITEM_TYPE;
    private static String SCH_ID;
    private static String USER_ID;
    private static String MACHINE;
    private static String QTY_INPUT;
    private static String OVEN_ID;
    private static String PLASMA;
    private static String MAG_NO;
    private static String START_DT;
    private static String CHECK_TIME;
    private static String DICER_ID;
    private static String CLS_LOT;
    private static String CLS_MAX;
    private static String EQM;
    private static String EQM_EXP;



    private static Integer DB_PROCESS_TIMES;



    public static void readManagementFile(File dir) throws IOException {
        try {
            // clear list first
            mgmtList.clear();

            String raw = FileUtil.readFile(MANAGEMENT_INFO, dir.getAbsolutePath());

            String[] lines = raw.split(System.getProperty("line.separator"));
            int i = 0;
            for (String line : lines) {
                Log.d(Settings.context.getString(R.string.tag), "read line:" + line);
                String[] values = line.split(",");
                try {
                    mgmtList.put(values[0], values[1]);
                    i++;
                } catch (Exception e) {
                    Log.d(Settings.context.getString(R.string.tag), "line format error!");
                }
            }

            if (lines.length == 0 || i==0) {
                throw new IOException("file format error");
            }
        } catch (IOException ioe) {
            Log.d(Settings.context.getString(R.string.tag), "cannot read file, error:" + ioe.getMessage());
            throw ioe;
        }
    }

    public static void readManagementFile(DocumentFile path, ContentResolver contentResolver) {

        // read manager file
        Log.d(Settings.context.getString(R.string.tag), "open file:" + MANAGEMENT_INFO);
        DocumentFile mgmtFile = path.findFile(MANAGEMENT_INFO);
        if (mgmtFile.exists() && mgmtFile.canRead()) {
            try {
                String raw = FileUtil.readTextFromUri(mgmtFile.getUri(), contentResolver);
                Log.d(Settings.context.getString(R.string.tag), "file content:" + raw);

                String[] lines = raw.split(System.getProperty("line.separator"));
                for (String line : lines) {
                    String[] values = line.split("=");
                    mgmtList.put(values[0], values[1]);
                }
            } catch (IOException ioe) {
                Log.d(Settings.context.getString(R.string.tag), "cannot read file, error:" + ioe.getMessage());
            }
        } else {
            Log.i("SKT", "file not found![" + MANAGEMENT_INFO + "]");
        }

    }

    public static void readSettingFile(File dir) {
        try {
            // clear list first
            settingList.clear();

            String raw = FileUtil.readFile(SETTING_INFO, dir.getAbsolutePath());

            String[] lines = raw.split(System.getProperty("line.separator"));
            int i = 0;
            for (String line : lines) {
                Log.d(Settings.context.getString(R.string.tag), "read line:" + line);
                String[] values = line.split(",");
                try {
                    settingList.put(values[0], values[1]);
                    i++;
                } catch (Exception e) {
                    Log.d(Settings.context.getString(R.string.tag), "line format error!");
                }
            }

            if (lines.length == 0 || i==0) {
                throw new IOException("file format error");
            }
        } catch (IOException ioe) {
            Log.d(Settings.context.getString(R.string.tag), "cannot read file, error:" + ioe.getMessage());
        }
    }

    public static void readSettingFile(DocumentFile path, ContentResolver contentResolver) {

        // read setting file
        Log.d(Settings.context.getString(R.string.tag), "open file:" + SETTING_INFO);
        DocumentFile settingInfoFile = path.findFile(SETTING_INFO);
        if (settingInfoFile.exists() && settingInfoFile.canRead()) {
            try {
                String raw = FileUtil.readTextFromUri(settingInfoFile.getUri(), contentResolver);
                Log.d(Settings.context.getString(R.string.tag), "file content:" + raw);

                String[] lines = raw.split(System.getProperty("line.separator"));
                int i = 0;
                for (String line : lines) {
                    String[] values = line.split(",");
                    settingList.put(values[0], values[1]);
                }
            } catch (IOException ioe) {
                Log.d(Settings.context.getString(R.string.tag), "cannot read file, error:" + ioe.getMessage());
            }
        } else {
            Log.i("SKT", "file not found![" + SETTING_INFO + "]");
        }
    }

    public static void readUserInfoFile(File dir) throws IOException {
        try {
            // clear list first
            usrList.clear();

            String raw = FileUtil.readFile(USER_INFO, dir.getAbsolutePath());

            String[] lines = raw.split(System.getProperty("line.separator"));
            int i = 0;
            for (String line : lines) {
                Log.d(Settings.context.getString(R.string.tag), "read line:" + line);
                String[] values = line.split(",");
                try {
                    usrList.put(values[0], values[1]);
                    i++;
                } catch (Exception e) {
                    Log.d(Settings.context.getString(R.string.tag), "line format error!");
                }
            }

            if (lines.length == 0 || i==0) {
                throw new IOException("file format error");
            }
        } catch (IOException ioe) {
            Log.d(Settings.context.getString(R.string.tag), "cannot read file, error:" + ioe.getMessage());
            throw ioe;
        }
    }

    public static void readUserInfoFile(DocumentFile path, ContentResolver contentResolver) {

        // read user info file
        Log.d(Settings.context.getString(R.string.tag), "open file:" + USER_INFO);
        DocumentFile userInfoFile = path.findFile(USER_INFO);
        if (userInfoFile.exists() && userInfoFile.canRead()) {
            try {
                String raw = FileUtil.readTextFromUri(userInfoFile.getUri(), contentResolver);
                Log.d(Settings.context.getString(R.string.tag), "file content:" + raw);

                String[] lines = raw.split(System.getProperty("line.separator"));
                for (String line : lines) {
                    String[] values = line.split(",");
                    usrList.put(values[0], values[1]);
                }
            } catch (IOException ioe) {
                Log.d(Settings.context.getString(R.string.tag), "cannot read file, error:" + ioe.getMessage());
            }
        } else {
            Log.i("SKT", "file not found![" + USER_INFO + "]");
        }
    }

    public static void updateSettingsFile(Map<String, String> settingList, String path) {
        Settings.settingList = settingList;

//        Log.d(context.getString(R.string.tag), "write settings file...");
        try {
            FileUtil.writeFile(SETTING_INFO, path, Utils.mapToCsv((HashMap) settingList));
        } catch (IOException ioe) {
            Log.d(Settings.context.getString(R.string.tag), "cannot write file, error:" + ioe.getMessage());
        }
    }

    public static void init(Context context) {
        Settings.context = context;

        readSettingFile(context.getFilesDir());

        String localDir = context.getFilesDir().getAbsolutePath();

        // load manager setting
        try {
            readManagementFile(context.getFilesDir());
        } catch (Exception ioe) {
            try {
                if (Settings.getServerMode().equalsIgnoreCase("http")) {
                    new AsyncHttpClient(
                            context
                            ,"http://" + Settings.getServer() + "/" + Settings.getPath() + "/" + Settings.getManagementInfo()
                            , ""
                    ) {
                        @Override
                        public void onFinished(String response, int resp_code) {
                            Log.d(Settings.context.getString(R.string.tag), "response: " + response);
                            Log.d(Settings.context.getString(R.string.tag), "write management info file...");
                            try {
                                FileUtil.writeFile(MANAGEMENT_INFO, context.getFilesDir().getAbsolutePath(), response);
                            } catch (IOException ioe) {
                                Log.d(Settings.context.getString(R.string.tag), "cannot write file, error:" + ioe.getMessage());
                            }
                        }
                    }
                            .execute();
                } else {
                    new AsyncFtpClient(new AsyncFtpClient.TaskListener() {
                        @Override
                        public void onFinished(String result) {
                            // Do Something after the task has finished
                            try {
                                readManagementFile(context.getFilesDir());
                            } catch (IOException e) {
                                Log.d(Settings.context.getString(R.string.tag), "read Manager file error");
                            }
                        }
                    }).execute(Settings.getServer(), Settings.getUser(), Settings.getPassword(),
                            AsyncFtpClient.ACTION.DOWNLOAD,
                            localDir + "/" + Settings.getManagementInfo(),
                            Settings.getSettingList().get("path") +
                                    "/" + Settings.getManagementInfo());

                }
            } catch (Exception e) {
                Log.d(Settings.context.getString(R.string.tag), "download file failed");
            }
        }

        // load user setting
        try {
            readUserInfoFile(context.getFilesDir());
        } catch (Exception ioe) {

            try {

                if (Settings.getServerMode().equalsIgnoreCase("http")) {
                    new AsyncHttpClient(
                            context
                            ,"http://" + Settings.getServer() + "/" + Settings.getPath() + "/" + Settings.getUserInfo()
                            , ""
                    ) {
                        @Override
                        public void onFinished(String response, int resp_code) {
                            Log.d(Settings.context.getString(R.string.tag), "response: " + response);
                            Log.d(Settings.context.getString(R.string.tag), "write user info file...");
                            try {
                                FileUtil.writeFile(USER_INFO, context.getFilesDir().getAbsolutePath(), response);
                            } catch (IOException ioe) {
                                Log.d(Settings.context.getString(R.string.tag), "cannot write file, error:" + ioe.getMessage());
                            }
                        }
                    }
                            .execute();
                } else {
                    new AsyncFtpClient(new AsyncFtpClient.TaskListener() {
                        @Override
                        public void onFinished(String result) {
                            // Do Something after the task has finished
                            try {
                                Toast.makeText(context, "Config files updated. Restart required!",
                                        Toast.LENGTH_LONG).show();
                                readUserInfoFile(context.getFilesDir());


                            } catch (IOException e) {
                                Log.d(Settings.context.getString(R.string.tag), "read User info file error");
                            }
                        }
                    }).execute(Settings.getServer(), Settings.getUser(), Settings.getPassword(),
                            AsyncFtpClient.ACTION.DOWNLOAD,
                            localDir + "/" + Settings.getUserInfo(),
                            Settings.getSettingList().get("path") +
                                    "/" + Settings.getUserInfo());
                }

            } catch (Exception e) {
                Log.d(Settings.context.getString(R.string.tag), "download file failed");
            }
        }
    }

    public static String getEQM() {
        return EQM;
    }

    public static void setEQM(String EQM) {
        Settings.EQM = EQM;
    }

    public static String getEqmExp() {
        return EQM_EXP;
    }

    public static void setEqmExp(String eqmExp) {
        EQM_EXP = eqmExp;
    }

    public static Map<String, User_Lists> getMap_user() {
        return map_user;
    }

    public static void setMap_user(Map map_user) {
        Settings.map_user = map_user;
    }


    public static String getClsLot() {
        return CLS_LOT;
    }

    public static void setClsLot(String clsLot) {
        CLS_LOT = clsLot;
    }

    public static String getItemType() {
        return ITEM_TYPE;
    }

    public static void setItemType(String itemType) {
        ITEM_TYPE = itemType;
    }

    public static String getClsMax() {
        return CLS_MAX;
    }

    public static void setClsMax(String clsMax) {
        CLS_MAX = clsMax;
    }


    public static String getDicerId() {
        return DICER_ID;
    }

    public static void setDicerId(String dicerId) {
        DICER_ID = dicerId;
    }

    public static String getCheckTime() {
        return CHECK_TIME;
    }

    public static void setCheckTime(String checkTime) {
        CHECK_TIME = checkTime;
    }

    public static String getMagNo() {
        return MAG_NO;
    }

    public static void setMagNo(String magNo) {
        MAG_NO = magNo;
    }

    public static String getStartDt() {
        return START_DT;
    }

    public static void setStartDt(String startDt) {
        START_DT = startDt;
    }

    public static String getPLASMA() {
        return PLASMA;
    }

    public static void setPLASMA(String PLASMA) {
        Settings.PLASMA = PLASMA;
    }

    public static String getOvenId() {
        return OVEN_ID;
    }

    public static void setOvenId(String ovenId) {
        OVEN_ID = ovenId;
    }

    public static String getQtyInput() {
        return QTY_INPUT;
    }

    public static void setQtyInput(String qtyInput) {
        QTY_INPUT = qtyInput;
    }

    public static String getUserId() {
        return USER_ID;
    }

    public static void setUserId(String userId) {
        USER_ID = userId;
    }

    public static String getMACHINE() {
        return MACHINE;
    }

    public static void setMACHINE(String MACHINE) {
        Settings.MACHINE = MACHINE;
    }

    public static String getSchId() {
        return SCH_ID;
    }

    public static void setSchId(String schId) {
        SCH_ID = schId;
    }

    public static String getMcType() {
        return MC_TYPE;
    }

    public static void setMcType(String mcType) {
        MC_TYPE = mcType;
    }

    public static String getOverdueDt() {
        return OVERDUE_DT;
    }

    public static void setOverdueDt(String overdueDt) {
        OVERDUE_DT = overdueDt;
    }

    public static String getOverdueTitle() {
        return OVERDUE_TITLE;
    }

    public static void setOverdueTitle(String overdueTitle) {
        OVERDUE_TITLE = overdueTitle;
    }

    public static String getSTATUS() {
        return STATUS;
    }

    public static void setSTATUS(String STATUS) {
        Settings.STATUS = STATUS;
    }

    public static String getICS() {
        return ICS;
    }

    public static void setICS(String ICS) {
        Settings.ICS = ICS;
    }

    public static String getJobOrder() {
        return JOB_ORDER;
    }

    public static void setJobOrder(String jobOrder) {
        JOB_ORDER = jobOrder;
    }

    public static String getLotNo() {
        return LOT_NO;
    }

    public static void setLotNo(String lotNo) {
        LOT_NO = lotNo;
    }

    public static Integer getDbProcessTimes() {
        return DB_PROCESS_TIMES;
    }

    public static void setDbProcessTimes(Integer dbProcessTimes) {
        DB_PROCESS_TIMES = dbProcessTimes;
    }

    public static String getPROCESS() {
        return PROCESS;
    }

    public static void setPROCESS(String PROCESS) {
        Settings.PROCESS = PROCESS;
    }

    public static Map<String, String> getMgmtList() {
        return mgmtList;
    }

    public static Map<String, String> getSettingList() {
        return settingList;
    }

    public static void setSettingList(Map<String, String> settingList) {
        Settings.settingList = settingList;
    }

    public static Map<String, String> getUsrList() {
        return usrList;
    }

    public static User getLoginUser() {
        return loginUser;
    }

    public static void setLoginUser(User loginUser) {
        Settings.loginUser = loginUser;
    }

    public static String getDeviceNo() {
        return Settings.settingList.get("device_no");
    }

    public static void setDeviceNo(String device_no) {
        Settings.settingList.put("device_no", device_no);
    }

    public static String getSettingPath() {
        return SETTING_PATH;
    }

    public static String getLogPath() {
        return LOG_PATH;
    }

    public static String getServerMode() {
        return Settings.settingList.get("server_mode");
    }

    public static void setServerMode(String server_mode) {
        Settings.settingList.put("server_mode", server_mode);
    }

    public static String getServer() {
        return Settings.settingList.get("server");
    }

    public static void setServer(String server) {
        Settings.settingList.put("server", server);
    }

    public static String getUser() {
        return Settings.settingList.get("user");
    }

    public static void setUser(String user) {
        Settings.settingList.put("user", user);
    }

    public static String getPassword() {
        return Settings.settingList.get("password");
    }

    public static void setPassword(String password) {
        Settings.settingList.put("password", password);
    }

    public static String getPath() {
        return Settings.settingList.get("path");
    }

    public static void setPath(String path) {
        Settings.settingList.put("path", path);
    }

    public static String getManagementInfo() {
        return MANAGEMENT_INFO;
    }

    public static String getSettingInfo() {
        return SETTING_INFO;
    }

    public static String getUserInfo() {
        return USER_INFO;
    }

    public static void removeAllFile(File dir) {
        String[] filename_ = {
                Settings.getUserInfo(),
                Settings.getManagementInfo(),
                Settings.getSettingInfo()};
        for (String filename : filename_) {
            File file = new File(dir, filename);
            if (file.exists()) {
                if (file.delete()) {
                    Log.i("SKT", "file removed :" + filename);
                } else {
                    Log.i("SKT", "remove failed :" + filename);
                }
            }
        }
    }

    public static void removeAllFileExceptSettings(File dir) {
        String[] filename_ = {
                Settings.getUserInfo(),
                Settings.getManagementInfo()};
        for (String filename : filename_) {
            File file = new File(dir, filename);
            if (file.exists()) {
                if (file.delete()) {
                    Log.i("SKT", "file removed :" + filename);
                } else {
                    Log.i("SKT", "remove failed :" + filename);
                }
            }
        }
    }
}
