import { useContext, useEffect, useRef, useState } from "react"
import classNames from "classnames"

import { DashboardTableHeader } from "./dashboard-table-header/dashboard-table-header.component"
import { DashboardTableCreate } from "./dashboard-table-create/dashboard-table-create.component"
import { DashboardTableHistory } from "./dashboard-table-history/dashboard-table-history.component"

import styles from "./dashboard-table.module.css"
import { Button } from "../../../ui-component/button/button.component"
import useWindowDimensions from "../../../hooks/window-dimensions.hook"
import { ScheduleType } from "../../../types/schedule.type"
import { DropdownItems } from "../../../ui-component/dropdown/dropdown.component"
import { Menu, MenuItem } from "../../../ui-component/menu"
import { PopupOpener } from "../../../ui-component/popup/popup-opener.provider"
import { DateUtils } from "../../../utils/date.utils"
import ellipsisVertical from "../../../assets/images/ellipsis_vertical.png"
import { Config } from "../../../utils/config"
import historyStyles from "./dashboard-table-preview/dashboard-table-preview.module.css"
import { DashboardTablePreview } from "./dashboard-table-preview/dashboard-table-preview.component"
import { DirtyContext } from "../../../provider/dirty.context"
import { useAccountUser } from "../../../hooks/user.hook"

