"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import SearchBox, { Criterion } from "../SearchBox";
import SearchResults, { Column } from "../SearchResults";
import { EditNote } from "@mui/icons-material";
import { useRouter, useSearchParams } from "next/navigation";
import { useTranslation } from "react-i18next";
import { ScheduleType } from "@/app/api/scheduling";
import { NEXT_PUBLIC_API_URL } from "@/config/api";
import {
  ProdScheduleResult,
  SearchProdSchedule,
  fetchDetailedProdSchedules,
  fetchProdSchedules,
  exportProdSchedule,
  testDetailedSchedule,
  getFile6,
} from "@/app/api/scheduling/actions";
import { defaultPagingController } from "../SearchResults/SearchResults";
import { arrayToDateString, arrayToDayjs, decimalFormatter } from "@/app/utils/formatUtil";
import dayjs from "dayjs";
import { orderBy, uniqBy, upperFirst } from "lodash";
import { Button, Stack } from "@mui/material";
import isToday from 'dayjs/plugin/isToday';
import useUploadContext from "../UploadProvider/useUploadContext";
import { FileDownload, CalendarMonth } from "@mui/icons-material";
import { useSession } from "next-auth/react";
import { AUTH } from "@/authorities";

dayjs.extend(isToday);

// may need move to "index" or "actions"
// type RecordStructure = {
//     id: number,
//     scheduledPeriod: string,
//     scheduledAt: string,
//     productCount: number,
// };

type Props = {
  type: ScheduleType;
  // records: RecordStructure[];
  defaultInputs: SearchProdSchedule;
};

type SearchQuery = Partial<
  Omit<SearchProdSchedule, "id" | "pageSize" | "pageNum">
>;
type SearchParamNames = keyof SearchQuery;

