/**
 * 按业务域分组的 DWD 表选择器。
 *
 * 从 /api/tasks/dwd-tables 获取 DWD 表定义，按业务域折叠展示，
 * 支持全选/反选。仅在 Flow 包含 DWD 层时由父组件渲染。
 */

import React, { useEffect, useState, useMemo, useCallback } from "react";
import {
  Collapse,
  Checkbox,
  Spin,
  Alert,
  Button,
  Space,
  Typography,
} from "antd";
import type { CheckboxChangeEvent } from "antd/es/checkbox";
import { fetchDwdTables } from "../api/tasks";

const { Text } = Typography;

/* ------------------------------------------------------------------ */
/*  Props                                                              */
/* ------------------------------------------------------------------ */

export interface DwdTableSelectorProps {
  /** 已选中的 DWD 表名列表 */
  selectedTables: string[];
  /** 选中表变化回调 */
  onTablesChange: (tables: string[]) => void;
}

/* ------------------------------------------------------------------ */
/*  组件                                                               */
/* ------------------------------------------------------------------ */

const DwdTableSelector: React.FC<DwdTableSelectorProps> = ({
  selectedTables,
  onTablesChange,
}) => {
  /** 按业务域分组的 DWD 表 */
  const [tableGroups, setTableGroups] = useState<Record<string, string[]>>({});
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  /* ---------- 加载 DWD 表定义 ---------- */
  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(null);

    fetchDwdTables()
      .then((data) => {
        if (!cancelled) setTableGroups(data);
      })
      .catch((err) => {
        if (!cancelled) setError(err?.message ?? "获取 DWD 表列表失败");
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });

    return () => {
      cancelled = true;
    };
  }, []);

  /** 所有表名的扁平列表 */
  const allTableNames = useMemo(
    () => Object.values(tableGroups).flat(),
    [tableGroups],
  );

  /* ---------- 事件处理 ---------- */

  /** 单个业务域的勾选变化 */
  const handleDomainChange = useCallback(
    (domain: string, checkedTables: string[]) => {
      const domainTables = new Set(tableGroups[domain] ?? []);
      const otherSelected = selectedTables.filter((t) => !domainTables.has(t));
      onTablesChange([...otherSelected, ...checkedTables]);
    },
    [selectedTables, tableGroups, onTablesChange],
  );

  /** 全选 */
  const handleSelectAll = useCallback(() => {
    onTablesChange(allTableNames);
  }, [allTableNames, onTablesChange]);

  /** 反选 */
  const handleInvertSelection = useCallback(() => {
    const currentSet = new Set(selectedTables);
    const inverted = allTableNames.filter((t) => !currentSet.has(t));
    onTablesChange(inverted);
  }, [allTableNames, selectedTables, onTablesChange]);

  /* ---------- 渲染 ---------- */

  if (loading) {
    return <Spin tip="加载 DWD 表列表…" />;
  }

  if (error) {
    return <Alert type="error" message="加载失败" description={error} />;
  }

  const domainEntries = Object.entries(tableGroups);

  if (domainEntries.length === 0) {
    return <Text type="secondary">无可选 DWD 表</Text>;
  }

  const selectedCount = selectedTables.filter((t) =>
    allTableNames.includes(t),
  ).length;

  return (
    <div>
      {/* 全选 / 反选 */}
      <Space style={{ marginBottom: 8 }}>
        <Button size="small" onClick={handleSelectAll}>
          全选
        </Button>
        <Button size="small" onClick={handleInvertSelection}>
          反选
        </Button>
        <Text type="secondary">
          已选 {selectedCount} / {allTableNames.length}
        </Text>
      </Space>

      <Collapse
        defaultActiveKey={domainEntries.map(([d]) => d)}
        items={domainEntries.map(([domain, tables]) => {
          const domainSelected = selectedTables.filter((t) =>
            tables.includes(t),
          );

          const allChecked = domainSelected.length === tables.length;
          const indeterminate = domainSelected.length > 0 && !allChecked;

          const handleDomainCheckAll = (e: CheckboxChangeEvent) => {
            handleDomainChange(domain, e.target.checked ? tables : []);
          };

          return {
            key: domain,
            label: (
              <span onClick={(e) => e.stopPropagation()}>
                <Checkbox
                  indeterminate={indeterminate}
                  checked={allChecked}
                  onChange={handleDomainCheckAll}
                  style={{ marginRight: 8 }}
                />
                {domain}
                <Text type="secondary" style={{ marginLeft: 4 }}>
                  ({domainSelected.length}/{tables.length})
                </Text>
              </span>
            ),
            children: (
              <Checkbox.Group
                value={domainSelected}
                onChange={(checked) =>
                  handleDomainChange(domain, checked as string[])
                }
              >
                <Space direction="vertical">
                  {tables.map((table) => (
                    <Checkbox key={table} value={table}>
                      {table}
                    </Checkbox>
                  ))}
                </Space>
              </Checkbox.Group>
            ),
          };
        })}
      />
    </div>
  );
};

export default DwdTableSelector;
