import { Request, Response } from "express";
import clientDB from "../models/client.model";
import log from "../config/log";
import CONSTANTS from "../config/constants";
import propertyDB from "../models/property.model";
import CustomRequest from "../types/requestType";
import noticeDB from "../models/notice.model";
import tenantDB from "../models/tenant.model";
import occupancyDB from "../models/occupancy.model";
import staffDB from "../models/staff.model";
import propertiesTypes from "../schemas/property.schema";
import fsPromises from "fs/promises";
import fs from "fs";
import moment from "moment";
import { isUserPartner } from "../utils/isUserPartner";
import { exec } from 'child_process';
import noticePollOptionDB from "../models/noitcePollOption.model";
import noticePollResponseDB from "../models/noticePollResponse.model";
import moveOutDB from "../models/moveOut.model";
import { cli } from "winston/lib/winston/config";

const notice: any = {};

notice.AddNotice = async (req: CustomRequest, res: Response) => {
  const C = "Notice Controller";
  const F = "AddNotice";

  try {
    let { title, description, propertyList, type = 1, optionList } = req.body;

    log.info(
      `[${C}], [${F}], Client Id [${req.id}], Title [${title}], Description [${description}], Prop List [${propertyList}], Type [${type}], Option List [${optionList}]`
    );

    if (Number(type) === CONSTANTS.NOTICE_TYPE.POLL && (!optionList || optionList.length === 0)) {
      log.info(
        `[${C}], [${F}], Client Id [${req.id}], Title [${title}], Description [${description}], Prop List [${propertyList}], Type [${type}], Empty Option List`
      );
      return res.status(400).json({ 
        msg: "Option list cannot be empty for poll type", 
        isSuccess: false 
      });
    }

    if (Number(type) === CONSTANTS.NOTICE_TYPE.POLL)
    {
      optionList = JSON.parse(optionList);
      log.info(
        `[${C}], [${F}], Client Id [${req.id}], Questions ` + optionList
      );
    }

    if (!title || title === "undefined") title = null;
    if (!description || description === "undefined") description = null;

    if (!propertyList || propertyList === "undefined") propertyList = [];
    else propertyList = JSON.parse(propertyList);

    const userType = req.userType;
    const file = req.file;
    let clientId = req.id;

    if (!title) {
      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Prop Length [${propertyList.length}], Empty Title`
      );

      if (file) await fsPromises.unlink(file.path);

      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }

    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      const staff = await staffDB.getById({ id: req.id });
      if (!staff) {
        log.info(
          `[${C}], [${F}], Title [${title}], Description [${description}], Prop Length [${propertyList.length}], Staff Id [${req.id}], No Staff Found`
        );

        if (file) await fsPromises.unlink(file.path);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      clientId = staff.clientId;

      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Prop Length [${propertyList.length}], Staff Id [${req.id}], Staff Requested....`
      );
    } else {
      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Prop Length [${propertyList.length}], Client Requested....`
      );
    }

    const client = await clientDB.getById({ id: clientId });

    if (!client) {
      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Prop Length [${propertyList.length}], No Client Found`
      );

      if (file) await fsPromises.unlink(file.path);

      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }

    let filePath = null;
    if (file) {
      const folderName = `notices/${moment().format("DD_MM_YYYY")}`;
      const folderPath = `uploads/documents/client_${client.id}/${folderName}`;

      if (!fs.existsSync(folderPath)) {
        await fsPromises.mkdir(folderPath, { recursive: true });
      }

      const oldPath = `uploads/tmp/${file.filename}`;
      const newPath = `${folderPath}/${file.filename}`;
      await fsPromises.copyFile(oldPath, newPath);

      filePath = `${process.env.UPLOAD_PATH}/documents/client_${client.id}/${folderName}/${file.filename}`;
    }

    const noticeId = await noticeDB.create({
      clientId,
      type,
      title: title || null,
      description: description || "",
      img: filePath || "",
      publishedBy: Number(req.userType) === CONSTANTS.USER_TYPE.CLIENT ? 0 : req.id,
    });

    if (file) await fsPromises.unlink(file.path);

    for (const index in propertyList) {
      try {
        const propertyId = propertyList[index];
        const propertyDetail = await propertyDB.getById({ id: propertyId });

        if (!propertyDetail) {
          log.info(
            `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Property Id [${propertyId}], Property Not Found`
          );
          continue;
        }

        await noticeDB.addToPropertyNotice({
          noticeId,
          propId: propertyDetail?.id,
          clientId: propertyDetail?.clientId,
        });

        log.info(
          `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Property Id [${propertyDetail.id}], Announcement Sent Successfully`
        );
      } catch (error: any) {
        log.info(
          `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Error while sending Announcement: ${
            error?.message || error
          }`
        );
      }
    }

    if (Number(type) === CONSTANTS.NOTICE_TYPE.POLL && optionList && optionList.length > 0) {
      for (const option of optionList) {
        await noticePollOptionDB.addPollOption({
          clientId,
          noticeId,
          description: option,
        });
      }
    }

    //PHP Script to Sent InApp Notice Notification
    let noticeScript = process.env.NOTICES_PUSH_PATH;
    exec(`php ${noticeScript} ${clientId} ${noticeId} > /dev/null 2>&1 &`);

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Title [${title}], Description [${description}], Type [${type}], Property List [${propertyList}], Option List [${optionList}] Announcement sent successfully`
    );

    return res.status(200).json({
      msg: "Announcement has been sent successfully",
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

notice.ListForClient = async (req: CustomRequest, res: Response) => {
  const C = "Notice Controller";
  const F = "ListForClient";

  try {
    // let clientId = req.id;
    const userType = req.userType;

    let list: any = [];

    // let isPartner = false;

    // if (userType === CONSTANTS.USER_TYPE.STAFF) {
    //   const staff = await staffDB.getById({ id: req.id });
    //   if (!staff) {
    //     log.info(`[${C}], [${F}], Staff Id [${req.id}] No Staff Found`);
    //     return res
    //       .status(400)
    //       .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    //   }
    //   isPartner = staff.role === CONSTANTS.STAFF_ROLES.PARTNER ? true : false;
    //   clientId = staff.clientId;
    // }

    let {isPartner, clientId} = await isUserPartner (Number(userType), Number(req.id));

    if (userType === CONSTANTS.USER_TYPE.CLIENT || isPartner) {
      log.info(`[${C}], [${F}], Client Id [${clientId}], ${isPartner? "Partner Requesting": "Client Requesting"}....`);

      const client = await clientDB.getById({ id: clientId });

      if (!client) {
        log.info(`[${C}], [${F}], Client Id [${clientId}], No Client Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      list = await noticeDB.getByClientId({ clientId });

      if (list) {
        for (const notice of list) {
          const propList = await noticeDB.getByIdFromPropertyNotice({
            noticeId: notice?.id,
          });
          if (!propList) {
            log.info(
              `[${C}], [${F}], Client Id [${clientId}], Notice Id [${notice?.id}], No Property Found`
            );

            notice.propertyList = [];
            continue;
          }

          notice.propertyList = propList;

          const noticeView = await noticeDB.getViewsByNoticeId({
            noticeId: notice?.id,
          });

          notice.views = noticeView
            ? noticeView[0]?.totalViews || 0
            : 0;
          notice.tenantViewed = noticeView.length > 0 ? noticeView?.map((v:any) => v.tenantName) : [];

          const pollOptions = await noticePollOptionDB.getPollOptionsByNoticeId({
            noticeId: notice?.id,
          });

          notice.pollOptions = pollOptions.length > 0 ? pollOptions : [];

          
          const pollResponsesPerOption = await noticePollResponseDB.getTotalResponsesByNoticeIdPerOption({
            noticeId: notice?.id,
          });

          const propertiesIds = propList
          .map((prop: propertiesTypes) => prop.id)
          .join(",");

          const totalTenants = await occupancyDB.getTotalActiveTenantsByPropIds({
            clientId,
            propertiesIds: propertiesIds,
          });
          
          const totalPollResponses = await noticePollResponseDB.getTotalResponsesByNoticeId({
            noticeId: notice?.id,
          });
          
          notice.totalPollResponses = totalPollResponses || 0;
          notice.totalTenants = totalTenants || 0;
          
          notice.pollResponsesPerOption = pollResponsesPerOption || false;

          const pollResponses = await noticePollResponseDB.getPollResponsesByNoticeId({
            noticeId: notice?.id,
          });

          if (pollResponses && pollResponses.length > 0) {
            notice.pollResponses = pollResponses;
          } else {
            notice.pollResponses = {};
          }
        }
      }
    } else {
      const staff = await staffDB.getById({ id: req.id });
      if (!staff) {
        log.info(`[${C}], [${F}], Staff Id [${req.id}], No Staff Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      clientId = staff.clientId;

      const notices = await noticeDB.getByClientId({ clientId });
      const staffLinkedProps = await propertyDB.getPropsByStaffId({
        staffId: req.id,
      });

      if (notices && staffLinkedProps && staffLinkedProps.length > 0) {
        for (const notice of notices) {
          const propList = await noticeDB.getByIdFromPropertyNotice({
            noticeId: notice?.id,
          });
          if (!propList) {
            log.info(
              `[${C}], [${F}], Client Id [${clientId}], Notice Id [${notice?.id}], No Property Found`
            );
            continue;
          }

          // notice.propertyList = propList.filter((prop: { id: number }) => {
          //   return staffLinkedProps.find(
          //     (property: propertiesTypes) => property.id === prop.id
          //   );
          // });

          const propertyList = propList.filter((prop: { id: number }) => {
            return staffLinkedProps.find(
              (property: propertiesTypes) => property.id === prop.id
            );
          });

          if(propertyList.length<1) {
            continue;
          }

          notice.propertyList = propertyList;

          const noticeView = await noticeDB.getViewsByNoticeId({
            noticeId: notice?.id,
          });

          notice.views = noticeView
            ? noticeView[0]?.totalViews || 0
            : 0;
          notice.tenantViewed = noticeView.length > 0 ? noticeView?.map((v:any) => v.tenantName) : [];

          const pollOptions = await noticePollOptionDB.getPollOptionsByNoticeId({
            noticeId: notice?.id,
          });

          notice.pollOptions = pollOptions.length > 0 ? pollOptions : [];

          
          const pollResponsesPerOption = await noticePollResponseDB.getTotalResponsesByNoticeIdPerOption({
            noticeId: notice?.id,
          });

          const propertiesIds = propertyList
          .map((prop: propertiesTypes) => prop.id)
          .join(",");

          const totalTenants = await occupancyDB.getTotalActiveTenantsByPropIds({
            clientId,
            propertiesIds: propertiesIds,
          });
          
          const totalPollResponses = await noticePollResponseDB.getTotalResponsesByNoticeId({
            noticeId: notice?.id,
          });
          
          notice.totalPollResponses = totalPollResponses || 0;
          notice.totalTenants = totalTenants || 0;
          notice.pollResponsesPerOption = pollResponsesPerOption || false;

          const pollResponses = await noticePollResponseDB.getPollResponsesByNoticeId({
            noticeId: notice?.id,
          });

          if (pollResponses && pollResponses.length > 0) {
            notice.pollResponses = pollResponses;
          } else {
            notice.pollResponses = {};
          }

          list.push(notice);
        }
      }
    }

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Announcement List Sent Successfully`
    );

    return res.status(200).json({
      msg: "Announcement list has been sent successfully",
      data: list,
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

notice.ListForClientX = async (req: CustomRequest, res: Response) => {
  const C = "Notice Controller";
  const F = "ListForClientX";

  try {
    let { type, pageNum = 1 } = req.query;
    const userType = req.userType;

    let limit = 10;

    if (req.platform === CONSTANTS.TENANT_DEVICE_TYPE.WEB) limit = 0;

    log.info(`[${C}], [${F}], Type [${type}], PageNum [${pageNum}], Limit [${limit}]`);

    let list: any = [];

    let {isPartner, clientId} = await isUserPartner (Number(userType), Number(req.id));

    if (userType === CONSTANTS.USER_TYPE.CLIENT || isPartner) {
      log.info(`[${C}], [${F}], Client Id [${clientId}], ${isPartner? "Partner Requesting": "Client Requesting"}....`);

      const client = await clientDB.getById({ id: clientId });

      if (!client) {
        log.info(`[${C}], [${F}], Client Id [${clientId}], No Client Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      list = await noticeDB.getByClientIdX({ clientId, type, pageNum, limit });

      if (list) {
        for (const notice of list) {
          const propList = await noticeDB.getByIdFromPropertyNotice({
            noticeId: notice?.id,
          });
          if (!propList) {
            log.info(
              `[${C}], [${F}], Client Id [${clientId}], Notice Id [${notice?.id}], No Property Found`
            );

            notice.propertyList = [];
            continue;
          }

          notice.propertyList = propList;

          if (notice.publishedBy && Number(notice.publishedBy) === 0) {
            notice.publishedBy = client.name;
          } else if (notice.publishedBy && Number(notice.publishedBy) > 0) {
            const staff = await staffDB.getById({ id: Number(notice.publishedBy) });
            if (staff) {
              notice.publishedBy = staff.name;
            }
          }

          const noticeView = await noticeDB.getViewsByNoticeId({
            noticeId: notice?.id,
          });

          notice.views = noticeView
            ? noticeView[0]?.totalViews || 0
            : 0;
          notice.tenantViewed = noticeView.length > 0 ? noticeView?.map((v:any) => v.tenantName) : [];

          const pollOptions = await noticePollOptionDB.getPollOptionsByNoticeId({
            noticeId: notice?.id,
          });

          notice.pollOptions = pollOptions.length > 0 ? pollOptions : [];

          
          const pollResponsesPerOption = await noticePollResponseDB.getTotalResponsesByNoticeIdPerOption({
            noticeId: notice?.id,
          });

          const propertiesIds = propList
          .map((prop: propertiesTypes) => prop.id)
          .join(",");

          const totalTenants = await occupancyDB.getTotalActiveTenantsByPropIds({
            clientId,
            propertiesIds: propertiesIds,
          });
          
          const totalPollResponses = await noticePollResponseDB.getTotalResponsesByNoticeId({
            noticeId: notice?.id,
          });
          
          notice.totalPollResponses = totalPollResponses || 0;
          notice.totalTenants = totalTenants || 0;
          
          notice.pollResponsesPerOption = pollResponsesPerOption || false;

          const pollResponses = await noticePollResponseDB.getPollResponsesByNoticeId({
            noticeId: notice?.id,
          });

          if (pollResponses && pollResponses.length > 0) {
            notice.pollResponses = pollResponses;
          } else {
            notice.pollResponses = {};
          }
        }
      }
    } else {
      const staff = await staffDB.getById({ id: req.id });
      if (!staff) {
        log.info(`[${C}], [${F}], Staff Id [${req.id}], No Staff Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      clientId = staff.clientId;

      const notices = await noticeDB.getByClientIdX({ clientId, type, pageNum, limit });

      const staffLinkedProps = await propertyDB.getPropsByStaffId({
        staffId: req.id,
      });

      if (notices && staffLinkedProps && staffLinkedProps.length > 0) {
        for (const notice of notices) {
          const propList = await noticeDB.getByIdFromPropertyNotice({
            noticeId: notice?.id,
          });
          if (!propList) {
            log.info(
              `[${C}], [${F}], Client Id [${clientId}], Notice Id [${notice?.id}], No Property Found`
            );
            continue;
          }

          const propertyList = propList.filter((prop: { id: number }) => {
            return staffLinkedProps.find(
              (property: propertiesTypes) => property.id === prop.id
            );
          });

          if(propertyList.length<1) {
            continue;
          }

          notice.propertyList = propertyList;

          if (notice.publishedBy && Number(notice.publishedBy) === 0) {
            const client = await clientDB.getById({ id: clientId });
            notice.publishedBy = client.name;
          } else if (notice.publishedBy && Number(notice.publishedBy) > 0) {
            const staff = await staffDB.getById({ id: Number(notice.publishedBy) });
            if (staff) {
              notice.publishedBy = staff.name;
            }
          }

          const noticeView = await noticeDB.getViewsByNoticeId({
            noticeId: notice?.id,
          });

          notice.views = noticeView
            ? noticeView[0]?.totalViews || 0
            : 0;
          notice.tenantViewed = noticeView.length > 0 ? noticeView?.map((v:any) => v.tenantName) : [];

          const pollOptions = await noticePollOptionDB.getPollOptionsByNoticeId({
            noticeId: notice?.id,
          });

          notice.pollOptions = pollOptions.length > 0 ? pollOptions : [];

          
          const pollResponsesPerOption = await noticePollResponseDB.getTotalResponsesByNoticeIdPerOption({
            noticeId: notice?.id,
          });

          const propertiesIds = propertyList
          .map((prop: propertiesTypes) => prop.id)
          .join(",");

          const totalTenants = await occupancyDB.getTotalActiveTenantsByPropIds({
            clientId,
            propertiesIds: propertiesIds,
          });
          
          const totalPollResponses = await noticePollResponseDB.getTotalResponsesByNoticeId({
            noticeId: notice?.id,
          });
          
          notice.totalPollResponses = totalPollResponses || 0;
          notice.totalTenants = totalTenants || 0;
          notice.pollResponsesPerOption = pollResponsesPerOption || false;

          const pollResponses = await noticePollResponseDB.getPollResponsesByNoticeId({
            noticeId: notice?.id,
          });

          if (pollResponses && pollResponses.length > 0) {
            notice.pollResponses = pollResponses;
          } else {
            notice.pollResponses = {};
          }

          list.push(notice);
        }
      }
    }

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Type [${type}], PageNum [${pageNum}], Limit [${limit}], Announcement List Sent Successfully`
    );

    return res.status(200).json({
      msg: "Announcement list has been sent successfully",
      data: list,
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

notice.ListForTenant = async (req: CustomRequest, res: Response) => {
  const C = "Notice Controller";
  const F = "ListForTenant";

  try {
    const tenantId = req.id;
    const isEvicted = req.isEvicted;
    const clientId = req.clientId || 0;

    log.info(`[${C}], [${F}], Tenant Id [${tenantId}]`);

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

    if (!tenant) {
      log.info(`[${C}], [${F}], Tenant Id [${tenantId}], No Tenant Found`);
      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }

    let occupancy = await occupancyDB.getByTenantId({ tenantId });

    if (isEvicted) {
      occupancy = await moveOutDB.getMovedOutTenants({
        tenantId: tenant.id,
      });
    }
    if(clientId >0) {
      occupancy = await occupancyDB.getByTenantIdAndClientId({ tenantId, clientId });
      if(isEvicted) {
        occupancy = await moveOutDB.getByTenantIdAndClientId({
          clientId, tenantId: tenant.id,
        });
      }
    }

    if (!occupancy) {
      log.info(`[${C}], [${F}], Tenant Id [${tenantId}], No Occupancy Found`);
      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }

    const list = await noticeDB.getByPropId({ propId: occupancy?.propId });

    if (!list) {
      log.info(`[${C}], [${F}], Tenant Id [${tenantId}], No Notice Found`);
      return res.status(200).json({
        msg: "Announcement list has been sent successfully",
        data: false,
        isSuccess: true,
      });
    }

    if (list && list.length > 0) {
      for( let notice of list) {
        const pollOptions = await noticePollOptionDB.getPollOptionsByNoticeId({
          noticeId: notice?.id,
        });
        notice.pollOptions = pollOptions.length > 0 ? pollOptions : [];

        const pollResponse = await noticePollResponseDB.getPollResponsesByNoticeIdAndTenantId({
          noticeId: notice?.id,
          tenantId: tenantId,
        });

        //log.info(`Poll Response [${tenantId}: ${JSON.stringify(pollResponse)}]`);

        if (pollResponse) {
          notice.pollResponses = pollResponse;
        } else {
          notice.pollResponses = false;
        }
        
        if (notice.publishedBy && Number(notice.publishedBy) === 0) {
          const client = await clientDB.getById({ id: notice.clientId });
          if (client) {
            notice.publishedBy = client.name;
          }
        } else if (notice.publishedBy && Number(notice.publishedBy) > 0) {
          const staff = await staffDB.getById({ id: Number(notice.publishedBy) });
          if (staff) {
            notice.publishedBy = staff.name;
          }
        }
      }
    }

    log.info(
      `[${C}], [${F}], Tenant Id [${tenantId}], Notice List Sent Successfully`
    );

    return res.status(200).json({
      msg: "Announcement list has been sent successfully",
      data: list,
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

notice.Delete = async (req: CustomRequest, res: Response) => {
  const C = "Notice Controller";
  const F = "Delete";

  try {
    const { noticeId } = req.body;
    const userType = req.userType;
    let id = req.id;

    log.info(
      `[${C}], [${F}], Id [${id}], Notice Id [${noticeId}], Deleting Announcement....`
    );

    let {isPartner, clientId} = await isUserPartner (Number(userType), Number(req.id));

    if (userType === CONSTANTS.USER_TYPE.CLIENT || isPartner) {
      log.info(`[${C}], [${F}], Client Id [${clientId}], ${isPartner? "Partner Requesting": "Client Requesting"}....`);

      const client = await clientDB.getById({ id: clientId });

      if (!client) {
        log.info(`[${C}], [${F}], Client Id [${clientId}], No Client Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

    } else {
      const staff = await staffDB.getById({ id: req.id });
      if (!staff) {
        log.info(`[${C}], [${F}], Staff Id [${req.id}], No Staff Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }
    }

    const notice = await noticeDB.getById({ id: noticeId });

    if (!notice) {
      log.info(
        `[${C}], [${F}], Announcement Id [${noticeId}], No Announcement Found`
      );
      return res
        .status(400)
        .json({ msg: "No Announcement Found", isSuccess: false });
    }

    let msg = "Announcement Deleted Successsfully";

    await noticeDB.removeFromPropertyList({ noticeId: noticeId });

    await noticeDB.remove({ noticeId: noticeId });
    if(notice.type === CONSTANTS.NOTICE_TYPE.POLL) {
      await noticePollResponseDB.remove({ noticeId: noticeId });
      await noticePollOptionDB.remove({ noticeId: noticeId });
    }

    log.info(
      `[${C}], [${F}], Announcement Id [${noticeId}], Announcement Deleted Successsfully}`
    );

    return res.status(200).json({
      msg: msg,
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);

    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

notice.AddNoticePollResponse = async (req: CustomRequest, res: Response) => {
  const C = "Notice Controller";
  const F = "AddNoticePollResponse";

  try {
    const { noticeId, optionId } = req.body;

    let tenantId = req.id;

    log.info(
      `[${C}], [${F}], Tenant Id [${tenantId}], Notice Id [${noticeId}], Option Id [${optionId}]`
    );

    let userType = req.userType;

    if (!noticeId || !optionId || !tenantId) {
      log.info(
        `[${C}], [${F}], Tenant Id [${tenantId}], Notice Id [${noticeId}], Option Id [${optionId}], Invalid Request`
      );
      return res.status(400).json({
        msg: "Invalid request",
        isSuccess: false,
      });
    }

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

    if (!tenant) {
      log.info(`[${C}], [${F}], Tenant Id [${tenantId}], No Tenant Found`);
      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }

    const occupancy = await occupancyDB.getByTenantId({ tenantId });

    if (!occupancy) {
      log.info(`[${C}], [${F}], Tenant Id [${tenantId}], No Occupancy Found`);
      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }

    await noticePollResponseDB.addPollResponse({
      clientId: occupancy?.clientId,
      tenantId: tenantId,
      optionId: optionId,
    });

    log.info(
      `[${C}], [${F}], Tenant Id [${tenantId}], Notice Id [${noticeId}], Option Id [${optionId}], Poll Response Recorded Successfully`
    );

    return res.status(200).json({
      msg: "Poll response recorded successfully",
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);

    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
}

notice.GetTemplate = async (req: CustomRequest, res: Response) => {
  const C = "Notice Controller";
  const F = "GetTemplate";

  try {
    // let clientId = req.id;
    const userType = req.userType;

    let list: any = [];

    let {isPartner, clientId} = await isUserPartner (Number(userType), Number(req.id));

    if (userType === CONSTANTS.USER_TYPE.CLIENT || isPartner) {
      log.info(`[${C}], [${F}], Client Id [${clientId}], ${isPartner? "Partner Requesting": "Client Requesting"}....`);

      const client = await clientDB.getById({ id: clientId });

      if (!client) {
        log.info(`[${C}], [${F}], Client Id [${clientId}], No Client Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }
    } else {
      const staff = await staffDB.getById({ id: req.id });
      if (!staff) {
        log.info(`[${C}], [${F}], Staff Id [${req.id}], No Staff Found`);
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      clientId = staff.clientId;

    }

const categories = [
  { label: 'All', value: 'all' },
  { label: 'Festival', value: 'festival' },
  { label: 'Maintenance', value: 'maintenance' },
  { label: 'Rules', value: 'rules' }
];
 
const data = {
  festival: [
    {
      id: 'festival-1',
      title: 'Happy Diwali',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May the glow of diyas fill your heart with happiness and light up your life with peace and prosperity.</p>
        <p>Let’s celebrate the victory of light over darkness and good over evil with love, laughter, and positivity.</p>
        <p>✨ Wishing you and your family a Diwali full of joy, success, and beautiful memories.</p>
        <p><em>- Property Management Team</em></p>`,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-2',
      title: 'Happy Holi',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>Splash into the colors of happiness! 💦</p>
        <p>May your days be filled with bright moments, your heart with sweet memories, and your life with endless joy.</p>
        <p>Let’s celebrate this Holi with love, laughter, and togetherness — because life is more colorful when we share it with others.</p>
        <p>Wishing you a truly vibrant and joyous Holi! 🌈🥳</p>
        <p><em>- Property Management Team</em></p>`,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-3',
      title: 'Happy Lohri',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May the fire of Lohri burn away all your troubles and fill your life with warmth and joy.</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-4',
      title: 'Happy Makar Sankranti',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>Wishing you a harvest of happiness and success this Makar Sankranti!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-5',
      title: 'Happy Pongal',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>Pongalo Pongal! May your days be as sweet as the sugarcane and as bright as the sun.</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-6',
      title: 'Happy Navratri',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May Goddess Durga bless you with strength, wisdom, and prosperity. Happy Navratri!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-7',
      title: 'Happy Dussehra',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May this Dussehra bring you victory over your challenges and fill your life with joy and prosperity.</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-8',
      title: 'Happy Bhai Dooj',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>On this auspicious occasion of Bhai Dooj, may the bond between brothers and sisters be strengthened. Wishing you all a day filled with love and joy!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-9',
      title: 'Happy Durga Puja',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May Maa Durga fill your life with colour, energy, and positivity. Shubho Durga Puja!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-10',
      title: 'Happy Ganesh Chaturthi',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May Lord Ganesha remove all obstacles from your life and bless you with happiness and wisdom. Ganpati Bappa Morya!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-11',
      title: 'Happy Janamashtami',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May Lord Krishna fill your life with love, laughter, and divine blessings. Happy Janmashtami!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-12',
      title: 'Happy Raksha Bandhan',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>A bond of love and protection, forever strong. Happy Raksha Bandhan!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-13',
      title: 'Happy Independence Day',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>Wishing you a joyous Independence Day! Let's celebrate the spirit of freedom and unity.</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-14',
      title: 'Happy Republic Day',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>On this Republic Day, let's pledge to uphold the values of justice, liberty, and equality. Happy Republic Day!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-15',
      title: 'Happy Christmas',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>Wishing you a Merry Christmas filled with joy, love, and peace!</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-16',
      title: 'Happy New Year',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>Wishing you a prosperous and joyful New Year! May this year bring new opportunities and success.</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
    {
      id: 'festival-17',
      title: 'Eid Mubarak',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <p>May this special day bring peace, prosperity, and happiness to you and your loved ones.</p>
        <p>Wishing you a joyous celebration and blessings throughout the year ahead.</p>
        <p><em>- Property Management Team</em></p>
      `,
      category: 'festival',
      hasImage: false,
    },
  ],
  maintenance: [
    {
      id: 'maintenance-1',
      title: 'Water Supply Interruption',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <h3>🚰 Water Supply Maintenance Notice</h3>
        <p><strong>Important Update:</strong> Temporary water supply interruption scheduled for essential pipeline maintenance.</p>
        <p><u>Schedule Details:</u></p>
        <ul>
          <li>📅 <strong>Date:</strong> October 20th</li>
          <li>⏰ <strong>Time:</strong> 9 AM to 4 PM</li>
          <li>📍 <strong>Affected:</strong> Entire property</li>
        </ul>
        <p><strong>⚠️ Important Instructions:</strong></p>
        <ul>
          <li>💧 Store sufficient water for essential needs</li>
          <li>🚫 Avoid using washing machines during this period</li>
          <li>📞 Contact maintenance for emergency requirements</li>
        </ul>
        <p>We apologize for any inconvenience and appreciate your cooperation.</p>
      `,
      category: 'maintenance',
      hasImage: false,
    },
    {
      id: 'maintenance-2',
      title: 'Elevator Maintenance',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <h3>🛗 Scheduled Elevator Maintenance</h3>
        <p>Please be informed about the scheduled maintenance for Elevator A:</p>
        <p><u>Maintenance Schedule:</u></p>
        <ul>
          <li>📅 <strong>Date:</strong> October 25th</li>
          <li>⏰ <strong>Time:</strong> 10 AM to 2 PM</li>
          <li>🔧 <strong>Elevator:</strong> Elevator A (Left side)</li>
        </ul>
        <p><strong>During Maintenance:</strong></p>
        <ul>
          <li>✅ Use <strong>Elevator B</strong> (Right side)</li>
          <li>📱 Allow extra time for elevator usage</li>
          <li>🚫 Elevator A will be temporarily unavailable</li>
        </ul>
        <p>We apologize for any inconvenience caused and thank you for your understanding.</p>
      `,
      category: 'maintenance',
      hasImage: false,
    },
  ],
  rules: [
    {
      id: 'rules-1',
      title: 'Visitor Policy Update',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <h3>👥 Updated Visitor Policy</h3>
        <p><strong>Effective immediately:</strong> New visitor registration procedures for enhanced security.</p>
        <p><u>New Policy Details:</u></p>
        <ul>
          <li>📝 <strong>All visitors must register</strong> at security desk after 9 PM</li>
          <li>🛌 <strong>Overnight guests</strong> need prior management approval</li>
          <li>📋 Valid ID proof required for all visitors</li>
          <li>⏰ Maximum 3 overnight stays per month</li>
        </ul>
        <p><strong>Why this update?</strong></p>
        <ul>
          <li>✅ Enhanced security for all residents</li>
          <li>✅ Better monitoring of premises</li>
          <li>✅ Improved safety measures</li>
        </ul>
        <p>Please cooperate for everyone's safety and security.</p>
      `,
      category: 'rules',
      hasImage: false,
    },
    {
      id: 'rules-2',
      title: 'Parking Regulations',
      message: `
        <p><strong>Dear tenants,</strong></p>
        <h3>🅿️ Parking Regulations Reminder</h3>
        <p>Important reminder about our parking policies to ensure smooth operations:</p>
        <p><u>Parking Rules:</u></p>
        <ul>
          <li>🚗 <strong>Park only in your assigned spots</strong></li>
          <li>💰 <strong>Unauthorized parking:</strong> ₹500 fine per occurrence</li>
          <li>👥 <strong>Visitor parking:</strong> Designated area only</li>
          <li>⏰ <strong>Time limit:</strong> 2 hours for visitor parking</li>
        </ul>
        <p><strong>Additional Guidelines:</strong></p>
        <ul>
          <li>✅ Display parking permit clearly</li>
          <li>🚫 No parking in fire lanes or emergency zones</li>
          <li>📞 Report parking violations to security</li>
        </ul>
        <p>Let's maintain order and convenience for all residents.</p>
      `,
      category: 'rules',
      hasImage: false,
    },
  ],
};
 
    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Announcement List Sent Successfully`
    );

    return res.status(200).json({
      msg: "Announcement templates sent successfully",
      categories,
      data,
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

export default notice;
