package kz.arta.synergy.workflow.mobile.android.common.offline.get;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

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

import kz.arta.synergy.workflow.mobile.android.works.models.WorkItem;
import kz.arta.synergy.workflow.mobile.android.works.models.WorkUser;

/**
 * Класс для работы с базой данных
 */
public class WorksTable extends SQLiteOpenHelper {

    private SQLiteDatabase db = getWritableDatabase();
    private static final String TABLE_NAME = "Synergy";
    private static final String TABLE = "create table " + TABLE_NAME + " ("
            + "actionID text,"
            + "filterType text,"
            + "filterID text,"
            + "objectID text,"
            + "name text,"
            + "start_date text,"
            + "finish_date text,"
            + "stateID text,"
            + "userID text,"
            + "userName text,"
            + "authorID text,"
            + "authorName text,"
            + "percent text,"
            + "has_attachments text,"
            + "remained text,"
            + "remained_label text,"
            + "is_expired text,"
            + "is_soon_expired text,"
            + "priority text,"
            + "can_edit text,"
            + "can_change_state text,"
            + "can_delete text,"
            + "can_send_acquaintance text,"
            + "can_send_agreement text,"
            + "can_send_approval text,"
            + "can_be_resended text,"
            + "can_reassign text,"
            + "can_send_by_route text,"
            + "can_change_progress text,"
            + "can_manage_comments text,"
            + "can_take_on_control text,"
            + "is_new text,"
            + "has_subprocesses text,"
            + "can_mark_as_seen text,"
            + "work_state_icon text,"
            + "work_state_label text,"
            + "process_result text,"
            + "parent_process text,"
            + "procInstID text,"
            + "completionFormID text,"
            + "completionResultID text,"
            + "isResolution text,"
            + "time text"
            + ");";

