import { Company } from '@/modules/company/company.model';
import { CommonTypes, Status } from '@/shared/constants/enum.constant';
import { ApiError } from '@/shared/utils/errors';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import { Types } from 'mongoose';

export const getFast2smsCreds = async (
  companyId: string | Types.ObjectId,
  model,
) => {
  const company = await model.findById(companyId).select('fast2sms smsCredit ');

  const hasValidValues = Object.values(company.fast2sms).some(
    (value: string) => value && value.length > 0,
  );

  if (!company.fast2sms || !hasValidValues)
    return {
      smsCredit: company.smsCredit,
    };

  return { ...company.fast2sms, smsCredit: company.smsCredit };
};

export const getSuperAdminCompanyId = async () => {
  const superAdmin = await Company.findOne({
    companyType: CommonTypes.SUPERADMIN,
  }).select('_id fast2sms whatsapp');
  return { id: superAdmin._id, fast2sms: superAdmin.fast2sms, whatsapp: superAdmin.whatsapp };
};

export const syncFast2smsTemplates = async (
  companyModel,
  companyId: string | Types.ObjectId,
  responseCode,
) => {
  try {
    if (!companyId) return;
    let superAdminCreds, creds;

    creds = await getFast2smsCreds(companyId, companyModel);

    if (!creds?.accessToken) {
      superAdminCreds = await getSuperAdminCompanyId();
      creds = {
        ...creds,
        ...superAdminCreds.fast2sms,
      };
    }

    return creds;
  } catch (error) {
    if (error instanceof ApiError) throw error;
    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to sync fast2sms templates',
      true,
      '',
      responseCode,
    );
  }
};

// Fetch super admin templates with isDefault: true
export const fetchSuperAdminTemplates = async (model) => {
  const superAdmin = await getSuperAdminCompanyId();
  return await model.find({ companyId: superAdmin.id, isDefault: true });
};

// Check already cloned templateIds for a company
export async function getExistingTemplateIds(companyId: Types.ObjectId, model) {
  return await model.find({ companyId }).distinct('templateId');
}

// Clone missing templates for a company
export const cloneTemplatesToCompany = async (
  companyId: Types.ObjectId,
  templatesToClone,
  model,
) => {
  if (!templatesToClone.length) return;

  const activeTemplates = templatesToClone.filter(
    (template) => template.status !== Status.INACTIVE,
  );

  if (activeTemplates.length === 0) return;

  const clones = activeTemplates.map((template) => {
    const t = template.toObject ? template.toObject() : template;
    delete t._id;
    return {
      ...t,
      companyId,
      isDefault: true,
    };
  });

  await model.insertMany(clones);
};

// Compose query including search and companyId conditions
export function buildQuery(
  filter: Record<string, string>,
  companyId: Types.ObjectId,
) {
  const { search, ...rest } = filter;
  return {
    ...rest,
    ...(search ? { name: { $regex: search, $options: 'i' } } : {}),
    companyId,
  };
}