const DSOverview: React.FC<Props> = ({ type, defaultInputs }) => {
  const [filteredSchedules, setFilteredSchedules] = useState<
    ProdScheduleResult[]
  >([]);
  const { t } = useTranslation("schedule");
  const { setIsUploading } = useUploadContext();
  const today = dayjs().format("YYYY-MM-DD");

  const { data: session } = useSession();  
  // Extract abilities (safe fallback to empty array if not logged in / no abilities)
  const abilities = session?.user?.abilities ?? [];  

  const router = useRouter();
  // const [filterObj, setFilterObj] = useState({});
  // const [tempSelectedValue, setTempSelectedValue] = useState({});
  const [pagingController, setPagingController] = useState(
    defaultPagingController,
  );
  const [totalCount, setTotalCount] = useState(0);
  const [inputs, setInputs] = useState({
    ...defaultInputs,
    produceAt: dayjs().format("YYYY-MM-DD"),
  });
  const typeOptions = [
    {
      value: "detailed",
      label: t("Detailed"),
    },
    {
      value: "manual",
      label: t("Manual"),
    },
  ];

  const searchCriteria: Criterion<SearchParamNames>[] = useMemo(() => {
    const searchCriteria: Criterion<SearchParamNames>[] = [
      // {
      //   label: t("Schedule Period"),
      //   label2: t("Schedule Period To"),
      //   paramName: "schedulePeriod",
      //   type: "dateRange",
      // },
      { label: t("Production Date"), paramName: "produceAt", type: "date", defaultValue: dayjs().format("YYYY-MM-DD") },
      //{
      //  label: t("Product Count"),
      //  paramName: "totalEstProdCount",
      //  type: "text",
      //},
      //{
      //  label: t("Type"),
      //  paramName: "types",
      //  type: "autocomplete",
      //  options: typeOptions,
      //},
    ];
    return searchCriteria;
  }, [t]);

  // const onDetailClick = useCallback(
  //     (item: ItemsResult) => {
  //         router.push(`/settings/items/edit?id=${item.id}`);
  //     },
  //     [router]
  // );

  // const onDeleteClick = useCallback(
  //     (item: ItemsResult) => {},
  //     [router]
  // );

  const onDetailClick = (record: ProdScheduleResult) => {
    console.log("[debug] record", record);
    router.push(`/scheduling/detailed/edit?id=${record.id}`);
  };

  const columns = useMemo<Column<ProdScheduleResult>[]>(
    () => [
      {
        name: "id",
        label: t("Details"),
        onClick: (record) => onDetailClick(record),
        buttonIcon: <EditNote />,
      },
      // {
      //   name: "schedulePeriod",
      //   label: t("Demand Forecast Period"),
      //   renderCell: (params) => {
      //     return `${arrayToDateString(
      //       params.schedulePeriod,
      //     )} - ${arrayToDateString(params.schedulePeriodTo)}`;
      //   },
      // },
      {
        name: "produceAt",
        label: t("Production Date"),
        renderCell: (params) => {
          return arrayToDateString(params.produceAt);
        },
      },
      {
        name: "totalEstProdCount",
        label: t("Product Count(s)"),
        headerAlign: "right",
        align: "right",
        renderCell: (params) => {
          return decimalFormatter.format(params.totalEstProdCount);
        },
      },
      {
        name: "type",
        label: t("Type"),
        renderCell: (params) => {
          return upperFirst(t(params.type));
        },
      },
      // {
      //     name: "action",
      //     label: t(""),
      //     buttonIcon: <GridDeleteIcon />,
      //     onClick: onDeleteClick,
      // },
    ],
    [filteredSchedules],
  );

  const refetchData = useCallback(
    async (
      query: Record<SearchParamNames, string> | SearchProdSchedule,
      actionType: "reset" | "search" | "paging",
    ) => {
      // console.log(query)
      const defaultTypes = ["detailed", "manual"];
      const convertedTypes = (
        query.types == undefined || typeof query.types == "string"
          ? query.types?.toLowerCase() == "all"
            ? defaultTypes
            : [query.types]
          : query.types.some((ele) => ele.toLowerCase() === "all")
            ? defaultTypes
            : query.types
      ) as ScheduleType[];

      const params: SearchProdSchedule = {
        produceAt: dayjs(query?.produceAt).isValid()
          ? query?.produceAt
          : undefined,
        types: convertedTypes,
        pageNum: pagingController.pageNum - 1,
        pageSize: pagingController.pageSize,
      };
      const response = await fetchDetailedProdSchedules(params);

      // console.log(response)
      if (response) {
        setTotalCount(response.total);
        switch (actionType) {
          case "reset":
          case "search":
            setFilteredSchedules(() => response.records);
            break;
          case "paging":
            setFilteredSchedules((fs) =>
            orderBy(
              uniqBy([...fs, ...response.records], "id"),
              ["id"], ["asc"]));
            break;
        }
      }
    },
    [pagingController, setPagingController],
  );

  useEffect(() => {
    refetchData(inputs, "paging");
  }, [pagingController]);

  const onReset = useCallback(() => {

  const resetWithToday = {
      ...defaultInputs,
      produceAt: dayjs().format("YYYY-MM-DD"),
    };
    setInputs(resetWithToday); // Update state
    refetchData(resetWithToday, "reset"); // Fetch data
  }, [defaultInputs, refetchData]);

  const handleDownloadPrintJob = async () => {
      const token = localStorage.getItem("accessToken");

      const params = {
        itemCode: 'TT173',
        lotNo: 'LOT342989',
        expiryDate: '2026-02-28',
        productName: 'Name2342'
      };

      try {
        // 1. Direct fetch call to avoid Next.js trying to parse JSON
        const query = new URLSearchParams(params).toString();
        const response = await fetch(`${NEXT_PUBLIC_API_URL}/plastic/get-printer6?${query}`, {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });

        if (!response.ok) throw new Error('Network response was not ok');

        // 2. GET THE DATA AS BLOB (This is the fix)
        const blob = await response.blob();

        // 3. Create a download link
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', `${params.lotNo}.zip`);
        document.body.appendChild(link);
        link.click();
        
        // Cleanup
        link.parentNode?.removeChild(link);
        window.URL.revokeObjectURL(url);

      } catch (error) {
        console.error("Download failed", error);
      }
  };

  const testDetailedScheduleClick = useCallback(async () => {
    try {
      setIsUploading(true)
      const response = await testDetailedSchedule(inputs.scheduleAt)
      if (response) {
        //refetchData(inputs, "paging");
        setPagingController(prev => ({ ...prev, pageNum: 1 }));
        refetchData(inputs, "search");
      }
    } catch(e) {
      console.log(e)
    } finally {
      setIsUploading(false)
    }
  }, [inputs])

  const exportProdScheduleClick = async () => {
    try {
      const token = localStorage.getItem("accessToken");
      // 1. Get Base64 string from server
      // 1. Prepare translated headers using the t() function
      
      const prodHeaders = [
        t("Item Name"), 
        t("Avg Qty Last Month"), 
        t("Stock Qty"),
        t("Days Left"), 
        t("Output Qty"), 
        t("Batch Need"), 
        t("Priority")
      ];

      const matHeaders = [
        t("Mat Code"), 
        t("Mat Name"), 
        t("Required Qty"), 
        t("Total Qty Need"),
        t("UoM"), 
        t("Purchased Qty"), 
        t("On Hand Qty"), 
        t("Unavailable Qty"),
        t("Related Item Code"), 
        t("Related Item Name"),
        t("Material Summary") // The last one can be used as the Sheet Name
      ];

      // 2. Pass these arrays to your server action
      // 'inputs' contains your filters (scheduleAt, types, etc.)
      const base64String = await exportProdSchedule(token, inputs, prodHeaders, matHeaders);
      
      // 2. Convert Base64 back to Blob
      const byteCharacters = atob(base64String);
      const byteNumbers = new Array(byteCharacters.length);
      for (let i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i);
      }
      const byteArray = new Uint8Array(byteNumbers);
      
      const blob = new Blob([byteArray], { 
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 
      });

      // 3. Trigger download (same as before)
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = "production_schedule.xlsx";
      link.click();
      window.URL.revokeObjectURL(url);
      
    } catch (error) {
      console.error(error);
      alert("Export failed. Check the console for details.");
    }
  };
  
  return (
    <>
      <Stack
        direction="row"
        justifyContent="flex-end"
        flexWrap="wrap"
        spacing={2} // This provides consistent space between buttons
        sx={{ mb: 3 }} // Adds some margin below the button group
      >
        <Button
          variant="outlined" // Outlined variant makes it look distinct from the primary action
          color="primary"
          startIcon={<CalendarMonth />}
          onClick={testDetailedScheduleClick}
        >
          {t("Detailed Schedule")}
        </Button>
        
        <Button
          variant="contained" // Solid button for the "Export" action
          color="success" // Green color often signifies a successful action/download
          startIcon={<FileDownload />}
          onClick={exportProdScheduleClick}
          sx={{ 
            boxShadow: 2, 
            '&:hover': { backgroundColor: 'success.dark', boxShadow: 4 } 
          }}
        >
          {t("Export Schedule")}
        </Button>

        {false && abilities.includes(AUTH.VIEW_USER) && (
        <Button 
          variant="contained" // Solid button for the "Export" action
          color="success" // Green color often signifies a successful action/download
          startIcon={<FileDownload />}
          onClick={handleDownloadPrintJob}
          sx={{ 
            boxShadow: 2, 
            '&:hover': { backgroundColor: 'success.dark', boxShadow: 4 } 
          }}
        >
          Get Printer File API
        </Button>
        )}
      </Stack>
      <SearchBox
        criteria={searchCriteria}
        onSearch={(query) => {
          const updatedInputs = {
            ...inputs,
            produceAt: query?.produceAt, // Ensure this matches paramName in searchCriteria
            totalEstProdCount: Number(query?.totalEstProdCount),
            types: query.types as unknown as ScheduleType[],
          };
          setInputs(updatedInputs);
          refetchData(updatedInputs, "search");
        }}
        onReset={onReset}
      />
      <SearchResults<ProdScheduleResult>
        items={filteredSchedules}
        columns={columns}
        setPagingController={setPagingController}
        pagingController={pagingController}
        totalCount={totalCount}
      // isAutoPaging={false}
      // hasCollapse={false}
      />
    </>
  );
};

export default DSOverview;
