import { render } from '@vue-email/render';
import Template1 from '@/lib/email/templates/Template1.vue';
import { forEachAsync, groupBy, last } from 'es-toolkit';

export default function useSendHandoverEmail(filter, templateName) {
  const products = ref(null);
  const contents = ref(null);
  const isSending = ref(false); 
  const emailTemplate = ref(null);
  const templateNameRef = toRef(templateName);

  watch(templateNameRef, async () => {
    await populateEmailTemplate();
    populateProducts();
  })
  
  const { 
    $dayjs,
    $getdata,
    $insertapi,
    $numtoString,
    $numberToVietnamese,
    $numberToVietnameseCurrency,
    $formatDateVN,
    $paymentQR,
    $getFirstAndLastName,
    $snackbar,
    $store,
  } = useNuxtApp();

  const buildQrHtml = (url) => `
    <div style="text-align: center; margin-top: 16px">
      <img
        src="${url}"
        alt="VietQR"
        width="500"
        style="display: inline-block"
      />
    </div>
  `;
  
  const formatDateVNText = (input, { withTime = false, withSeconds = false } = {}) => {
    if (!input) return '';

    const date = new Date(input);
    if (isNaN(date.getTime())) return '';

    const pad = (n) => String(n).padStart(2, '0');

    const day = pad(date.getDate());
    const month = pad(date.getMonth() + 1);
    const year = date.getFullYear();

    let result = `${day} tháng ${month} năm ${year}`;

    if (withTime) {
      const hours = pad(date.getHours());
      const minutes = pad(date.getMinutes());
      result += ` ${hours}:${minutes}`;

      if (withSeconds) {
        const seconds = pad(date.getSeconds());
        result += `:${seconds}`;
      }
    }

    return result;
  };
  
  function buildContentPayment(product) {
    const {
      trade_code, 
      prdbk__transaction__customer__type__code: customerType, 
      prdbk__transaction__customer__code: customerCode,
      prdbk__transaction__customer__fullname: customerName,
      prdbk__transaction__resvtxn__psh__cycle: cycle,
    } = product;

    if (customerType?.toLowerCase() === 'cn') {
      if (customerName.length < 14) {
        return `${trade_code} ${customerCode} ${customerName} TT ${cycle == 0 ? 'Dat Coc' : `Dot ${cycle}`}`;
      } else {
        return `${trade_code} ${customerCode} ${$getFirstAndLastName(customerName)} TT ${cycle == 0 ? 'Dat Coc' : `Dot ${cycle}`}`;
      }
    } else return `${trade_code} ${customerCode} TT ${cycle == 0 ? 'Dat Coc' : `Dot ${cycle}`}`;
  }

  function sanitizeContentPayment(text, maxLength = 80) {
    if (!text) return '';

    return text
      .normalize('NFD') // bỏ dấu tiếng Việt
      .replace(/[\u0300-\u036f]/g, '')
      .replace(/[^a-zA-Z0-9 _-]/g, '') // bỏ ký tự lạ
      .replace(/\s+/g, ' ')
      .trim()
      .slice(0, maxLength);
  }

  function addDays(days) {
    const today = new Date();
    today.setDate(today.getDate() + days);
    return today;
  }
  
  function replaceTemplateVars(html, product) {
    const { 
      trade_code,
      number_of_floors,
      elpro__current_area,
      prdbk__transaction__date,
      prdbk__transaction__customer__code: cusCode,
      prdbk__transaction__customer__fullname: cusName,
      prdbk__transaction__customer__legal_code: cusLegalCode,
      prdbk__transaction__customer__issued_date: cusIssuedDate,
      prdbk__transaction__customer__type__code: cusTypeCode,
      prdbk__transaction__customer__contact_address: cusContactAddress,
      prdbk__transaction__customer__address: cusAddress,
      prdbk__transaction__customer__phone: cusPhone,
      prdbk__transaction__customer__email: cusEmail,
      prdbk__transaction__customer__orgncust__bank_account: orgBankAccount,
      prdbk__transaction__customer__orgncust__bank_name: orgBankName,
      prdbk__transaction__customer__orgncust__orgrep__people__fullname: orgPeopleFullname,
      prdbk__transaction__customer__orgncust__orgrep__relation__name: orgRelationName,
      prdbk__transaction__co_op__people__fullname: coopFullname,
      prdbk__transaction__co_op__people__legal_code: coopLegalCode,
      prdbk__transaction__co_op__people__address: coopAddress,
      prdbk__transaction__co_op__people__contact_address: coopContactAddress,
      prdbk__transaction__co_op__people__phone: coopPhone,
      prdbk__transaction__co_op__people__email: coopEmail,
      prdbk__transaction__resvtxn__psh__amount: amount,
      prdbk__transaction__resvtxn__psh__paid_amount: paid_amount,
      prdbk__transaction__resvtxn__psh__penalty_remain: penalty_remain,
      prdbk__transaction__resvtxn__psh__remain_amount: remain_amount,
      prdbk__transaction__resvtxn__psh__cycle: cycle,
      prdbk__transaction__resvtxn__psh__to_date: to_date,
    } = product;

    const getName = () => {
      if (cusTypeCode === 'CN') {
        return cusName.length < 14 ? cusName : $getFirstAndLastName(cusName);
      }
      return '';
    }

    const issuedDate = $dayjs(cusIssuedDate);
    const issued_date_d = issuedDate.date();
    const issued_date_m = issuedDate.month() + 1;
    const issued_date_y = issuedDate.year();
    
    let replaced = html
      .replaceAll('[day]', String(new Date().getDate()).padStart(2, '0'))
      .replaceAll('[month]', String(new Date().getMonth() + 1).padStart(2, '0'))
      .replaceAll('[year]', new Date().getFullYear())
      .replaceAll('[product.trade_code]', trade_code)
      .replaceAll('[product.elpro__current_area]', elpro__current_area)
      .replaceAll('[product.elpro__current_area_in_words]', $numberToVietnameseCurrency(elpro__current_area))
      .replaceAll('[product.number_of_floors]', number_of_floors)
      .replaceAll('[customer.name]', cusName)
      .replaceAll('[customer.code]', cusCode)
      .replaceAll('[customer.fullname]', cusName)
      .replaceAll('[customer.legal_code]', cusLegalCode)
      .replaceAll('[customer.address]', cusAddress)
      .replaceAll('[customer.contact_address]', cusContactAddress || cusAddress || '')
      .replaceAll('[customer.phone]', cusPhone)
      .replaceAll('[customer.email]', cusEmail)
      .replaceAll('[issued_date_d]', issued_date_d)
      .replaceAll('[issued_date_m]', issued_date_m)
      .replaceAll('[issued_date_y]', issued_date_y)
      .replaceAll('[customer.orgncust.bank_account]', orgBankAccount)
      .replaceAll('[customer.orgncust.bank_name]', orgBankName)
      .replaceAll('[customer.orgncust.orgrep.people.fullname]', orgPeopleFullname)
      .replaceAll('[customer.orgncust.orgrep.relation.name]', orgRelationName)
      .replaceAll('[co_op.people.fullname]', coopFullname)
      .replaceAll('[co_op.people.legal_code]', coopLegalCode)
      .replaceAll('[co_op.people.address]', coopAddress)
      .replaceAll('[co_op.people.contact_address]', coopContactAddress || coopAddress || '')
      .replaceAll('[co_op.people.phone]', coopPhone || '')
      .replaceAll('[co_op.people.email]', coopEmail || '')

    if (templateNameRef.value !== 'Biên bản bàn giao đất - Cá nhân') {
      replaced = replaced
      .replaceAll('[product.trade_code_payment]', sanitizeContentPayment(trade_code))
      .replaceAll('[transaction.date]', formatDateVNText(prdbk__transaction__date) || '')
      .replaceAll('[customer.name]', getName())
      .replaceAll('[payment_schedule.remain_amount]', $numtoString((remain_amount).toFixed()) || '')
      .replaceAll('[payment_schedule.paid_amount]', $numtoString(paid_amount.toFixed()) || '')
      .replaceAll('[payment_schedule.penalty_remain]', $numtoString(penalty_remain.toFixed()) || '')
      .replaceAll('[payment_schedule.amount]', $numtoString(amount) || '')
      .replaceAll('[payment_schedule.remain_amount_in_word]', $numberToVietnameseCurrency(remain_amount) || '')
      .replaceAll('[payment_schedule.to_date]', $formatDateVN(to_date) || '')
      .replaceAll('[payment_schedule.expiration_date]',  $formatDateVN(addDays(3)) || '')
      .replaceAll('[payment_schedule.cycle]', $numtoString(cycle) || '')
      .replaceAll(
        '[payment_schedule.cycle-in-words]',
        cycle == 0 ? 'đặt cọc' : `đợt thứ ${$numberToVietnamese(cycle).toLowerCase()}`,
      )
      .replaceAll('[payment_schedule.note]', cycle == 0 ? 'đặt cọc' : `đợt ${cycle}`)
    }

    return replaced;
  }

  function quillToEmailHtml(html) {
    return html
      // ALIGN (chỉ replace align class, không phá class khác)
      .replace(/class="([^"]*?)ql-align-center([^"]*?)"/g, 'style="text-align:center;"')
      .replace(/class="([^"]*?)ql-align-right([^"]*?)"/g, 'style="text-align:right;"')
      .replace(/class="([^"]*?)ql-align-left([^"]*?)"/g, 'style="text-align:left;"')
      .replace(/class="([^"]*?)ql-align-justify([^"]*?)"/g, 'style="text-align:justify;"')

      // FONT SIZE (xóa class size)
      .replace(/ql-size-small/g, '')
      .replace(/ql-size-large/g, '')
      .replace(/ql-size-huge/g, '')

      // REMOVE EMPTY CLASS
      .replace(/class=""/g, '')

      // FIX FIGURE MARGIN LEFT + RIGHT
      .replace(
        /<figure([^>]*?)style="([^"]*)"/g,
        (match, before, styles) => {
          if (!/margin-left\s*:/.test(styles)) {
            styles += ';margin-left:0';
          }
          if (!/margin-right\s*:/.test(styles)) {
            styles += ';margin-right:0';
          }
          return `<figure${before}style="${styles}"`;
        }
      );
  }

  async function send() {
    isSending.value = true;
    $snackbar(`Đang gửi ${contents.value.length} email thông báo...`);

    await forEachAsync(contents.value, async (bigContent, i) => {    
      const { imageUrl, keyword } = bigContent;
      const tempEm = {
        content: toRaw(bigContent),
        previewMode: true,
      };
      
      // ===== QUILL → HTML EMAIL (INLINE STYLE) =====
      let emailHtml = await render(Template1, tempEm);
      
      // If no image URL provided, remove image section from HTML
      if ((imageUrl ?? '').trim() === '') {
        emailHtml = emailHtml
          .replace(/<tr\s+class=["']header-row["'][^>]*>[\s\S]*?<\/tr>/gi, '')
          .replace(/\n\s*\n\s*\n/g, '\n\n');
      }

      // Replace keywords in HTML
      if (keyword && keyword.length > 0) {
        keyword.forEach(({ keyword, value }) => {
          if (keyword && value) {
            const regex = new RegExp(`\\{\\{${keyword}\\}\\}`, 'g');
            emailHtml = emailHtml.replace(regex, value);
          }
        });
      }

      const subject = replaceTemplateVars(bigContent.subject, products.value[i]) || 'Thông báo từ Utopia Villas & Resort';

      const response = await $insertapi(
        'sendemail',
        {
          to: products.value[i].prdbk__transaction__customer__email,
          content: emailHtml,
          subject
        },
        undefined,
        false,
      );

      if (response !== null) {
        await $insertapi('productnote', {
          ref: products.value[i].id,
          user: $store.login.id,
          detail: `Đã gửi ${templateNameRef.value} cho sản phẩm ${products.value[i].trade_code} vào lúc ${$dayjs().format('HH:mm ngày DD/MM/YYYY')}.`
        }, undefined, false);
      } 
    });

    setTimeout(() => {
      $snackbar('Thông báo đã được gửi thành công đến khách hàng.');
      isSending.value = false;
    }, 1000);
  }

  async function populateProducts(idFilters = {}) {
    const productsData = await $getdata(
      'product',
      undefined,
      {
        filter: { 
          ...filter.value,
          ...idFilters,
        },
        sort: 'prdbk__transaction__resvtxn__psh__cycle',
        values: 'prdbk__transaction,prdbk__transaction__code,prdbk__transaction__date,prdbk__transaction__txncurrent__detail__status__name,prdbk,prdbk__transaction__policy__code,prdbk__transaction__sale_price,prdbk__transaction__discount_amount,prdbk__transaction__customer,prdbk__transaction__customer__code,prdbk__transaction__customer__type__code,prdbk__transaction__customer__phone,prdbk__transaction__customer__fullname,prdbk__transaction__customer__legal_code,prdbk__transaction__customer__issued_date,prdbk__transaction__customer__contact_address,prdbk__transaction__customer__address,prdbk__transaction__customer__email,prdbk__transaction__customer__orgncust__bank_account,prdbk__transaction__customer__orgncust__bank_name,prdbk__transaction__customer__orgncust__orgrep__people__fullname,prdbk__transaction__customer__orgncust__orgrep__relation__name,prdbk__transaction__co_op,prdbk__transaction__co_op__people,prdbk__transaction__co_op__people__fullname,prdbk__transaction__co_op__people__legal_code,prdbk__transaction__co_op__people__address,prdbk__transaction__co_op__people__contact_address,prdbk__transaction__co_op__people__phone,prdbk__transaction__amount_remain,prdbk__transaction__amount_received,prdbk__transaction__resvtxn__psh,prdbk__transaction__resvtxn__psh__code,prdbk__transaction__resvtxn__psh__amount_remain,prdbk__transaction__resvtxn__psh__paid_amount,prdbk__transaction__resvtxn__psh__penalty_amount,prdbk__transaction__resvtxn__psh__penalty_remain,prdbk__transaction__resvtxn__psh__remain_amount,prdbk__transaction__resvtxn__psh__amount,prdbk__transaction__resvtxn__psh__cycle,prdbk__transaction__resvtxn__psh__to_date,locked_until,note,cart,cart__name,cart__code,cart__dealer,cart__dealer__code,cart__dealer__name,direction,type,zone_type,dealer,link,type__name,dealer__code,dealer__name,id,code,trade_code,land_lot_code,zone_code,zone_type__name,lot_area,building_area,total_built_area,number_of_floors,land_lot_size,origin_price,price_excluding_vat,direction__name,villa_model,product_type,template_name,project,project__name,status,status__code,status__name,status__color,status__sale_status,status__sale_status__color,create_time,elpro__stage,elpro__area_before,elpro__current_area,elpro__area_gap,elpro__rate_amount,elpro__date',
      }
    );

    // group by trade_code first
    products.value = groupByProduct(productsData);
    contents.value = products.value.map((product) => { 
      const qr = templateNameRef.value === 'Mail Thông báo bàn giao đất' ? buildQrHtml($paymentQR(buildContentPayment(product), 'TCB')) : '';
      const content = emailTemplate.value?.content.content + qr;
      const message = quillToEmailHtml(replaceTemplateVars(content, product)); // replace property `content` with `message`, then fill info

      return {
        ...emailTemplate.value?.content,
        message,
        content: undefined,
      }
    });
  }
  
  /**
   * Group product objects by same product id
   * [{G.B01}, {G.B01}, {G.B01}] => {G.B01, with sum amount, sum remain_amount, etc.}
   */
  function groupByProduct(products) {
    const uniqueProducts = groupBy(products, (p) => p.trade_code);
    const uniqueProductsWithSummedFields = Object.entries(uniqueProducts).map(([_, sameProductRows]) => {
      // same product different schedules
      const summedFields = {
        prdbk__transaction__resvtxn__psh__amount: sameProductRows.reduce((prev, curr) => prev + curr.prdbk__transaction__resvtxn__psh__amount, 0),
        prdbk__transaction__resvtxn__psh__paid_amount: sameProductRows.reduce((prev, curr) => prev + curr.prdbk__transaction__resvtxn__psh__paid_amount, 0),
        prdbk__transaction__resvtxn__psh__amount_remain: sameProductRows.reduce((prev, curr) => prev + curr.prdbk__transaction__resvtxn__psh__amount_remain, 0),
        prdbk__transaction__resvtxn__psh__penalty_remain: sameProductRows.reduce((prev, curr) => prev + curr.prdbk__transaction__resvtxn__psh__penalty_remain, 0),
        prdbk__transaction__resvtxn__psh__remain_amount: sameProductRows.reduce((prev, curr) => prev + curr.prdbk__transaction__resvtxn__psh__remain_amount, 0),
      }
      // console.table(summedFields);

      const productWithSummedFields = {
        ...last(sameProductRows),
        ...summedFields
      }

      return productWithSummedFields;
    });

    return uniqueProductsWithSummedFields;
  }
  
  async function populateEmailTemplate() {
    if (templateNameRef.value) {
      const emailTemplateData = await $getdata(
        'emailtemplate',
        { name__icontains: templateNameRef.value },
        undefined,
        true,
      ); 
      
      emailTemplate.value = emailTemplateData;
    }
  }
  
  onMounted(async () => {
    await populateEmailTemplate();
    populateProducts();
  });
 
  watch(filter, () => {
    populateProducts();
  }, { deep: true });

  watch(() => $store.selectedProductsForHandoverEmail, (val) => {
    populateProducts({ id__in: val });
  })
  
  return { contents, send, isSending };
}