import { catchAsync, pick } from '@/shared/utils';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import { Request, Response } from 'express';
import * as MakanifySitesService from '@/modules/makanifySites/makanifySites.service';
import { createContact } from '../contacts/contacts.service';
import { querySource } from '../master/constructionStatus/source/source.service';
import { LeadSource } from './makanifySites.constants';
import { prepareContactBody, prepareLeadBody } from './makanifySites.utils';
import { getObjectId } from '@/shared/utils/commonHelper';
import {
  queryPrimaryProperties,
  QueryResult,
} from '../individualProperties/individualProperties.service';
import { createLead as createLeadService } from '@/modules/lead/lead.service';
import { queryLeadStages } from '../master/leadStage/leadStage.service';
import { LeadStageStatus } from '../master/leadStage/leadStage.constant';
import { MakanifySites } from './makanifySites.model';
import { Types } from 'mongoose';
import { IPropertyDoc } from '../individualProperties/individualProperties.interface';
import { IContact } from '../contacts/contacts.interface';
import { queryUsers } from '../user/user.service';
import { NewCreatedLead } from '../lead/lead.interface';

const { MakanifySitesResponseCodes, ContactResponseCodes } = responseCodes;

export const createSite = catchAsync(async (req: Request, res: Response) => {
  const site = await MakanifySitesService.createSite(req.body);

  res.success(
    site,
    MakanifySitesResponseCodes.SUCCESS,
    'Sites Created Successfully',
  );
});
export const fetchSite = catchAsync(async (req: Request, res: Response) => {
  const { subdomain } = pick(req, ['subdomain']);
  const { _id } = subdomain;

  const site = await MakanifySitesService.fetchSite(_id);
  res.success(
    site,
    MakanifySitesResponseCodes.MAKANIFY_SITES_FETCHED,
    'Website Data Fetched  Successfully',
  );
});
export const fetchListings = catchAsync(async (req: Request, res: Response) => {
  let {
    subdomain: {
      company: { _id: companyId },
    },
  } = pick(req, ['subdomain']);
  let filter = pick(req.query, [
    'propertyType',
    'subcategory',
    'configuration',
    'carpetArea',
    'listingType',
    'price',
    '_id',
    'search',
  ]);
  filter.companyId = companyId;

  const options = pick(req.query, [
    'sort',
    'limit',
    'page',
    'populate',
    'fields',
  ]);

  const listings = await MakanifySitesService.fetchListings(filter, options);
  res.success(
    listings,
    MakanifySitesResponseCodes.MAKANIFY_SITES_FETCHED,
    'Website Data Fetched  Successfully',
  );
});

export const isSiteCreated = catchAsync(async (req: Request, res: Response) => {
  const { subdomains } = pick(req.query, ['subdomains']);
  const site = await MakanifySitesService.isSiteCreated(subdomains);
  res.success(
    site,
    MakanifySitesResponseCodes.MAKANIFY_SITES_FETCHED,
    'Website Data Fetched Successfully',
  );
});

export const fetchHomepage = catchAsync(async (req: Request, res: Response) => {
  const { subdomain } = pick(req, ['subdomain']);
  const { _id } = subdomain;

  const site = await MakanifySitesService.fetchHomepage(_id);
  res.success(
    site,
    MakanifySitesResponseCodes.MAKANIFY_SITES_FETCHED,
    'Website Data Fetched  Successfully',
  );
});

export const fetchFilters = catchAsync(async (req: Request, res: Response) => {
  // let {
  //   subdomain: {
  //     company: { _id: companyId },
  //   },
  // } = pick(req, ['subdomain']);
  const { category, subcategory } = pick(req.query, [
    'category',
    'subcategory',
  ]);
  const filters = await MakanifySitesService.fetchFilters({
    categoryId: category,
    subCategoryId: subcategory,
  });
  res.success(
    filters,
    MakanifySitesResponseCodes.MAKANIFY_SITES_FETCHED,
    'Website Data Fetched  Successfully',
  );
});

export const createLead = catchAsync(async (req: Request, res: Response) => {
  // let {
  //   subdomain: {
  //     company: { _id: companyId },
  //   },
  // } = pick(req, ['subdomain']);
  //** Steps to execute one by one
  // * 1. Create contacts first with the provided details.
  // * 2. fetch Source & Lead stage Id.
  // * 3. fetch assigned to Id from website config.
  // * 4. fetch buying preference & other details from provided productId.
  // * 5. create lead with the details */

  /** To Collect Lead details required following things
   * 1. Select Buying Type according to product
   * 2. Select Lead stage
   */

  const source = await querySource({
    search: LeadSource,
  });
  const { results: sourceResults } = source;
  const sourceId = sourceResults?.[0]?.id;
  const property = (await queryPrimaryProperties(
    {
      _id: getObjectId(req.body.listingId),
    },
    {
      fields: 'companyId listingType project subcategory propertyType',
      populate: 'project',
    },
  )) as QueryResult<IPropertyDoc & { companyId: { id: string } }>;

  const { results } = property;
  const listing = results?.[0];
  const userInfo = await queryUsers(
    { company: listing.companyId },
    { fields: 'id firstName lastName' },
  );
  const { results: userResults } = userInfo;
  const assignedBy = userResults?.[0]?.id;
  const leadStage = await queryLeadStages(
    {
      stageName: LeadStageStatus.newLead,
      company: getObjectId(listing.companyId.id),
    },
    {},
  );
  const { results: leadStageResults } = leadStage;
  const siteInfo = await MakanifySites.findOne({
    company: getObjectId(listing.companyId.id),
  });
  const leadStageId = leadStageResults?.[0]?.id;
  const contactBody = prepareContactBody({
    ...req.body,
    source: sourceId,
    company: listing.companyId.id,
  });
  const contact = await createContact(contactBody).catch((err) => err);
  let contactInfo: IContact & { id: Types.ObjectId };
  if (contact.errorCode === ContactResponseCodes.CONTACT_ALREADY_EXISTS)
    contactInfo = contact.data;
  else contactInfo = contact;

  const leadBody = prepareLeadBody({
    ...req.body,
    listing,
    contact: contactInfo.id,
    company: listing.companyId,
    source: sourceId,
    contactInfo,
    leadStageId,
    assignedTo: siteInfo.userId,
    assignedBy,
  });
  const lead = await createLeadService(leadBody as NewCreatedLead).catch(
    (err) => err,
  );
  res.success(
    lead,
    MakanifySitesResponseCodes.MAKANIFY_LEAD_CREATED,
    'Lead Created Successfully',
  );
});
