import { Types } from 'mongoose';

import { Fast2sms } from '@/modules/communication/fast2sms/fast2sms.model';
import {
  buildQuery,
  cloneTemplatesToCompany,
  fetchSuperAdminTemplates,
  getExistingTemplateIds,
  syncFast2smsTemplates,
} from './fast2sms.helper';
import { Company } from '@/modules/company/company.model';
import { ApiError } from '@/shared/utils/errors';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import { getObjectId } from '@/shared/utils/commonHelper';
import { Fast2smsRow } from './fast2sms.interface';

const { Fast2smsResponseCodes } = responseCodes;
export const queryFast2smss = async (
  filter: Record<string, string> = {},
  options = {},
  companyId?: Types.ObjectId | string,
) => {
  if (!companyId) throw new Error('companyId required');
  const objectCompanyId = getObjectId(companyId);

  const creds = await syncFast2smsTemplates(
    Company,
    companyId,
    Fast2smsResponseCodes.WHATSAPP_ERROR,
  );

  if (!creds?.accessToken) {
    // No creds: clone missing super admin templates to this company
    const superAdminTemplates = await fetchSuperAdminTemplates(Fast2sms);
    const existingTemplateIds = await getExistingTemplateIds(
      objectCompanyId,
      Fast2sms,
    );

    const templatesToClone = superAdminTemplates.filter(
      (t) => !existingTemplateIds.includes(t.templateId),
    );

    await cloneTemplatesToCompany(objectCompanyId, templatesToClone, Fast2sms);

    // Query cloned default templates
    const query = {
      ...buildQuery(filter, objectCompanyId),
      isDefault: true,
    };

    const fast2sms = await Fast2sms.paginate(query, options);

    return { ...fast2sms, fast2sms: creds };
  } else {
    // Creds found: fetch company-specific templates (isDefault: false)
    const query = {
      ...buildQuery(filter, objectCompanyId),
      isDefault: false,
    };

    const fast2sms = await Fast2sms.paginate(query, options);

    return { ...fast2sms, fast2sms: creds };
  }
};

export const updateTemplate = async (
  id: string,
  data: Record<string, unknown>,
) => {
  await Fast2sms.findOneAndUpdate({ _id: id }, { $set: data }, { new: true });

  return true;
};

export const addFast2smsCreds = async (
  companyId: Types.ObjectId,
  data: Record<string, unknown>,
) => {
  const updateFields: Record<string, unknown> = {};
  Object.keys(data).forEach((key) => {
    updateFields[`fast2sms.${key}`] = data[key];
  });

  const updateCompany = await Company.findByIdAndUpdate(
    companyId,
    { $set: updateFields },
    { new: true },
  );

  if (!updateCompany)
    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Company not found',
      true,
      '',
      Fast2smsResponseCodes.COMPANY_NOT_FOUND,
    );
};

export async function bulkUpsertFast2smsTemplates(
  companyId: Types.ObjectId,
  rows: Fast2smsRow,
) {
  if (!rows.templates.length) return;

  try {
    // Fetch senderId from company model
    const company =
      await Company.findById(companyId).select('fast2sms.senderId');
    const companySenderId = company?.fast2sms?.senderId?.trim();

    if (!companySenderId) {
      console.error('Company senderId not found, aborting bulk upsert');
      throw new ApiError(
        defaultStatus.INTERNAL_SERVER_ERROR,
        'Company Fast2sms credentials not found',
        true,
        '',
        Fast2smsResponseCodes.COMPANY_SENDER_ID_NOT_FOUND,
      );
    }

    // Filter templates where sender_id matches company senderId
    const filteredTemplates = rows.templates.filter((row) => {
      const rowSenderId = row.sender_id?.trim() || '';
      if (rowSenderId !== companySenderId) {
        console.error(
          `Skipping template with sender_id '${rowSenderId}' which does not match company senderId '${companySenderId}'`,
        );
        return false;
      }
      return true;
    });

    if (filteredTemplates.length === 0)
      throw new ApiError(
        defaultStatus.INTERNAL_SERVER_ERROR,
        'No templates matched company senderId',
        true,
        '',
        Fast2smsResponseCodes.COMPANY_SENDER_ID_NOT_FOUND,
      );

    const bulkOps = filteredTemplates.map((row) => {
      const templateId = String(row.message);
      const approvedMessage = row.approved_message;
      const variableCount = row.variable_count
        ? String(row.variable_count)
        : undefined;
      return {
        updateOne: {
          filter: { companyId, templateId },
          update: {
            $set: {
              companyId,
              templateId,
              message: approvedMessage,
              variableCount: variableCount,
              isDefault: false,
            },
          },
          upsert: true,
        },
      };
    });

    if (bulkOps.length === 0) {
      console.log('No templates matched company senderId, nothing to upsert');
      return false;
    }

    await Fast2sms.bulkWrite(bulkOps);
    return true;
  } catch (err) {
    console.error(err);
    if (err instanceof ApiError) throw err;
    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to bulk upsert fast2sms templates',
      true,
      '',
      Fast2smsResponseCodes.BULK_UPSERT_ERROR,
    );
  }
}
