"use client"

import {
  checkLabelDataSource,
  getProjectAdminList,
  getProjectTypeList,
  projectAdd,
} from "@/components/label/api/project"
import {
  getAllVersionByName,
  getLabelSchemeList,
} from "@/components/label/api/scheme"
import { usePermissionStore } from "@/components/label/store/auth"
import {
  Alert,
  Button,
  Group,
  Modal,
  MultiSelect,
  Radio,
  Select,
  Stack,
  Switch,
  Text,
  TextInput,
  Textarea,
} from "@mantine/core"
import { useForm } from "@mantine/form"
import { notifications } from "@mantine/notifications"
import { IconAlertTriangle } from "@tabler/icons-react"
import { useEffect, useMemo, useRef, useState } from "react"

export default function NewProjectModal(props: {
  opened: boolean
  onCloseAction: (refresh?: boolean) => void
}) {
  const { opened, onCloseAction } = props
  const userName = usePermissionStore((s) => s.user_name)

  const [typeOpts, setTypeOpts] = useState<
    Array<{ label: string; value: string }>
  >([])
  const [labelSchemeOpts, setLabelSchemeOpts] = useState<
    Array<{ label: string; value: string }>
  >([])
  const [versionOpts, setVersionOpts] = useState<
    Array<{ label: string; value: string }>
  >([])
  const [adminUserOpts, setAdminUserOpts] = useState<
    Array<{ label: string; value: string }>
  >([])
  const [dataSize, setDataSize] = useState<number>(0)

  const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const form = useForm({
    initialValues: {
      project_name: "",
      project_type: "",
      is_dynamic: false,
      data_source_radio: "" as "" | "0" | "1",
      data_source: "",
      label_schema_name: "",
      label_schema_version: "",
      is_embedding: false,
      admin_user: [] as string[],
      remark: "",
    },
    validate: {
      project_name: (v) => {
        if (!v) return "必填"
        if (/^\s*$/.test(v)) return "项目名称不能全为空格"
        return null
      },
      project_type: (v) => (!v ? "必填" : null),
      label_schema_name: (v) => (!v ? "必填" : null),
      label_schema_version: (v) => (!v ? "必填" : null),
      admin_user: (v) => (v && v.length ? null : "必填"),
    },
  })

  const isDynamic = form.values.is_dynamic
  const projectType = form.values.project_type
  const labelSchema = form.values.label_schema_name

  useEffect(() => {
    if (!opened) return
    const initFormOpts = async () => {
      try {
        const [schemeRes, adminRes, typeRes] = await Promise.all([
          getLabelSchemeList({ page_number: 1, page_size: 5000 } as any),
          getProjectAdminList(),
          getProjectTypeList(),
        ])

        const schemes = (schemeRes as any)?.label_schema_list ?? []
        setLabelSchemeOpts(
          schemes.map((item: any) => ({ label: item.name, value: item.name }))
        )

        setAdminUserOpts(
          (adminRes ?? []).map((item: any) => ({
            label: item.label,
            value: String(item.value),
          }))
        )

        setTypeOpts(
          (typeRes ?? []).map((name) => ({ label: name, value: name }))
        )
      } catch {
        setLabelSchemeOpts([])
        setAdminUserOpts([])
        setTypeOpts([])
      }
    }
    initFormOpts()
  }, [opened])

  useEffect(() => {
    if (!opened) return
    const run = async () => {
      form.setFieldValue("label_schema_version", "")
      setVersionOpts([])
      if (!labelSchema) return
      try {
        const res = await getAllVersionByName(labelSchema)
        const list = (res as any)?.label_schema_version_list ?? []
        setVersionOpts(
          list.map((item: any) => ({
            label: item.version,
            value: item.version,
          }))
        )
      } catch {
        setVersionOpts([])
      }
    }
    run()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [labelSchema, opened])

  useEffect(() => {
    if (!opened) return
    if (isDynamic) {
      form.setFieldValue("data_source_radio", "")
      form.setFieldValue("data_source", "")
      queueMicrotask(() => setDataSize(0))
      form.clearFieldError("data_source")
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isDynamic, opened])

  const triggerCheckDataSource = (value: string) => {
    if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current)
    if (!value) {
      setDataSize(0)
      form.clearFieldError("data_source")
      return
    }
    const radio = form.values.data_source_radio
    if (!projectType) {
      setDataSize(0)
      form.setFieldError("data_source", "请先选择所属业务")
      return
    }
    if (radio !== "0" && radio !== "1") {
      setDataSize(0)
      form.setFieldError("data_source", "请先选择标注数据源对应来源类型")
      return
    }

    debounceTimerRef.current = setTimeout(async () => {
      try {
        const res = await checkLabelDataSource({
          project_type: projectType,
          nfs_path: value,
          flag: Number(radio),
        })
        const errorCode = (res as any)?.error_code
        const size = (res as any)?.data_size ?? 0

        const errorMap = new Map<number, string>([
          [1, "nfs路径不存在"],
          [2, "nfs路径下不存在data目录"],
          [3, "nfs路径下不存在tag目录"],
          [4, "tag文件数量小于data文件数量"],
          [5, "pattern.json文件不存在"],
          [6, "clip.json文件不合法"],
          [7, "tag.json文件不合法"],
          [8, "pattern.json文件不合法"],
        ])

        if (errorCode === 0) {
          setDataSize(size)
          form.clearFieldError("data_source")
        } else if (errorMap.has(errorCode)) {
          setDataSize(0)
          form.setFieldError(
            "data_source",
            errorMap.get(errorCode) || "标注数据源填写有误"
          )
        } else {
          setDataSize(0)
          form.setFieldError("data_source", "标注数据源填写有误")
        }
      } catch (e) {
        setDataSize(0)
        form.setFieldError(
          "data_source",
          e instanceof Error ? e.message : "标注数据源校验失败"
        )
      }
    }, 1000)
  }

  const canSubmit = useMemo(() => {
    if (!opened) return false
    if (!form.values.project_name || /^\s*$/.test(form.values.project_name))
      return false
    if (!form.values.project_type) return false
    if (!form.values.label_schema_name || !form.values.label_schema_version)
      return false
    if (!form.values.admin_user.length) return false
    if (!form.values.is_dynamic) {
      if (!form.values.data_source_radio) return false
      if (!form.values.data_source) return false
      if (form.errors.data_source) return false
    }
    return true
  }, [form.errors.data_source, form.values, opened])

  return (
    <Modal
      opened={opened}
      onClose={() => onCloseAction()}
      title="新增标注任务"
      centered
      size="50%"
      closeOnClickOutside={false}>
      <Stack gap="sm">
        <Alert
          color="yellow"
          radius="xs"
          p="xs"
          icon={<IconAlertTriangle size={16} />}
          title="提示">
          如标注数据需预标或辅助标注，请先前往数据中心MDS模块进行数据处理
        </Alert>
        <form
          onSubmit={form.onSubmit(async (values) => {
            if (!canSubmit) return
            const data: any = { ...values }
            data.is_dynamic = values.is_dynamic ? 1 : 0
            data.is_embedding = values.is_embedding ? 1 : 0
            data.data_source = values.data_source ?? ""
            data.create_user = userName ?? ""
            data.data_size = dataSize
            data.admin_user = values.admin_user
              .map((v) => Number(v))
              .filter((n) => Number.isFinite(n))
            data.remarks = values.remark || undefined
            delete data.remark
            delete data.data_source_radio
            try {
              await projectAdd(data)
              notifications.show({
                color: "green",
                title: "项目创建成功",
                message: "已创建项目",
              })
              form.reset()
              setDataSize(0)
              onCloseAction(true)
            } catch (e) {
              notifications.show({
                color: "red",
                title: "创建失败",
                message: e instanceof Error ? e.message : "请求失败",
              })
            }
          })}>
          <div
            style={{ maxHeight: "58vh", overflowY: "auto", paddingRight: 6 }}>
            <Stack gap="sm">
              <TextInput
                label="项目名称"
                radius="xs"
                size="xs"
                placeholder="请输入项目名称"
                withAsterisk
                {...form.getInputProps("project_name")}
              />

              <Select
                label="所属业务"
                radius="xs"
                size="xs"
                placeholder="请选择所属业务"
                data={typeOpts}
                searchable
                clearable
                withAsterisk
                value={form.values.project_type || null}
                onChange={(v) => form.setFieldValue("project_type", v ?? "")}
                error={form.errors.project_type}
              />

              <Switch
                label="是否为动态任务"
                size="sm"
                checked={form.values.is_dynamic}
                onChange={(e) =>
                  form.setFieldValue("is_dynamic", e.currentTarget.checked)
                }
              />

              {!isDynamic ? (
                <>
                  <Radio.Group
                    label="标注数据源"
                    size="xs"
                    withAsterisk
                    value={form.values.data_source_radio}
                    onChange={(v) => {
                      const next = v as "0" | "1" | ""
                      form.setFieldValue("data_source_radio", next)
                      if (form.values.data_source)
                        triggerCheckDataSource(form.values.data_source)
                    }}>
                    <Group gap="md" mt={6}>
                      <Radio
                        value="0"
                        label="新建数据源"
                        size="xs"
                        disabled={!projectType}
                      />
                      <Radio
                        value="1"
                        label="现存数据源"
                        size="xs"
                        disabled={!projectType}
                      />
                    </Group>
                  </Radio.Group>

                  <TextInput
                    label="标注数据源"
                    size="xs"
                    radius="xs"
                    placeholder="请输入标注数据源"
                    withAsterisk
                    disabled={!projectType}
                    value={form.values.data_source}
                    onChange={(e) => {
                      const v = e.currentTarget.value
                      form.setFieldValue("data_source", v)
                      triggerCheckDataSource(v)
                    }}
                    error={form.errors.data_source}
                    rightSection={
                      dataSize > 0 && form.values.data_source ? (
                        <Text size="xs" c="blue" style={{ paddingRight: 6 }}>
                          {dataSize}
                        </Text>
                      ) : undefined
                    }
                  />
                </>
              ) : null}

              <Select
                label="标注方案"
                size="xs"
                radius="xs"
                placeholder="请选择标注方案"
                data={labelSchemeOpts}
                searchable
                clearable
                withAsterisk
                value={form.values.label_schema_name || null}
                onChange={(v) =>
                  form.setFieldValue("label_schema_name", v ?? "")
                }
                error={form.errors.label_schema_name}
              />

              <Select
                label="方案版本"
                size="xs"
                radius="xs"
                placeholder="请选择标注方案版本号"
                data={versionOpts}
                searchable
                clearable
                withAsterisk
                value={form.values.label_schema_version || null}
                onChange={(v) =>
                  form.setFieldValue("label_schema_version", v ?? "")
                }
                error={form.errors.label_schema_version}
              />

              <Switch
                label="是否生成embedding"
                size="sm"
                checked={form.values.is_embedding}
                onChange={(e) =>
                  form.setFieldValue("is_embedding", e.currentTarget.checked)
                }
              />

              <MultiSelect
                label="标注管理员"
                size="xs"
                radius="xs"
                placeholder="请选择标注管理员"
                data={adminUserOpts}
                searchable
                clearable
                withAsterisk
                value={form.values.admin_user}
                onChange={(v) => form.setFieldValue("admin_user", v)}
                error={form.errors.admin_user}
              />

              <Textarea
                label="备注"
                size="xs"
                radius="xs"
                placeholder="请输入"
                maxLength={50}
                autosize
                minRows={3}
                value={form.values.remark}
                onChange={(e) =>
                  form.setFieldValue("remark", e.currentTarget.value)
                }
              />
            </Stack>
          </div>

          <Group justify="flex-end" mt="md" gap="sm">
            <Button
              variant="default"
              size="xs"
              radius="xs"
              onClick={() => onCloseAction()}>
              取消
            </Button>
            <Button type="submit" size="xs" radius="xs" disabled={!canSubmit}>
              确定
            </Button>
          </Group>
        </form>
      </Stack>
    </Modal>
  )
}
