import { getDatabaseDir } from "./env";
import { formatDate } from "./utils";
const path = require("path");
const fs = require("fs");
const sqlite = require("sqlite3").verbose();

let db = undefined;

init();

function init() {
  if (db) return;
  const databasePath = getDatabaseDir();
  var orgDb = path.join(databasePath, "org.rdb");
  var clientDb = path.join(databasePath, "client.rdb");

  if (!fs.existsSync(clientDb)) {
    fs.copyFileSync(orgDb, clientDb);
  }
  db = new sqlite.Database(clientDb, sqlite.OPEN_READWRITE);
}

function saveUploadInfo(params) {
  const sql = `INSERT INTO scan (examId, examName, subjectId, subjectName, examNumber, studentName, siteCode, roomCode, formalImgPath, sliceImgPath,isManual,imageEnc, clientUserId, clientUsername, clientUserLoginTime, isUpload,createdTime, fininshTime) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`;
  const datas = [
    params.examId,
    params.examName,
    params.subjectId,
    params.subjectName,
    params.examNumber,
    params.studentName,
    params.siteCode,
    params.roomCode,
    params.formalImgPath,
    params.sliceImgPath,
    params.isManual,
    params.imageEnc,
    params.clientUserId,
    params.clientUsername,
    params.clientUserLoginTime,
    0, // isUpload
    formatDate(), // createdTime
    null
  ];
  return new Promise((resolve, reject) => {
    db.serialize(() => {
      db.run(sql, datas, err => {
        if (err) reject("save upload info to database fail!");

        resolve(this.lastId);
      });
    });
  });
}

function searchUploadList(params) {
  const { where, whereData } = serializeWhere(params);

  const sql = `SELECT * FROM scan WHERE ${where}`;

  return new Promise((resolve, reject) => {
    db.all(sql, whereData, (err, rows) => {
      if (err) reject("search info fail!");
      resolve(rows);
    });
  });
}

function countUploadList(params) {
  const { where, whereData } = serializeWhere(params);
  const sql = `SELECT COUNT(1) as count FROM scan WHERE ${where}`;

  return new Promise((resolve, reject) => {
    db.all(sql, whereData, (err, rows) => {
      if (err) reject("count list fail!");

      resolve(rows[0].count);
    });
  });
}

function updateUploadState(id) {
  const sql = `UPDATE scan SET isUpload=$isUpload,fininshTime=$fininshTime WHERE id=$id`;
  const datas = {
    $isUpload: 1,
    $fininshTime: formatDate(),
    $id: id
  };
  return new Promise((resolve, reject) => {
    db.run(sql, datas, err => {
      if (err) reject("update upload info fail!");

      resolve();
    });
  });
}

function getAllDict() {
  const sql = `SELECT * FROM dict`;

  return new Promise((resolve, reject) => {
    db.all(sql, (err, rows) => {
      if (err) reject("get all dict fail!");

      const storeDict = {};
      rows.map(item => {
        storeDict[item.key] = item.val;
      });
      resolve(storeDict);
    });
  });
}

function initDict(key) {
  const sql = `INSERT INTO dict (key, val) VALUES (?,?)`;
  const datas = [key, null];

  return new Promise((resolve, reject) => {
    db.run(sql, datas, err => {
      if (err) reject(`init dict ${key} fail!`);

      resolve();
    });
  });
}

function getDict(key, defaultVal = "") {
  const sql = `SELECT * FROM dict WHERE key=?`;
  return new Promise((resolve, reject) => {
    db.get(sql, key, (err, row) => {
      if (err) reject(`get dict ${key} fail!`);
      resolve((row && row.val) || defaultVal);
    });
  });
}

function setDict(key, val) {
  const sql = `UPDATE dict SET val=? where key=?`;
  return new Promise((resolve, reject) => {
    db.run(sql, [val, key], err => {
      if (err) reject(`update dict ${key} fail!`);

      resolve();
    });
  });
}

function serializeWhere(params) {
  const where = Object.keys(params)
    .map(key => {
      if (key.indexOf("Time") !== -1) {
        return `${key} LIKE $${key}`;
      } else {
        return `${key} = $${key}`;
      }
    })
    .join(" AND ");
  const whereData = {};
  Object.entries(params).map(([key, val]) => {
    whereData[`$${key}`] = key.indexOf("Time") !== -1 ? `${val}%` : val;
  });

  return {
    where,
    whereData
  };
}

export default {
  init,
  saveUploadInfo,
  searchUploadList,
  countUploadList,
  updateUploadState,
  getDict,
  setDict,
  getAllDict,
  initDict
};
