import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { Card, Spin, Typography, Tag, message } from 'antd';
import {
  DndContext,
  DragOverlay,
  PointerSensor,
  useSensor,
  useSensors,
  closestCorners,
} from '@dnd-kit/core';
import type { DragEndEvent, DragStartEvent } from '@dnd-kit/core';
import { listPluginData, patchPluginData } from '../api/pluginData';
import { getPluginSchema, type PluginPageSchema } from '../api/plugins';

// ── 内部看板渲染组件 ──

interface KanbanInnerProps {
  pluginId: string;
  entity: string;
  laneField: string;
  laneOrder: string[];
  cardTitleField: string;
  cardSubtitleField?: string;
  cardFields?: string[];
  enableDrag?: boolean;
}

function KanbanInner({
  pluginId,
  entity,
  laneField,
  laneOrder,
  cardTitleField,
  cardSubtitleField,
  cardFields,
  enableDrag,
}: KanbanInnerProps) {
  const [lanes, setLanes] = useState<Record<string, any[]>>({});
  const [loading, setLoading] = useState(true);
  const [activeId, setActiveId] = useState<string | null>(null);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
  );

  const fetchData = async () => {
    setLoading(true);
    try {
      const allData: Record<string, any[]> = {};
      const results = await Promise.all(
        laneOrder.map(async (lane) => {
          const res = await listPluginData(pluginId, entity, 1, 100, {
            filter: { [laneField]: lane },
          });
          return { lane, data: res.data || [] };
        }),
      );
      for (const { lane, data } of results) {
        allData[lane] = data;
      }
      setLanes(allData);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchData();
  }, [pluginId, entity]);

  const handleDragStart = (event: DragStartEvent) => {
    setActiveId(event.active.id as string);
  };

  const handleDragEnd = async (event: DragEndEvent) => {
    setActiveId(null);
    if (!enableDrag) return;

    const { active, over } = event;
    if (!over) return;

    const recordId = active.id as string;
    const newLane = String(over.data.current?.lane || over.id);
    if (!newLane) return;

    let currentLane = '';
    let currentRecord: Record<string, any> | null = null;
    for (const [lane, items] of Object.entries(lanes)) {
      const found = items.find((item) => item.id === recordId);
      if (found) {
        currentLane = lane;
        currentRecord = found;
        break;
      }
    }
    if (currentLane === newLane) return;

    // 乐观更新
    setLanes((prev) => {
      const next: Record<string, any[]> = {};
      for (const [lane, items] of Object.entries(prev)) {
        if (lane === currentLane) {
          next[lane] = items.filter((item) => item.id !== recordId);
        } else if (lane === newLane) {
          const moved = prev[currentLane]?.find((item) => item.id === recordId);
          next[lane] = moved ? [...items, moved] : [...items];
        } else {
          next[lane] = items;
        }
      }
      return next;
    });

    try {
      await patchPluginData(pluginId, entity, recordId, {
        data: { [laneField]: newLane },
        version: currentRecord?.version ?? 0,
      });
      message.success('移动成功');
    } catch {
      message.error('移动失败');
      fetchData();
    }
  };

  const handleDragCancel = () => {
    setActiveId(null);
  };

  const activeCard = activeId
    ? Object.values(lanes)
        .flat()
        .find((item) => item.id === activeId)
    : null;

  if (loading) {
    return (
      <div style={{ padding: 24, textAlign: 'center' }}>
        <Spin />
      </div>
    );
  }

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCorners}
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
      onDragCancel={handleDragCancel}
    >
      <div style={{ display: 'flex', gap: 16, overflowX: 'auto', padding: 16 }}>
        {laneOrder.map((lane) => {
          const items = lanes[lane] || [];
          return (
            <div
              key={lane}
              id={`lane-${lane}`}
              style={{
                minWidth: 280,
                flex: 1,
                background: 'var(--colorBgLayout, #f5f5f5)',
                borderRadius: 8,
                padding: 12,
              }}
            >
              <div
                style={{
                  marginBottom: 12,
                  display: 'flex',
                  alignItems: 'center',
                  gap: 8,
                }}
              >
                <Typography.Text strong>{lane}</Typography.Text>
                <Tag>{items.length}</Tag>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                {items.map((item) => (
                  <Card
                    key={item.id}
                    id={item.id}
                    size="small"
                    style={{
                      cursor: enableDrag ? 'grab' : 'default',
                      opacity: activeId === item.id ? 0.4 : 1,
                    }}
                  >
                    <Typography.Text strong>
                      {item.data?.[cardTitleField] ?? '-'}
                    </Typography.Text>
                    {cardSubtitleField && item.data?.[cardSubtitleField] && (
                      <div>
                        <Typography.Text type="secondary">
                          {item.data[cardSubtitleField]}
                        </Typography.Text>
                      </div>
                    )}
                    {cardFields && (
                      <div style={{ marginTop: 4 }}>
                        {cardFields.map(
                          (f) =>
                            item.data?.[f] ? (
                              <Tag key={f}>{String(item.data[f])}</Tag>
                            ) : null,
                        )}
                      </div>
                    )}
                  </Card>
                ))}
              </div>
            </div>
          );
        })}
      </div>
      <DragOverlay>
        {activeCard ? (
          <Card
            size="small"
            style={{
              cursor: 'grabbing',
              boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
              width: 260,
            }}
          >
            <Typography.Text strong>
              {activeCard.data?.[cardTitleField] ?? '-'}
            </Typography.Text>
            {cardSubtitleField && activeCard.data?.[cardSubtitleField] && (
              <div>
                <Typography.Text type="secondary">
                  {activeCard.data[cardSubtitleField]}
                </Typography.Text>
              </div>
            )}
          </Card>
        ) : null}
      </DragOverlay>
    </DndContext>
  );
}