    public WorksTable(Context context) {
        super(context, TABLE_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public boolean removeAll() {
        try {
            db.delete(TABLE_NAME, null, null);
            return true;
        } catch (Exception exc) {
            return false;
        }
    }

    public boolean removeWorksByArray(String fType, String fID, String oID) {
        try {
            if (fID == null && oID == null && fType != null) {
                db.delete(TABLE_NAME, "filterType = " + "\"" + fType + "\"" + " AND filterID IS NULL AND objectID IS NULL", null);
            } else if (oID == null) {
                db.delete(TABLE_NAME, "filterID = ?", new String[]{fID});
            } else if (fID == null) {
                db.delete(TABLE_NAME, "objectID = ?", new String[]{oID});
            }
            return true;
        } catch (Exception exc) {
            return false;
        }
    }

    private ContentValues getContentValues(WorkItem work) {
        ContentValues cv = new ContentValues();
        cv.put("actionID", work.getActionID());
        cv.put("filterType", work.getFilterType());
        cv.put("filterID", work.getFilterID());
        cv.put("objectID", work.getObjectID());
        cv.put("name", work.getName());
        cv.put("start_date", work.getStart_date());
        cv.put("finish_date", work.getFinish_date());
        cv.put("stateID", work.getStateID());
        cv.put("userID", work.getUser().getID());
        cv.put("userName", work.getUser().getName());
        cv.put("authorID", work.getAuthor().getID());
        cv.put("authorName", work.getAuthor().getName());
        cv.put("percent", work.getPercent());
        cv.put("has_attachments", work.getHas_attachments());
        cv.put("remained", work.getRemained());
        cv.put("remained_label", work.getRemained_label());
        cv.put("is_expired", work.getIs_expired());
        cv.put("is_soon_expired", work.getIs_soon_expired());
        cv.put("priority", work.getPriority());
        cv.put("can_edit", work.getCan_edit());
        cv.put("can_change_state", work.getCan_change_state());
        cv.put("can_delete", work.getCan_delete());
        cv.put("can_send_acquaintance", work.getCan_send_acquaintance());
        cv.put("can_send_agreement", work.getCan_send_agreement());
        cv.put("can_send_approval", work.getCan_send_approval());
        cv.put("can_be_resended", work.getCan_be_resended());
        cv.put("can_reassign", work.getCan_reassign());
        cv.put("can_send_by_route", work.getCan_send_by_route());
        cv.put("can_change_progress", work.getCan_change_progress());
        cv.put("can_manage_comments", work.getCan_manage_comments());
        cv.put("can_take_on_control", work.getCan_take_on_control());
        cv.put("is_new", work.getIs_new());
        cv.put("has_subprocesses", work.getHas_subprocesses());
        cv.put("can_mark_as_seen", work.getCan_mark_as_seen());
        cv.put("work_state_icon", work.getWork_state_icon());
        cv.put("work_state_label", work.getWork_state_label());
        cv.put("process_result", work.getProcess_result());
        cv.put("parent_process", work.getParent_process());
        cv.put("procInstID", work.getProcInstID());
        cv.put("completionFormID", work.getCompletionFormID());
        cv.put("completionResultID", work.getCompletionResultID());
        cv.put("time", System.currentTimeMillis());
        cv.put("isResolution", work.getIs_resolution());
        return cv;
    }

    public boolean addWorksInTable(List<WorkItem> works) {
        try {
            for (WorkItem work : works) {
                db.insert(TABLE_NAME, null, getContentValues(work));
            }
            return true;
        } catch (Exception exc) {
            return false;
        }
    }

    public boolean addWork(WorkItem work) {
        try {
            db.insert(TABLE_NAME, null, getContentValues(work));
            return true;
        } catch (Exception exc) {
            return false;
        }
    }

    public List<WorkItem> getWorks() {
        List<WorkItem> result = new ArrayList<>();
        Cursor c = null;
        try {
            c = db.query(TABLE_NAME, null, null, null, null, null, null);
            if (c.moveToFirst()) {
                do {
                    result.add(getWork(c));
                } while (c.moveToNext());
            }
            return result;
        } catch (Exception exc) {
            return result;
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }

    public List<WorkItem> getWorksById(String[] uuidArray) {
        List<WorkItem> result = new ArrayList<>();
        for (String uuid : uuidArray) {
            Cursor c = null;
            try {
                c = db.rawQuery("select * from " + TABLE_NAME + " where actionID = ?", new String[]{uuid});
                if (c.moveToFirst()) {
                    result.add(getWork(c));
                }
            } catch (Exception exc) {
                // handling error ...
            } finally {
                if (c != null) {
                    c.close();
                }
            }
        }
        return result;
    }

    public WorkItem getWorkInfo(String actionID) {
        WorkItem work = new WorkItem();
        Cursor c = null;
        try {
            c = db.rawQuery("select * from " + TABLE_NAME + " where actionID = ?", new String[]{actionID});
            if (c.moveToFirst()) {
                do {
                    work = getWork(c);
                } while (c.moveToNext());
            }
            return work;
        } catch (Exception exc) {
            return work;
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }

    private WorkItem getWork(Cursor c) {
        WorkItem work = new WorkItem();
        // пользователь ответственный за работу
        WorkUser user = new WorkUser();
        user.setName(c.getString(c.getColumnIndex("userName")));
        user.setID(c.getString(c.getColumnIndex("userID")));
        // автор работы
        WorkUser author = new WorkUser();
        author.setName(c.getString(c.getColumnIndex("authorName")));
        author.setID(c.getString(c.getColumnIndex("authorID")));
        // данные по работе
        work.setActionID(c.getString(c.getColumnIndex("actionID")));
        work.setFilterType(c.getString(c.getColumnIndex("filterType")));
        work.setFilterID(c.getString(c.getColumnIndex("filterID")));
        work.setObjectID(c.getString(c.getColumnIndex("objectID")));
        work.setName(c.getString(c.getColumnIndex("name")));
        work.setStart_date(c.getString(c.getColumnIndex("start_date")));
        work.setFinish_date(c.getString(c.getColumnIndex("finish_date")));
        work.setStateID(c.getString(c.getColumnIndex("stateID")));
        work.setUser(user);
        work.setAuthor(author);
        work.setPercent(c.getString(c.getColumnIndex("percent")));
        work.setHas_attachments(c.getString(c.getColumnIndex("has_attachments")));
        work.setRemained(c.getString(c.getColumnIndex("remained")));
        work.setRemained_label(c.getString(c.getColumnIndex("remained_label")));
        work.setIs_expired(c.getString(c.getColumnIndex("is_expired")));
        work.setIs_soon_expired(c.getString(c.getColumnIndex("is_soon_expired")));
        work.setPriority(c.getString(c.getColumnIndex("priority")));
        work.setCan_edit(c.getString(c.getColumnIndex("can_edit")));
        work.setCan_change_state(c.getString(c.getColumnIndex("can_change_state")));
        work.setCan_delete(c.getString(c.getColumnIndex("can_delete")));
        work.setCan_send_acquaintance(c.getString(c.getColumnIndex("can_send_acquaintance")));
        work.setCan_send_agreement(c.getString(c.getColumnIndex("can_send_agreement")));
        work.setCan_send_approval(c.getString(c.getColumnIndex("can_send_approval")));
        work.setCan_be_resended(c.getString(c.getColumnIndex("can_be_resended")));
        work.setCan_reassign(c.getString(c.getColumnIndex("can_reassign")));
        work.setCan_send_by_route(c.getString(c.getColumnIndex("can_send_by_route")));
        work.setCan_change_progress(c.getString(c.getColumnIndex("can_change_progress")));
        work.setCan_manage_comments(c.getString(c.getColumnIndex("can_manage_comments")));
        work.setCan_take_on_control(c.getString(c.getColumnIndex("can_take_on_control")));
        work.setIs_new(c.getString(c.getColumnIndex("is_new")));
        work.setHas_subprocesses(c.getString(c.getColumnIndex("has_subprocesses")));
        work.setCan_mark_as_seen(c.getString(c.getColumnIndex("can_mark_as_seen")));
        work.setWork_state_icon(c.getString(c.getColumnIndex("work_state_icon")));
        work.setWork_state_label(c.getString(c.getColumnIndex("work_state_label")));
        work.setProcess_result(c.getString(c.getColumnIndex("process_result")));
        work.setParent_process(c.getString(c.getColumnIndex("parent_process")));
        work.setProcInstID(c.getString(c.getColumnIndex("procInstID")));
        work.setCompletionFormID(c.getString(c.getColumnIndex("completionFormID")));
        work.setCompletionResultID(c.getString(c.getColumnIndex("completionResultID")));
        work.setIs_resolution(c.getString(c.getColumnIndex("isResolution")));
        work.setTime(c.getString(c.getColumnIndex("time")));
        return work;
    }

    public boolean updateWork(WorkItem work) {
        try {
            ContentValues cv = new ContentValues();
            cv.put("percent", work.getPercent());
            cv.put("work_state_icon", work.getWork_state_icon());
            cv.put("work_state_label", work.getWork_state_label());
            db.update(TABLE_NAME, cv, "actionID = ?", new String[]{work.getActionID()});
            return true;
        } catch (Exception exc) {
            return false;
        }
    }
}