import moment from "moment";
import CONSTANTS from "../config/constants";
import activityLogsDB from "../models/activityLogs.model";
import clientDB from "../models/client.model";
import flatDB from "../models/flat.model";
import moveOutDB from "../models/moveOut.model";
import occupancyDB from "../models/occupancy.model";
import propertyDB from "../models/property.model";
import roomDB from "../models/room.model";
import staffDB from "../models/staff.model";
import tenantDB from "../models/tenant.model";
import expenseDB from "../models/expense.model";
import log from "../config/log";
import vendor from "../controllers/vendors.controller";
import vendorDB from "../models/vendor.model";
import getModeName from "./getModeName";
import getDueName from "./getDueName";
import landlordDB from "../models/landlord.model";
import bankDB from "../models/bank.model";
import propertyLeaseDB from "../models/propertyLease.model";

export const logActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  tenantId: number,
  //   tenantName: string,
  activity: number,
  arg1: any,
  arg2: any,
  arg3: any,
  arg4: any,
  arg5: any
  //   occupancy: any,
) => {
  const U = "logActivity";
  const F = "logActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let occupancy = await occupancyDB.getByTenantIdAndClientId({
      tenantId,
      clientId,
    });

    if (!occupancy) {
      occupancy = await moveOutDB.getByTenantIdAndClientId({
        tenantId,
        clientId,
      });
    }

    const property = await propertyDB.getById({
      id: occupancy?.propId || null,
    });

    let occupancyName = `${property?.name}_`;

    if (occupancy?.flatId !== null) {
      const flat = await flatDB.getById({ id: occupancy?.flatId || null });
      occupancyName += `${flat?.name}_${occupancy?.roomNum}`;
    } else {
      occupancyName += `${occupancy?.floor}_${occupancy?.roomNum}`;
    }

    const tenant = await tenantDB.getById({
      id: tenantId || null,
    });

    const tenantName = tenant?.name || "";

    let dateDesc = ` for ${moment(arg3).format("DD MMM YY")} to ${moment(
      arg4
    ).format("DD MMM YY")} `;
    if (!arg3 || !arg4) {
      dateDesc = " ";
    }

    let description = "";
    let activityConstant = 0;
    if (activity === CONSTANTS.ACTIVITY_TYPES.ADD_DUES) {
      description = `Added ₹${arg1} "${arg2}" due${dateDesc}for ${tenantName}(${occupancyName})`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.ADD_DUES;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.MARK_PAID) {
      description = `Marked ₹${arg1} "${arg2}" due${dateDesc}as paid via ${arg5} for ${tenantName}(${occupancyName})`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.MARK_PAID;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.PROPERTY_CHANGE) {
      description = `Switched ${tenantName}(${occupancyName}) from ${arg2} to ${arg1} on ${arg4}, with shifting date ${arg3}`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.PROPERTY_CHANGE;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.DELETE_DUES) {
      description = `Deleted ₹${arg1} "${arg2}" due${dateDesc}for ${tenantName}(${occupancyName})`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.DELETE_DUES;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.EDIT_DUES) {
      description = `Edited ₹${arg1} "${arg2}" due${dateDesc}to ₹${arg5} for ${tenantName}(${occupancyName})`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.EDIT_DUES;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_ADDED) {
      //description = `Added Tenant ${tenantName}(${occupancyName}) ${arg1 === true ? "moving" : "moved"} in on ${moment(arg2).format("DD MMM YYYY")}`;
      description = `${tenantName}(${occupancyName}) has been added as a tenant and ${
        arg1 === true ? "will be moving" : "moved"
      } in on ${moment(arg2).format("DD MMM YYYY")}`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.TENANT_ADDED;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.ADD_EXTRA_CHARGES) {
      description = `Added Extra charge ${
        arg2.toLowerCase().includes("Electricity")
          ? arg1 === 0
            ? ""
            : `of ₹${arg1}/unit`
          : `of ₹${arg1}`
      } for ${arg2} for properties (${arg3})`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.ADD_EXTRA_CHARGES;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.SETTLE_EXCESS) {
      description = `Paid Excess payment of ₹${arg1} back to ${tenantName}(${occupancyName}) via ${arg3} on ${moment(
        arg2
      ).format("DD MMM YYYY")}`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.SETTLE_EXCESS;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.SETTLE_EXCESS_VIA_PAYOUT) {
      description = `Paid Excess payment of ₹${arg1} back to ${tenantName}(${occupancyName}) online via payout module on ${moment(
        arg2
      ).format("DD MMM YYYY")}`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.SETTLE_EXCESS_VIA_PAYOUT;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.ASSIGN_TENANT_COMPLAINT) {
      //description = `Assigned ${arg1} complaint to ${arg2} raised by ${tenantName}(${occupancyName}) on ${moment().format("DD MMM YYYY")}`;
      description = `Assigned ${arg1} complaint to ${arg2} raised by ${tenantName}(${occupancyName})`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.ASSIGN_TENANT_COMPLAINT;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.RESTORE_TRANS) {
      //description = `Restored ₹${arg1} transaction paid by ${tenantName}(${occupancyName}) for ${arg2} on ${moment(arg3).format("DD MMM YYYY")}`;
      description = `Restored ₹${arg1} transaction paid by ${tenantName}(${occupancyName}) for ${arg2}`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.RESTORE_TRANS;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.CANCEL_RESERVATION) {
      description = `Cancelled reservation of ${tenant.name} for ${occupancyName}`;
      //description = `${tenant.name} is now deleted from reserved tenants from ${occupancyName}`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.CANCEL_RESERVATION;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.BOOKED_AGAIN) {
      if (Number(arg1) === 1) {
        //description = `Cancelled reservation tenant ${tenant.name} has been added back again in ${occupancyName}`;
        description = `Tenant ${tenant.name} from a cancelled reservation has been added back again to ${occupancyName}.`;
      } else {
        description = `Moved Out tenant ${tenant.name} is added back in ${occupancyName}`;
      }
      activityConstant = CONSTANTS.ACTIVITY_TYPES.BOOKED_AGAIN;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.DELETE_TENANT) {
      description = `Tenant ${tenant.name}(${tenant.mobile}) has been deleted from records.`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.DELETE_TENANT;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_OCCUPANCY_CHANGE) {
      description = `${tenant.name} (${occupancyName}) occupancy was updated from ${arg1} beds to a single bed.`;
      activityConstant = CONSTANTS.ACTIVITY_TYPES.TENANT_OCCUPANCY_CHANGE;
    }else {
      description = "";
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    await activityLogsDB.logActivity({
      tenantId: tenantId === 0 ? null : tenantId,
      clientId,
      propId: occupancy?.propId || null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: activityConstant,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logExpenseActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  paidBy: number,
  paidByUserType: number,
  paidTo: number,
  paidToUserType: number,
  expenseType: number,
  amount: number,
  mode: number,
  propId: any = 0,
  isPaid: any = 1
) => {
  const U = "logActivity";
  const F = "logExpenseActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let property = null;

    if (propId && Number(propId) !== 0) {
      property = await propertyDB.getById({ id: propId });
    }

    let expenseTypeName = await expenseDB.getExpenseTypeById({
      id: expenseType,
    });
    let expenseCategoryName = await expenseDB.getExpenseCategoryById({
      id: expenseTypeName?.categoryId,
    });
    expenseTypeName = expenseTypeName?.name || "general";
    expenseCategoryName = expenseCategoryName?.name || "general";

    let paidByName = "";
    if (Number(paidByUserType) === CONSTANTS.USER_TYPE.STAFF) {
      const staff = await staffDB.getById({ id: paidBy });
      paidByName = `${staff?.name}(Staff)` || "Staff";
    } else if (Number(paidByUserType) === CONSTANTS.USER_TYPE.CLIENT) {
      client = await clientDB.getById({ id: clientId });
      paidByName = `${client?.name}(Client)` || "Client";
    }

    let paidToName = "";
    if (Number(paidToUserType) === CONSTANTS.USER_TYPE.STAFF) {
      const staff = await staffDB.getById({ id: paidTo });
      paidToName = `${staff?.name}(Staff)` || "Staff";
    } else if (Number(paidToUserType) === CONSTANTS.USER_TYPE.VENDOR) {
      const vendor = await vendorDB.getById({ id: paidTo });
      paidToName = `${vendor?.name}(Vendor)` || "Vendor";
    } else if (Number(paidToUserType) === CONSTANTS.USER_TYPE.LANDLORD) {
      const landlord = await landlordDB.getById({ id: paidTo });
      paidToName = `${landlord?.name}(Landlord)` || "Landlord";
    }

    let modeName = getModeName(mode);

    let description = "";

    if (activity === CONSTANTS.ACTIVITY_TYPES.ADD_EXPENSE) {
      description = `Added an expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName}. Payment was made by ${paidByName} to ${paidToName} ${
        propId ? `for property ${property?.name}` : ""
      }`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.ADD_UNPAID_EXPENSE) {
      description = `Added a unpaid expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName}. Payment was made by ${paidByName} to ${paidToName} ${
        propId ? `for property ${property?.name}` : ""
      }`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.DELETE_EXPENSE) {
      if (isPaid === 0) {
        description = `Deleted an unpaid expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName} ${
          propId ? `for property ${property?.name}` : ""
        }`;
      } else {
        description = `Deleted an expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName} ${
          propId ? `for property ${property?.name}` : ""
        }`;
      }
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.MARKED_EXPENSE) {
      description = `${paidByName} paid ₹${amount} to ${paidToName} via ${modeName} under Type '${expenseTypeName}' and Category '${expenseCategoryName}' ${
        propId ? `for property ${property?.name}` : ""
      }`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.EDIT_EXPENSE) {
      description = `Edited an expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName} ${
        propId ? `for property ${property?.name}` : ""
      }`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.ADD_RECURRING_EXPENSE) {
      description = `Added a recurring expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName} ${
        propId ? `for property ${property?.name}` : ""
      }. Expense will recur as per set frequency.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.EDIT_RECURRING_EXPENSE) {
      description = `Edited a recurring expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName} ${
        propId ? `for property ${property?.name}` : ""
      }. Expense will recur as per set frequency.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.DELETE_RECURRING_EXPENSE) {
      description = `Deleted a recurring expense of amount ₹${amount} under Type ${expenseTypeName} and Category ${expenseCategoryName} ${
        propId ? `for property ${property?.name}` : ""
      }. Expense will recur as per set frequency.`;
    }

    await activityLogsDB.logActivity({
      tenantId: null,
      clientId,
      propId: propId || null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: activity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};
export const logUtilityBillActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  type: number,
  noOfTenants: number,
  amount: number,
  propId: any,
  roomFlatName: any
) => {
  const U = "logActivity";
  const F = "logExpenseActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let property = null;

    if (propId && Number(propId) !== 0) {
      property = await propertyDB.getById({ id: propId });
    }

    const utilityTypeName = getDueName(type);

    let description = "";

    if (activity === CONSTANTS.ACTIVITY_TYPES.UTILITY_BILL_ADDED) {
      description = `Added ${utilityTypeName} bill of amount ₹${amount} for ${noOfTenants} Tenants living in ${
        property.type === CONSTANTS.PROPERTY_TYPE.FLAT ? "Flat" : "Room"
      } ${roomFlatName} in Property ${property?.name}`;
    }

    await activityLogsDB.logActivity({
      tenantId: null,
      clientId,
      propId: propId || null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: activity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logTenantRequestActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  propId: any,
  tenantId: number,
  tenantName: string,
  roomId: number,
  amount: number = 0
) => {
  const U = "logActivity";
  const F = "logTenantRequestActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    let tenant = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else if (userType === CONSTANTS.USER_TYPE.TENANT) {
      tenant = await tenantDB.getById({ id: id });
      userName = tenant.name;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let property = await propertyDB.getById({ id: propId });
    let room = await roomDB.getById({ id: roomId });

    let occupancyName = `${property?.name}_`;

    if (room?.flatId !== null) {
      const flat = await flatDB.getById({ id: room?.flatId || null });
      occupancyName += `${flat?.name}_${room?.roomNum}`;
    } else {
      occupancyName += `${room?.floor}_${room?.roomNum}`;
    }

    if (userType === CONSTANTS.USER_TYPE.TENANT) {
      clientId = property?.clientId || 0;
    }

    let description = "";
    let addActivity = activity;
    if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_ROOM_REQUEST) {
      description = `${tenantName} has made a room request for ${occupancyName}`;
    } else if (
      activity === CONSTANTS.ACTIVITY_TYPES.TENANT_ROOM_REQUEST_CANCEL
    ) {
      description = `${tenantName} has cancelled the room request for ${occupancyName}`;
    } else if (
      activity === CONSTANTS.ACTIVITY_TYPES.TENANT_ROOM_REQUEST_REJECT
    ) {
      description = `${userName} has rejected the room request raised by ${tenantName} for ${occupancyName}`;
    } else if (
      activity === CONSTANTS.ACTIVITY_TYPES.TENANT_ROOM_REQUEST_ACCEPT
    ) {
      description = `${userName} has accepted the room request raised by ${tenantName} for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.GUEST_REQUEST) {
      description = `${tenantName} has requested permission for guests for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.GUEST_REQUEST_ACCEPTED) {
      //addActivity = CONSTANTS.ACTIVITY_TYPES.GUEST_REQUEST;
      if (Number(amount) > 0) {
        //description = `${userName} has accepted the request for guests raised by ${tenantName} for ${occupancyName}`
        description = `${userName} has approved the guest request raised by ${tenantName} for ${occupancyName}. Guest charges of ₹${amount} have been applied.`;
      } else {
        description = `${userName} has accepted the request for guests raised by ${tenantName} for ${occupancyName}`;
      }
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.GUEST_REQUEST_REJECTED) {
      description = `${userName} has rejected the request for guests raised by ${tenantName} for ${occupancyName}`;
    } 
    else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_LATE_ARRIVAL_REQUEST) {
      description = `${tenantName} has notified a late arrival for their stay at ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_LATE_ARRIVAL_REQUEST_ACCEPTED) {
      description = `${userName} has approved the late arrival request raised by ${tenantName} for ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_LATE_ARRIVAL_REQUEST_REJECTED) {
      description = `${userName} has rejected the late arrival request raised by ${tenantName} for ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_GOING_HOME_REQUEST) {
      description = `${tenantName} has notified that they will be away from ${occupancyName} as they are going home.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_GOING_HOME_REQUEST_ACCEPTED) {
      description = `${userName} has approved the going home request raised by ${tenantName} for ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_GOING_HOME_REQUEST_REJECTED) {
      description = `${userName} has rejected the going home request raised by ${tenantName} for ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_NIGHT_OUT_REQUEST) {
      description = `${tenantName} has notified a night out for their stay at ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_NIGHT_OUT_REQUEST_ACCEPTED) {
      description = `${userName} has approved the night out request raised by ${tenantName} for ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_NIGHT_OUT_REQUEST_REJECTED) {
      description = `${userName} has rejected the night out request raised by ${tenantName} for ${occupancyName}.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.REFUND_REQUEST_INITIATED) {
      description = `${tenantName} has made a refund request for ${occupancyName}`;
    } else if (
      activity === CONSTANTS.ACTIVITY_TYPES.REFUND_REQUEST_INPROGRESS
    ) {
      description = `${userName} has accepted the refund request for processing, raised by ${tenantName} for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.REFUND_REQUEST_REJECTED) {
      description = `${userName} has rejected the refund request raised by ${tenantName} for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.REFUND_REQUEST_PROCESSED) {
      if (amount > 0) {
        description = `${userName} has successfully processed the refund for ${tenantName} (${occupancyName}). ₹${amount} has been paid back.`;
      } else {
        description = `${userName} has successfully processed the refund for ${tenantName} (${occupancyName}).`;
      }
    }

    await activityLogsDB.logActivity({
      tenantId: tenantId,
      clientId,
      propId: propId || null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: addActivity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logTenantAgreementRenewActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  propId: any,
  tenantId: number,
  tenantName: string,
  roomId: number
) => {
  const U = "logActivity";
  const F = "logTenantAgreementRenewActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let property = await propertyDB.getById({ id: propId });
    let room = await roomDB.getById({ id: roomId });

    let occupancyName = `${property?.name}_`;

    if (room?.flatId !== null) {
      const flat = await flatDB.getById({ id: room?.flatId || null });
      occupancyName += `${flat?.name}_${room?.roomNum}`;
    } else {
      occupancyName += `${room?.floor}_${room?.roomNum}`;
    }

    if (userType === CONSTANTS.USER_TYPE.TENANT) {
      clientId = property?.clientId || 0;
    }

    let description = "";

    if (activity === CONSTANTS.ACTIVITY_TYPES.RENEW_AGREEMENT) {
      description = `${userName} has renewed rent agreement for ${tenantName} living in ${occupancyName}`;
    }

    await activityLogsDB.logActivity({
      tenantId: tenantId,
      clientId,
      propId: propId || null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: activity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logPropertyActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  propId: any,
  roomId: number = 0,
  beds: number = 0
) => {
  const U = "logActivity";
  const F = "logPropertyActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let property = await propertyDB.getById({ id: propId });
    let room = null;
    let propertyName = property?.name || "";
    if (roomId) {
      room = await roomDB.getById({ id: roomId });

      if (property?.type === CONSTANTS.PROPERTY_TYPE.FLAT) {
        const flat = await flatDB.getById({ id: room?.flatId || null });
        propertyName = `${property?.name}_${flat?.name}_${room?.roomNum}`;
      } else {
        propertyName = `${property?.name}_${room?.floor}_${room?.roomNum}`;
      }
    }

    let description = "";

    if (activity === CONSTANTS.ACTIVITY_TYPES.MAKE_PROPERTY_ACTIVE) {
      description = `${userName} has toggled Property(${property?.name}) as active.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.MAKE_PROPERTY_INACTIVE) {
      description = `${userName} has toggled Property(${property?.name}) as inactive.`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.DELETE_PROPERTY) {
      description = `${userName} has deleted the Property(${property?.name}).`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.REMOVE_BED) {
      description = `${userName} has removed a bed from the Property(${propertyName}).`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.ADD_BED) {
      if (beds > 1) {
        description = `${userName} has added ${beds} beds to the Property(${propertyName}).`;
      } else {
        description = `${userName} has added a bed to the Property(${propertyName}).`;
      }
    }

    await activityLogsDB.logActivity({
      tenantId: null,
      clientId,
      propId: propId || null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: activity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logTenantEvictionActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  propId: any,
  tenantId: number,
  tenantName: string,
  roomId: number,
  date: string = ""
) => {
  const U = "logActivity";
  const F = "logTenantEvictionActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    let tenant = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else if (userType === CONSTANTS.USER_TYPE.TENANT) {
      tenant = await tenantDB.getById({ id: id });
      userName = tenant.name;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let property = await propertyDB.getById({ id: propId });
    let room = await roomDB.getById({ id: roomId });

    let occupancyName = `${property?.name}_`;

    if (room?.flatId !== null) {
      const flat = await flatDB.getById({ id: room?.flatId || null });
      occupancyName += `${flat?.name}_${room?.roomNum}`;
    } else {
      occupancyName += `${room?.floor}_${room?.roomNum}`;
    }

    if (userType === CONSTANTS.USER_TYPE.TENANT) {
      clientId = property?.clientId || 0;
    }

    let description = "";
    let addActivity = activity;
    if (activity === CONSTANTS.ACTIVITY_TYPES.MOVEOUT_REQUEST) {
      description = `${tenantName} has made a move-out request for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.TENANT_CANCELLED_MOVEOUT) {
      description = `${tenantName} has cancelled the move-out request for ${occupancyName}`;
    } else if (
      activity === CONSTANTS.ACTIVITY_TYPES.MOVEOUT_REQUEST_CANCELLED
    ) {
      description = `${userName} has cancelled the move-out of ${tenantName} for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.EXTEND_STAY) {
      description = `${userName} has extended the stay of ${tenantName}(${occupancyName}). Updated move-out date is ${moment(
        date
      ).format("DD MMM YYYY")}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.MOVEOUT_REQUEST_REJECTED) {
      description = `${userName} has rejected the move-out request raised by ${tenantName} for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.MOVEOUT_REQUEST_ACCEPTED) {
      description = `${userName} has accepted the move-out request raised by ${tenantName} for ${occupancyName}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.MOVEOUT_INITIATED) {
      description = `${userName} has initiated the move-out for ${tenantName} (${occupancyName}) with a move-out date of ${moment(
        date
      ).format("DD MMM YYYY")}`;
    } else if (activity === CONSTANTS.ACTIVITY_TYPES.MOVEOUT_NOW) {
      description = `${userName} has moved out ${tenantName} from ${occupancyName}`;
    }

    await activityLogsDB.logActivity({
      tenantId: tenantId,
      clientId,
      propId: propId || null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: addActivity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logBankActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  propNames: any,
  bankId: any,
  oldBankId: any = 0
) => {
  const U = "logActivity";
  const F = "logBankActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    let tenant = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else if (userType === CONSTANTS.USER_TYPE.TENANT) {
      tenant = await tenantDB.getById({ id: id });
      userName = tenant.name;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let bank = await bankDB.getById({ id: bankId });

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let description = "";
    let addActivity = activity;
    if (activity === CONSTANTS.ACTIVITY_TYPES.SWITCH_ONLINE_ACCOUNT) {
      if (0 === oldBankId) {
        description = `${userName} linked the bank account ${bank?.holderName}(${bank?.accountNum}) to the property ${propNames}.`;
      } else {
        let oldBank = await bankDB.getById({ id: oldBankId });
        description = `${userName} changed the linked bank account for the property ${propNames} from ${oldBank?.holderName}(${oldBank?.accountNum}) to ${bank?.holderName}(${bank?.accountNum}).`;
      }
    }

    await activityLogsDB.logActivity({
      tenantId: null,
      clientId,
      propId: null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: addActivity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logLeaseActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  landlordId: number,
  propId: number,
) => {
  const U = "logActivity";
  const F = "logBankActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    let tenant = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else if (userType === CONSTANTS.USER_TYPE.TENANT) {
      tenant = await tenantDB.getById({ id: id });
      userName = tenant.name;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    const landlord = await landlordDB.getById({
      id: landlordId,
    });

    const property = await propertyDB.getById({
      id: propId,
    });

    const propertyLease = await propertyLeaseDB.getByClientIdAndPropId({
      clientId,
      propId,
    });

    let description = "";
    let addActivity = activity;
    if (activity === CONSTANTS.ACTIVITY_TYPES.ADD_PROPERTY_LEASE) {
      description = `${userName} has added lease for "${property?.name}" under landlord ${landlord?.name}. Unpaid expenses for security(₹${propertyLease.security}) and rent(₹${propertyLease.rent}) were created, and a recurring rent expense was scheduled.`;
    }

    await activityLogsDB.logActivity({
      tenantId: null,
      clientId,
      propId: propId,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: addActivity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logRentalCycleActivity = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  tenantId: number,
  oldCycle: string,
  newCycle: string  
) => {
  const U = "logActivity";
  const F = "logRentalCycleActivity";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    let tenant = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    tenant = await tenantDB.getById({id: tenantId});
    
    const occupancy = await occupancyDB.getByTenantIdAndClientId({
      clientId,
      tenantId,
    });

    const property = await propertyDB.getById({
      id: occupancy?.propId,
    });
    

    let description = `${userName} has changed rental cycle for tenant "${tenant?.name}" in property "${property?.name}" from ${oldCycle} to ${newCycle}.`;

    await activityLogsDB.logActivity({
      tenantId: tenantId,
      clientId:clientId,
      propId: occupancy?.propId,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: activity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};

export const logStaffAttendanceManual = async (
  userType: number,
  id: number,
  parentId: number,
  device: number,
  activity: number,
  staffId: number,
  date: string,
  status: number
) => {
  const U = "logActivity";
  const F = "logStaffAttendanceManual";
  try {
    let clientId = id;
    let doneBy = parentId;
    let userName = "";
    let staff = null;
    let client = null;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      staff = await staffDB.getById({ id: id });
      userName = staff.name;
      clientId = staff.clientId;
      doneBy = id;
    } else {
      client = await clientDB.getById({ id: parentId });
      userName = client.name;
    }

    let doneByRole = 0;
    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      doneByRole = staff?.role;
    }

    let attendanceStaff = await staffDB.getById({
      id: staffId,
    });

    let attendance = "";
    if (status === 0) {
      attendance = "Absent";
    } else if (status === 2) {
      attendance = "Holiday";
    } else if (status === 1) {
      attendance = "Present";
    }

    let description = ""; 

    if(activity === CONSTANTS.ACTIVITY_TYPES.STAFF_CHECKIN_MANUAL){
      description = `${userName} has manually checked in "${attendanceStaff?.name}" for date ${moment(date).format("YYYY-MM-DD")} on ${moment().format("YYYY-MM-DD HH:mm:ss")}.`;
    }else if(activity === CONSTANTS.ACTIVITY_TYPES.STAFF_CHECKOUT_MANUAL){
      description = `${userName} has manually checked out "${attendanceStaff?.name}" for date ${moment(date).format("YYYY-MM-DD")} on ${moment().format("YYYY-MM-DD HH:mm:ss")}.`;
    }else if(activity === CONSTANTS.ACTIVITY_TYPES.STAFF_MARK_ABSENT_MANUAL){
      description = `${userName} has marked "${attendanceStaff?.name}" as Absent for date ${moment(date).format("YYYY-MM-DD")} on ${moment().format("YYYY-MM-DD HH:mm:ss")}.`;
    }

    await activityLogsDB.logActivity({
      tenantId: null,
      clientId:clientId,
      propId: null,
      doneByUserType: userType,
      doneBy: doneBy,
      doneByName: userName,
      doneByRole: doneByRole,
      activity: activity,
      description: description,
      device: device || 0,
    });
  } catch (error: any) {
    log.info(`[${U}], [${F}], Error: ${error?.message || error}`);
  }
};
