"use client";

import React, { useCallback, useMemo, useState } from "react";
import SearchBox, { Criterion } from "../SearchBox";
import { useTranslation } from "react-i18next";
import SearchResults, { Column } from "../SearchResults";
import EditNote from "@mui/icons-material/EditNote";
import { convertLocaleStringToNumber } from "@/app/utils/formatUtil"
import { Button, ButtonGroup, Stack, Tab, Tabs, TabsProps } from "@mui/material";
import FileDownloadIcon from '@mui/icons-material/FileDownload';
import FileUploadIcon from '@mui/icons-material/FileUpload';
import { dateInRange, downloadFile } from "@/app/utils/commonUtil";
import { importIssuedInovice, importReceivedInovice } from "@/app/api/invoices/actions";
import { errorDialogWithContent, successDialog } from "../Swal/CustomAlerts";
import { issuedInvoiceList, issuedInvoiceResult, issuedInvoiceSearchForm, receivedInvoiceList, receivedInvoiceSearchForm } from "@/app/api/invoices";

interface Props {
  issuedInvoice: issuedInvoiceList[];
  receivedInvoice: receivedInvoiceList[];
}

type SearchQuery = Partial<Omit<issuedInvoiceSearchForm, "id">>;
type SearchParamNames = keyof SearchQuery;

type SearchQuery2 = Partial<Omit<receivedInvoiceSearchForm, "id">>;
type SearchParamNames2 = keyof SearchQuery2;

