import { ResultSetHeader, RowDataPacket } from "mysql2";
import DB from "../config/database/db";
import assetTypes from "../schemas/assets.schema";
import CONSTANTS from "../config/constants";
import assetInfoTypes from "../schemas/assetInfo.schema";

const assetsDB: any = {};

assetsDB.getById = async ({ id }: assetTypes) => {
  const query = "Select * from Assets where id = ?";
  const data = [id];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows.length > 0) return rows[0];
  else return false;
};

assetsDB.add = async ({
  name,
  clientId,
  type,
  purchaseDate,
  total,
  free,
  cost,
  depreciationRate,
  status,
  description,
  vendorId,
  warrentyExpire,
}: assetTypes) => {
  const query =
    "Insert into Assets (name, clientId, type, purchaseDate, total, free, cost, depreciationRate, status, description, vendorId, warrentyExpire) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
  const data = [
    name,
    clientId,
    type,
    purchaseDate,
    total,
    free,
    cost,
    depreciationRate,
    status,
    description,
    vendorId,
    warrentyExpire,
  ];
  const [row] = await DB.execute<ResultSetHeader>(query, data);
  return row.insertId;
};

assetsDB.addAssetInfo = async ({
  clientId,
  assetId,
  type,
  value,
}: assetInfoTypes) => {
  const query = `Insert into AssetInfo(clientId, assetId, type, value) values (?, ?, ?, ?)`;
  const data = [
    clientId,
    assetId,
    type,
    value,
  ];
  const [row] = await DB.execute<ResultSetHeader>(query, data);
  return row.insertId;
};

assetsDB.updateAssetInfo = async ({
  clientId,
  assetId,
  type,
  value,
}: assetInfoTypes) => {
  const query = `Update AssetInfo set value = ? where clientId = ? and assetId = ? and type = ?`;
  const data = [
    value,
    clientId,
    assetId,
    type,
  ];
  const [row] = await DB.execute<ResultSetHeader>(query, data);
  return row.insertId;
};

assetsDB.updateFreeUnits = async ({ id, free }: assetTypes) => {
  const query = "Update Assets set free = ? where id = ?";
  const data = [free, id];
  await DB.execute<ResultSetHeader[]>(query, data);
  return true;
};

assetsDB.getByClientId = async ({ clientId }: assetTypes) => {
  const query = "Select * from Assets where clientId = ? and status != ? order by id desc";
  const data = [
    clientId,
    CONSTANTS.ASSETS_STATUS.DELETED,
  ];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  return rows;
};

assetsDB.updateAssetCount = async ({ id, total, free }: assetTypes) => {
  const query = "Update Assets set total = ?, free = ? where id = ?";
  const data = [total, free, id];
  await DB.execute<ResultSetHeader[]>(query, data);
  return true;
};

assetsDB.updateDescription = async ({ id, description }: assetTypes) => {
  const query = "Update Assets set description = ? where id = ?";
  const data = [description, id];
  await DB.execute<ResultSetHeader[]>(query, data);
  return true;
};

assetsDB.updateStatus = async ({
  id,
  status,
}: assetTypes) => {
  const query = "Update Assets set status = ? where id = ?";
  const data = [status, id];
  await DB.execute<ResultSetHeader[]>(query, data);
  return true;
};

assetsDB.deleteAssetInfo = async ({
  clientId,
  assetId,
  type,
}: assetInfoTypes) => {
  const query = "Delete from AssetInfo where clientId = ? and assetId = ? and type = ?";
  const data = [clientId, assetId, type];
  await DB.execute<ResultSetHeader[]>(query, data);
  return true;
};

assetsDB.getByClientIdAndFilters = async ({
  clientId,
  status,
  type,
}: assetTypes & {type: any[]}) => {
  let query = `Select * from Assets where clientId = ? `
  let data: any = [clientId];

  if (status && Number(status)) {
    query += ` and status = ?`;
    data.push(status);
  }

  if (type && type.length > 0) {
    query += ` and type in (${type.map(() => '?').join(',')})`;
    data.push(...type);
  }

  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows.length > 0) return rows;
  return false;
};

assetsDB.getAssetInfoByClientIdAndType = async ({
  clientId,
  assetId,
  type,
}: assetInfoTypes) => {
  const query = `Select * from AssetInfo where clientId = ? and assetId = ? and type = ?`;
  const data = [clientId, assetId, type];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows.length > 0) return rows[0];
  return false; 
};

assetsDB.getAssetInfoByAssetId = async ({
  assetId,
}: assetInfoTypes) => {
  const query = `Select * from AssetInfo where assetId = ?`;
  const data = [assetId];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows.length > 0) return rows;
  return false; 
};

assetsDB.getParticularAssetInfoByAssetId = async ({
  assetId,
  type,
}: assetInfoTypes) => {
  const query = `Select * from AssetInfo where assetId = ? and type = ?`;
  const data = [assetId, type];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows.length > 0) return rows[0];
  return false; 
};

export default assetsDB;