// ── 路由入口：自加载 schema ──

/**
 * 路由入口组件
 * 路由: /plugins/:pluginId/kanban/:entityName
 * 自动加载 schema 并提取 kanban 页面配置
 */
export default function PluginKanbanPageRoute() {
  const { pluginId, entityName } = useParams<{
    pluginId: string;
    entityName: string;
  }>();
  const [loading, setLoading] = useState(true);
  const [pageConfig, setPageConfig] = useState<{
    entity: string;
    lane_field: string;
    lane_order?: string[];
    card_title_field: string;
    card_subtitle_field?: string;
    card_fields?: string[];
    enable_drag?: boolean;
  } | null>(null);

  useEffect(() => {
    if (!pluginId || !entityName) return;

    async function loadSchema() {
      try {
        const schema = await getPluginSchema(pluginId!);
        const pages: PluginPageSchema[] = schema.ui?.pages || [];
        const kanbanPage = pages.find(
          (p): p is PluginPageSchema & { type: 'kanban' } =>
            p.type === 'kanban' && p.entity === entityName,
        );
        if (kanbanPage) {
          setPageConfig(kanbanPage);
        }
      } catch {
        message.warning('Schema 加载失败');
      } finally {
        setLoading(false);
      }
    }

    loadSchema();
  }, [pluginId, entityName]);

  if (loading) {
    return (
      <div style={{ padding: 24, textAlign: 'center' }}>
        <Spin />
      </div>
    );
  }

  if (!pageConfig) {
    return <div style={{ padding: 24 }}>未找到看板页面配置</div>;
  }

  return (
    <KanbanInner
      pluginId={pluginId!}
      entity={pageConfig.entity}
      laneField={pageConfig.lane_field}
      laneOrder={pageConfig.lane_order || []}
      cardTitleField={pageConfig.card_title_field}
      cardSubtitleField={pageConfig.card_subtitle_field}
      cardFields={pageConfig.card_fields}
      enableDrag={pageConfig.enable_drag}
    />
  );
}

// ── Tabs/Detail 内嵌使用 ──

export interface PluginKanbanPageFromConfigProps {
  pluginId: string;
  page: {
    entity: string;
    lane_field: string;
    lane_order?: string[];
    card_title_field: string;
    card_subtitle_field?: string;
    card_fields?: string[];
    enable_drag?: boolean;
  };
}

export function PluginKanbanPageFromConfig({
  pluginId,
  page,
}: PluginKanbanPageFromConfigProps) {
  return (
    <KanbanInner
      pluginId={pluginId}
      entity={page.entity}
      laneField={page.lane_field}
      laneOrder={page.lane_order || []}
      cardTitleField={page.card_title_field}
      cardSubtitleField={page.card_subtitle_field}
      cardFields={page.card_fields}
      enableDrag={page.enable_drag}
    />
  );
}