const InvoiceSearch: React.FC<Props> = ({ issuedInvoice, receivedInvoice }) => {
  const { t } = useTranslation("invoices");
  const [tabIndex, setTabIndex] = useState(0);

  const [filteredIssuedInvoices, setFilteredIssuedInvoices] = useState(issuedInvoice);
  const [filteredReceivedInvoices, setFilteredReceivedInvoices] = useState(receivedInvoice);

  const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
    () => [
      { label: t("Invoice No"), paramName: "invoiceNo", type: "text" },
      { label: t("Project Code"), paramName: "projectCode", type: "text" },
      { label: t("Invoice Date"), label2: t("Invoice Date To"), paramName: "invoiceDate", type: "dateRange" },
      { label: t("Due Date"), label2: t("Due Date To"), paramName: "dueDate", type: "dateRange" },
    ],
    [t, issuedInvoice],
  );

  const searchCriteria2: Criterion<SearchParamNames2>[] = useMemo(
    () => [
      { label: t("Invoice No"), paramName: "invoiceNo", type: "text" },
      { label: t("Project Code"), paramName: "projectCode", type: "text" },
      { label: t("Recipt Date"), label2: t("Recipt Date To"), paramName: "receiptDate", type: "dateRange" },
    ],
    [t, issuedInvoice],
  );

  const onReset = useCallback(() => {
    setFilteredIssuedInvoices(issuedInvoice);
  }, [issuedInvoice]);

  function concatListOfObject(obj: any[]): string {
    return obj.map(obj => `Cannot find "${obj.paymentMilestone}" in ${obj.invoiceNo}`).join(", ")
  }

  function concatListOfObject2(obj: any[]): string {
    return obj.map(obj => `"${obj.projectCode}" does not match with ${obj.invoicesNo}`).join(", ")
  }

  const handleImportClick = useCallback(async (event:any) => {
    // console.log(event)
    try {

      const file = event.target.files[0];

      if (!file) {
        console.log('No file selected');
        return;
      }

      if (file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
        console.log('Invalid file format. Only XLSX files are allowed.');
        return;
      }

      const formData = new FormData();
      formData.append('multipartFileList', file);

      const response = await importIssuedInovice(formData);
      // response: status, message, projectList, emptyRowList, invoiceList

      console.log(response)
      if (response.status) {
        successDialog(t("Import Success"), t).then(() => {
          window.location.reload()
        })
      }else{
        if (response.emptyRowList.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please fill the mandatory field at Row <br> ${response.emptyRowList.join(", ")}`), t)
          .then(() => {
            window.location.reload()
          })
        }
        else if (response.projectList.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please check the corresponding project code <br> ${response.projectList.join(", ")}`), t)
          .then(() => {
            // window.location.reload()
          })
        }
        else if (response.invoiceList.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please check the corresponding Invoice No. The invoice is imported. <br>`)+ `${response.invoiceList.join(", ")}`, t)
          .then(() => {
            window.location.reload()
          })
        }
        else if (response.duplicateItem.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please check the corresponding Invoice No. The below invoice has duplicated number. <br>`)+ `${response.duplicateItem.join(", ")}`, t)
          .then(() => {
            window.location.reload()
          })
        }else if (response.paymentMilestones.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`The payment milestone does not match with records. Please check the corresponding Invoice No. <br>`)+ `${concatListOfObject(response.paymentMilestones)}`, t)
          .then(() => {
            window.location.reload()
          })
        }
      }

  } catch (err) {
      console.log(err)
      return false
  }
  }, []);

  const handleRecImportClick = useCallback(async (event:any) => {
    try {

      const file = event.target.files[0];

      if (!file) {
        console.log('No file selected');
        return;
      }

      if (file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
        console.log('Invalid file format. Only XLSX files are allowed.');
        return;
      }

      const formData = new FormData();
      formData.append('multipartFileList', file);

      const response = await importReceivedInovice(formData)
      console.log(response)

      if (response.status) {
        successDialog(t("Import Success"), t).then(() => {
          window.location.reload()
        })
      }else{
        if (response.emptyRowList.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please fill the mandatory field at Row <br> ${response.emptyRowList.join(", ")}`), t)
          .then(() => {
            window.location.reload()
          })
        }
        else if (response.projectList.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please check the corresponding project code <br> ${response.projectList.join(", ")}`), t)
          .then(() => {
            // window.location.reload()
          })
        }
        else if (response.invoiceList.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please check the corresponding Invoice No. The invoice has not yet issued. <br>`)+ `${response.invoiceList.join(", ")}`, t)
          .then(() => {
            window.location.reload()
          })
        }
        else if (response.duplicateItem.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`Please check the corresponding Invoice No. The below invoice has duplicated number. <br>`)+ `${response.duplicateItem.join(", ")}`, t)
          .then(() => {
            window.location.reload()
          })
        }else if (response.paymentMilestones.length >= 1){
          errorDialogWithContent(t("Import Fail"), 
          t(`The payment milestone does not match with records. Please check the corresponding Invoice No. <br>`)+ `${concatListOfObject2(response.paymentMilestones)}`, t)
          .then(() => {
            window.location.reload()
          })
        }
      }
    }catch(error){
      console.log(error)
    }
    
  }, []);

  const columns = useMemo<Column<issuedInvoiceList>[]>(
    () => [
      { name: "invoiceNo", label: t("Invoice No") },
      { name: "projectCode", label: t("Project Code") },
      { name: "stage", label: t("Stage") },
      { name: "paymentMilestone", label: t("Payment Milestone") },
      { name: "invoiceDate", label: t("Invocie Date") },
      { name: "dueDate", label: t("Due Date") },
      { name: "issuedAmount", label: t("Amount (HKD)") },
    ],
    [t],
  );

  const columns2 = useMemo<Column<receivedInvoiceList>[]>(
    () => [
      { name: "invoiceNo", label: t("Invoice No") },
      { name: "projectCode", label: t("Project Code") },
      { name: "projectName", label: t("Project Name") },
      { name: "team", label: t("Team") },
      { name: "receiptDate", label: t("Receipt Date") },
      { name: "receivedAmount", label: t("Amount (HKD)") },
    ],
    [t],
  );

  function isDateInRange(dateToCheck: string, startDate: string, endDate: string): boolean {

    if (!startDate || !endDate) {
      return false;
    }

    // console.log(dateToCheck, startDate, endDate)
    const dateToCheckObj = new Date(dateToCheck);
    const startDateObj = new Date(startDate);
    const endDateObj = new Date(endDate);
    // console.log(dateToCheckObj >= startDateObj && dateToCheckObj <= endDateObj)
    return dateToCheckObj >= startDateObj && dateToCheckObj <= endDateObj;
  }

  const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
    (_e, newValue) => {
        setTabIndex(newValue);
    },
    [],
  );

  return (
    <>
    <Stack
      direction="row"
      justifyContent="right"
      flexWrap="wrap"
      spacing={2}
    >
      {/* <ButtonGroup variant="contained"> */}
        <Button startIcon={<FileUploadIcon />} variant="contained" component="label">
          <input
            id='importExcel'
            type='file'
            accept='.xlsx, .csv'
            hidden
            onChange={(event) => {handleImportClick(event)}}
          />
          {t("Import Invoice Issue Summary")}
        </Button>
        <Button startIcon={<FileUploadIcon />} component="label" variant="contained">
        <input
            id='importExcel'
            type='file'
            accept='.xlsx, .csv'
            hidden
            onChange={(event) => {handleRecImportClick(event)}}
          />
          {t("Import Invoice Amount Receive Summary")}
        </Button>
      {/* </ButtonGroup> */}
    </Stack>
      {
        tabIndex == 0 &&
        <SearchBox
          criteria={searchCriteria}
          onSearch={(query) => {
            console.log(query)
            setFilteredIssuedInvoices(
              issuedInvoice.filter(
                (s) => 
                  (isDateInRange(s.invoiceDate, query.invoiceDate ?? undefined, query.invoiceDateTo ?? undefined)) ||
                  (isDateInRange(s.dueDate, query.dueDate ?? undefined, query.dueDateTo ?? undefined)) ||
                  (s.invoiceNo === query.invoiceNo) ||
                  (s.projectCode === query.projectCode)
              ),
            );
          }}
          onReset={onReset}
        />
      }
      {
        tabIndex == 1 &&
        <SearchBox
        criteria={searchCriteria2}
        onSearch={(query) => {
          console.log(query)
          setFilteredReceivedInvoices(
            receivedInvoice.filter(
              (s) => 
                (isDateInRange(s.receiptDate, query.receiptDate ?? undefined, query.receiptDateTo ?? undefined)) ||
                (s.invoiceNo === query.invoiceNo) ||
                (s.projectCode === query.projectCode)
            ),
          );
        }}
        onReset={onReset}
      />
      }
      <Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable">
          <Tab label={t("Issued Invoices")}/>
          <Tab label={t("Received Invoices")}/>
      </Tabs>
      {
        tabIndex == 0 &&
        <SearchResults<issuedInvoiceList>
          items={filteredIssuedInvoices}
          columns={columns}
        />
      }
      {
        tabIndex == 1 &&
        <SearchResults<receivedInvoiceList>
          items={filteredReceivedInvoices}
          columns={columns2}
        />
      }
      
    </>
  );
};

export default InvoiceSearch;
