"use client"

import { userImport } from "@/components/label/api/user"
import {
  Alert,
  Button,
  FileInput,
  Group,
  Modal,
  Paper,
  Stack,
  Text,
} from "@mantine/core"
import { notifications } from "@mantine/notifications"
import { IconAlertCircle, IconDownload, IconUpload } from "@tabler/icons-react"
import { useState } from "react"
import * as XLSX from "xlsx-js-style"

interface ComponentProps {
  opened: boolean
  onCloseAction: (refresh?: boolean) => void
}

type ImportItem = {
  user_name: string
  group_name: string
  base_city: string
}

export default function ImportModal({ opened, onCloseAction }: ComponentProps) {
  const [file, setFile] = useState<File | null>(null)
  const [sheetList, setSheetList] = useState<ImportItem[]>([])
  const [failedDataTips, setFailedDataTips] = useState<string[]>([])
  const [submitting, setSubmitting] = useState(false)

  const clearState = () => {
    setFile(null)
    setSheetList([])
    setFailedDataTips([])
  }

  const parseFile = async (nextFile: File | null) => {
    setFile(nextFile)
    setSheetList([])
    setFailedDataTips([])
    if (!nextFile) return
    if (!nextFile.name.endsWith(".xlsx")) {
      notifications.show({
        color: "red",
        title: "文件格式错误",
        message: "仅支持 .xlsx 文件",
      })
      setFile(null)
      return
    }

    try {
      const data = await nextFile.arrayBuffer()
      const workbook = XLSX.read(data, { type: "array" })
      const sheetName = workbook.SheetNames[0]
      const ws = workbook.Sheets[sheetName]
      const arr = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1, raw: false })
      const tableData = arr.slice(4).filter((row) => row.length > 0)

      if (tableData.length === 0) {
        setSheetList([])
        return
      }

      const checkList: Record<number, string> = {
        0: "用户名",
        1: "组织",
        2: "所在地",
      }
      const tipRows = 4
      const errors: string[] = []

      const list: ImportItem[] = tableData.map((item: any[], index: number) => {
        Object.entries(checkList).forEach(([key, fieldName]) => {
          const value = item[Number(key)]
          if (!value || (typeof value === "string" && !value.trim())) {
            errors.push(
              `第${index + 1 + tipRows}行数据缺少必填项【${fieldName}】或该必填项全为空格`
            )
          }
        })

        return {
          user_name: item[0] ? String(item[0]).trim() : "",
          group_name: item[1] ? String(item[1]).trim() : "",
          base_city: item[2] ? String(item[2]).trim() : "",
        }
      })

      if (errors.length > 0) {
        setFailedDataTips(errors)
        setSheetList([])
        return
      }

      setSheetList(list)
    } catch (e) {
      notifications.show({
        color: "red",
        title: "解析失败",
        message: e instanceof Error ? e.message : "读取文件失败",
      })
      setFile(null)
    }
  }

  const exportTemplateFile = () => {
    const tips = [
      [`提示:\n1.下列字段均为必填项\n2.【组织】仅可以填入一个组织名称`],
      [""],
      [""],
    ]
    const col = [["用户名", "组织", "所在地"]]
    const wb = XLSX.utils.book_new()
    const ws = XLSX.utils.aoa_to_sheet([...tips, ...col])
    XLSX.utils.book_append_sheet(wb, ws, "用户信息")
    wb.Sheets["用户信息"]["!rows"] = [{ hpx: 20 }, { hpx: 20 }, { hpx: 20 }]
    wb.Sheets["用户信息"]["!cols"] = [{ wch: 20 }, { wch: 20 }, { wch: 20 }]
    wb.Sheets["用户信息"]["!merges"] = [
      { s: { c: 0, r: 0 }, e: { c: 2, r: 2 } },
    ]
    if (wb.Sheets["用户信息"]["A1"]) {
      wb.Sheets["用户信息"]["A1"].s = { alignment: { wrapText: true } }
    }
    XLSX.writeFile(wb, "用户信息批量导入模板.xlsx")
  }

  const submit = async () => {
    if (sheetList.length === 0) {
      notifications.show({
        color: "yellow",
        title: "无导入数据",
        message: "请先上传并校验 Excel 文件",
      })
      return
    }
    try {
      setSubmitting(true)
      const res = await userImport({ user_infos: sheetList })
      if (Array.isArray(res) && res.length > 0) {
        setFailedDataTips(res)
        notifications.show({
          color: "red",
          title: "导入失败",
          message: "请根据错误提示修正后重试",
        })
        return
      }
      notifications.show({
        color: "green",
        title: "导入成功",
        message: "批量新增用户数据成功",
      })
      clearState()
      onCloseAction(true)
    } catch (e) {
      notifications.show({
        color: "red",
        title: "导入失败",
        message: e instanceof Error ? e.message : "请求失败",
      })
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <Modal
      opened={opened}
      onClose={() => {
        clearState()
        onCloseAction()
      }}
      title="批量导入用户信息"
      centered
      size={760}
      closeOnClickOutside={false}>
      <Stack gap="sm">
        <Paper
          withBorder
          p="sm"
          radius="sm"
          style={{
            borderColor:
              "light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
          }}>
          <Group gap={8}>
            <Text size="sm">点击下载</Text>
            <Button
              variant="subtle"
              size="compact-sm"
              leftSection={<IconDownload size={14} />}
              onClick={exportTemplateFile}>
              用户信息批量导入模板
            </Button>
            <Text size="sm">后，填写上传</Text>
          </Group>
        </Paper>

        <FileInput
          label="上传文件"
          description="支持单个 xlsx 文件上传"
          size="xs"
          radius="xs"
          accept=".xlsx"
          placeholder="请选择文件"
          leftSection={<IconUpload size={16} />}
          value={file}
          onChange={parseFile}
          clearable
        />

        <Paper
          withBorder
          p="xs"
          radius="sm"
          style={{
            borderColor:
              "light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
          }}>
          <Text size="sm">待导入数据：{sheetList.length} 条</Text>
        </Paper>

        {failedDataTips.length > 0 ? (
          <Alert
            icon={<IconAlertCircle size={16} />}
            color="red"
            radius="sm"
            title="错误信息提示">
            <Stack gap={4} style={{ maxHeight: 180, overflowY: "auto" }}>
              {failedDataTips.map((item) => (
                <Text key={item} size="sm">
                  {item}
                </Text>
              ))}
            </Stack>
          </Alert>
        ) : null}

        <Group justify="flex-end">
          <Button
            variant="default"
            size="xs"
            radius="xs"
            onClick={() => {
              clearState()
              onCloseAction()
            }}>
            取消
          </Button>
          <Button size="xs" radius="xs" onClick={submit} loading={submitting}>
            开始导入
          </Button>
        </Group>
      </Stack>
    </Modal>
  )
}