export function DashboardTable() {
  // ---------------------------------------------------------------------------
  // variables
  // ---------------------------------------------------------------------------

  const { setDirty } = useContext(DirtyContext)
  const { width: screenWidth } = useWindowDimensions()
  const weeks = DateUtils.getWeeksByMonth(2024)
  const [selectedMonth, setSelectedMonth] = useState(
    DateUtils.getCurrentMonth(addDays(new Date(), 7)),
  )
  const [selectedWeek, setSelectedWeek] = useState(
    DateUtils.getWeekDateRange(addDays(new Date(), 7)),
  )
  const [mode, setMode] = useState<"newTable" | "tableHistory">("newTable")
  const [createMode, setCreateMode] = useState<"create" | "show">("create")
  const [table, setTable] = useState<ScheduleType>()
  const tableRef = useRef<HTMLDivElement>(null)
  const showTableRef = useRef<HTMLDivElement>(null)
  const accountUser = useAccountUser()

  // ---------------------------------------------------------------------------
  // effects
  // ---------------------------------------------------------------------------

  useEffect(() => {
    setCreateMode("create")

    setTable(undefined)
  }, [mode])

  useEffect(() => {
    if (
      DateUtils.getCurrentMonth(addDays(new Date(), 7)) === selectedMonth &&
      DateUtils.getWeekDateRange(addDays(new Date(), 7)) === selectedWeek
    )
      return

    setSelectedWeek(weeks[selectedMonth][0])
  }, [selectedMonth])

  useEffect(() => {
    loadSchedule(selectedWeek)
  }, [selectedWeek])

  // ---------------------------------------------------------------------------
  // functions
  // ---------------------------------------------------------------------------

  async function loadSchedule(week: string) {
    if (!accountUser) return
    week
    // const response = await fetch(`${Config.url}/api/schedule/gets`, {
    //   method: "POST",
    //   headers: { "Content-Type": "application/json" },
    //   body: JSON.stringify({ userId: accountUser.id, week: week }),
    // })

    // const tableByWeek = await response.json()

    // setTable(tableByWeek)
  }

  function addDays(date: Date, days: number): Date {
    const result = new Date(date)
    result.setDate(result.getDate() + days)
    return result
  }

  async function handlePDFDownload(element: React.RefObject<HTMLDivElement>) {
    if (!element.current) return

    try {
      // await new Promise((resolve) => setTimeout(resolve, 1000))

      const tableHTML = element.current.outerHTML

      const moduleStyles = Object.entries(historyStyles)
        .map(([key, value]) => {
          return `.${value} { /* styles for ${key} */ }`
        })
        .join("\n")

      const globalStyles = Array.from(document.styleSheets)
        .filter(
          (sheet) =>
            sheet.href === null ||
            sheet.href.startsWith(window.location.origin),
        )
        .map((sheet) => {
          try {
            return Array.from(sheet.cssRules)
              .map((rule) => rule.cssText)
              .join("\n")
          } catch (e) {
            console.log("Error accessing styleSheet", e)
            return ""
          }
        })
        .join("\n")

      const fullHTML = `
        <html>
          <head>
            <style>
              ${globalStyles}
              ${moduleStyles}
              body { margin: 0; padding: 0; background: white }
            </style>
          </head>
          <body>
            ${tableHTML}
          </body>
        </html>
      `

      const response = await fetch(`${Config.url}/api/upload/pdf`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ htmlContent: fullHTML }),
      })

      if (!response.ok) {
        const errorText = await response.text()
        throw new Error(
          `HTTP error! status: ${response.status}, message: ${errorText}`,
        )
      }

      const blob = await response.blob()
      const url = window.URL.createObjectURL(blob)
      const link = document.createElement("a")
      link.href = url
      link.download = "schedule.pdf"
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(url)
    } catch (error) {
      console.error("Error downloading PDF:", error)
    }
  }

  async function save() {
    if (!accountUser) return

    await fetch(`${Config.url}/api/gptTeacher/deleteHistorySchedule`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ userId: accountUser.id }),
    })

    setDirty(false)
    localStorage.setItem("table", JSON.stringify(table))
  }

  // ---------------------------------------------------------------------------
  return (
    <div
      className={classNames(
        styles.rightContentContainer,
        mode === "newTable" ? styles.overflow : "",
      )}
    >
      {/* --------------------------------------------------------------------------- */}
      {/* HEADER */}
      {/* --------------------------------------------------------------------------- */}

      <div className={styles.headerWrapper}>
        {/* --------------------------------------------------------------------------- */}
        {/* NAVIGATION */}
        {/* --------------------------------------------------------------------------- */}

        <DashboardTableHeader mode={mode} setMode={setMode} />

        {/* --------------------------------------------------------------------------- */}
        {/* ACTIONS */}
        {/* --------------------------------------------------------------------------- */}

        {((createMode === "show" && table && screenWidth > 500) ||
          mode === "tableHistory") && (
          <div className={styles.rightWrapper}>
            {/* --------------------------------------------------------------------------- */}
            {/* FILTERS */}
            {/* --------------------------------------------------------------------------- */}

            {mode === "tableHistory" && (
              <div className={styles.dropDownWrapper}>
                <div className={styles.btnsWrapper}>
                  <DropdownItems
                    btnClassName={styles.dropdownBtnWrapper}
                    placeholder="8月"
                    items={[
                      "1月", // January
                      "2月", // February
                      "3月", // March
                      "4月", // April
                      "5月", // May
                      "6月", // June
                      "7月", // July
                      "8月", // August
                      "9月", // September
                      "10月", // October
                      "11月", // November
                      "12月", // December
                    ]}
                    checked={(item) => {
                      return item === selectedMonth
                    }}
                    itemRender={(item) => <span>{item}</span>}
                    onChange={(item, checked) => {
                      if (!checked) {
                        setSelectedMonth(item)
                      }
                    }}
                  />

                  <DropdownItems
                    btnClassName={styles.dropdownBtnWrapper}
                    placeholder={DateUtils.getWeekDateRange(
                      addDays(new Date(), 7),
                    )}
                    items={weeks[selectedMonth]}
                    checked={(item) => {
                      return item === selectedWeek
                    }}
                    itemRender={(item) => <span>{item}</span>}
                    onChange={(item, checked) => {
                      if (!checked) {
                        setSelectedWeek(item)
                      }
                    }}
                  />
                </div>

                {screenWidth > 670 ? (
                  <>
                    <Button iconName="fa-solid fa-upload" mode="primary">
                      来週のスケジュールに使う
                    </Button>
                    <Button
                      iconName="fa-solid fa-download"
                      mode="primary"
                      onClick={() => handlePDFDownload(tableRef)}
                    >
                      出力
                    </Button>
                  </>
                ) : (
                  <PopupOpener
                    mode="click"
                    className={styles.popupWrapper}
                    placement="bottom-start"
                    closeOnInteract={true}
                    content={
                      <Menu>
                        <MenuItem
                          className={styles.menuitem}
                          icon="fa-solid fa-download"
                          label="出力"
                          onClick={() => handlePDFDownload(tableRef)}
                        />
                        <MenuItem
                          className={styles.menuitem}
                          icon="fa-solid fa-upload"
                          label="来週のスケジュールに使う"
                        />
                      </Menu>
                    }
                  >
                    <img src={ellipsisVertical} className={styles.ellipsis} />
                  </PopupOpener>
                )}
              </div>
            )}

            {/* --------------------------------------------------------------------------- */}
            {/* DOWNLOAD */}
            {/* --------------------------------------------------------------------------- */}

            {mode === "newTable" &&
            screenWidth > 500 &&
            createMode !== "create" &&
            table ? (
              <div className={styles.actionsWrapper}>
                <Button
                  iconName="fa-solid fa-floppy-disk"
                  mode="primary"
                  onClick={() => save()}
                >
                  保存
                </Button>

                <Button
                  iconName="fa-solid fa-download"
                  mode="primary"
                  onClick={() => handlePDFDownload(showTableRef)}
                >
                  出力
                </Button>
              </div>
            ) : (
              <></>
            )}
          </div>
        )}
      </div>

      {/* --------------------------------------------------------------------------- */}
      {/* TABLE */}
      {/* --------------------------------------------------------------------------- */}

      {mode === "tableHistory" ? (
        <DashboardTableHistory tableRef={tableRef} />
      ) : (
        // </div>
        <DashboardTableCreate
          mode={createMode}
          setMode={setCreateMode}
          table={table}
          setTable={setTable}
        />
      )}

      {/* --------------------------------------------------------------------------- */}
      {/* FOR DOWNLOADING TABLE  */}
      {/* --------------------------------------------------------------------------- */}

      <div style={{ display: "none" }}>
        {table && (
          <DashboardTablePreview
            tableRef={showTableRef}
            dataResponse={table}
            withCaption={false}
          />
        )}
      </div>
    </div>
  )
}
how To generate the PDF on the client-side instead of sending the HTML to the server ?