import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  Button,
  Card,
  Input,
  Popconfirm,
  Select,
  Space,
  Switch,
  Table,
  Tag,
  Tooltip,
  Typography,
  message,
} from 'antd';
import {
  DeleteOutlined,
  EditOutlined,
  EyeOutlined,
  PlusOutlined,
  ReloadOutlined,
} from '@ant-design/icons';
import { useSearchParams, useNavigate } from 'react-router-dom';
import { customRequest } from 'helpers/http';
import type { WorkflowNodeType } from '../types';

const { Title } = Typography;
const PAGE_SIZE = 20;

interface NodeInstance {
  id: string;
  nodeTypeId: string;
  name: string;
  description: string | null;
  config: Record<string, any>;
  isEnabled: boolean;
  creator: string;
  createdAt: string;
  updatedAt: string;
  nodeType?: { label: string; category: string };
}

export default function NodeInstanceListPage() {
  const navigate = useNavigate();
  const [data, setData] = useState<NodeInstance[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [nodeTypes, setNodeTypes] = useState<WorkflowNodeType[]>([]);

  const [searchParams, setSearchParams] = useSearchParams();
  const filterNodeType = searchParams.get('nodeTypeId') || undefined;
  const filterName = searchParams.get('name') || undefined;
  const page = Number(searchParams.get('page')) || 1;

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

  const updateParams = useCallback(
    (updates: Record<string, string | undefined>) => {
      setSearchParams(
        (prev) => {
          const next = new URLSearchParams(prev);
          for (const [k, v] of Object.entries(updates)) {
            if (v) next.set(k, v);
            else next.delete(k);
          }
          return next;
        },
        { replace: true },
      );
    },
    [setSearchParams],
  );

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const where: Record<string, any> = {};
      if (filterNodeType) where.nodeTypeId = Number(filterNodeType);
      if (filterName) where.name = { contains: filterName };

      const res = await customRequest<{
        data: NodeInstance[];
        meta: { itemCount: number };
      }>('workflowNodeInstance/findMany', 'POST', {
        skip: (page - 1) * PAGE_SIZE,
        take: PAGE_SIZE,
        where,
        orderBy: { id: 'desc' },
        include: { nodeType: { select: { label: true, category: true } } },
      });
      setData(res.data);
      setTotal(res.meta.itemCount);
    } catch (e: any) {
      message.error(e?.message ?? 'Failed to fetch data');
    } finally {
      setLoading(false);
    }
  }, [page, filterNodeType, filterName]);

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

  // Load node types for filter
  useEffect(() => {
    customRequest<WorkflowNodeType[]>('workflow-node-types', 'GET')
      .then(setNodeTypes)
      .catch(() => {});
  }, []);

  async function handleToggleEnabled(record: NodeInstance) {
    try {
      await customRequest(
        `workflowNodeInstance/updateUnique/${record.id}`,
        'PATCH',
        {
          isEnabled: !record.isEnabled,
        },
      );
      message.success(record.isEnabled ? 'Disabled' : 'Enabled');
      fetchData();
    } catch (e: any) {
      message.error(e?.message ?? 'Update failed');
    }
  }

  async function handleDelete(id: string) {
    try {
      await customRequest(`workflowNodeInstance/deleteUnique/${id}`, 'DELETE');
      message.success('Deleted');
      fetchData();
    } catch (e: any) {
      message.error(e?.message ?? 'Delete failed');
    }
  }

  const columns = [
    {
      title: '',
      dataIndex: 'isEnabled',
      key: 'isEnabled',
      width: 50,
      render: (val: boolean, record: NodeInstance) => (
        <Popconfirm
          title={
            val ? 'Disable this node instance?' : 'Enable this node instance?'
          }
          onConfirm={() => handleToggleEnabled(record)}
          okText="Confirm"
          cancelText="Cancel"
        >
          <Switch size="small" checked={val} />
        </Popconfirm>
      ),
    },
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      render: (name: string, record: NodeInstance) => (
        <a
          onClick={() =>
            navigate(`/admin/workflow/node-instances/show/${record.id}`)
          }
        >
          {name}
        </a>
      ),
    },
    {
      title: 'Node Type',
      key: 'nodeType',
      render: (_: any, record: NodeInstance) => (
        <Tag>{record.nodeType?.label ?? '—'}</Tag>
      ),
    },
    {
      title: 'Updated',
      dataIndex: 'updatedAt',
      key: 'updatedAt',
      width: 150,
      render: (v: string) => (
        <Tooltip title={new Date(v).toLocaleString()}>
          <span>{new Date(v).toLocaleDateString()}</span>
        </Tooltip>
      ),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 120,
      render: (_: any, record: NodeInstance) => (
        <Space>
          <Tooltip title="View">
            <Button
              size="small"
              icon={<EyeOutlined />}
              onClick={() =>
                navigate(`/admin/workflow/node-instances/show/${record.id}`)
              }
            />
          </Tooltip>
          <Tooltip title="Edit">
            <Button
              size="small"
              icon={<EditOutlined />}
              onClick={() =>
                navigate(`/admin/workflow/node-instances/edit/${record.id}`)
              }
            />
          </Tooltip>
          <Popconfirm
            title="Delete this instance?"
            okText="Delete"
            cancelText="Cancel"
            okButtonProps={{ danger: true }}
            onConfirm={() => handleDelete(record.id)}
          >
            <Tooltip title="Delete">
              <Button size="small" danger icon={<DeleteOutlined />} />
            </Tooltip>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div style={{ background: '#f0f2f5', minHeight: 'calc(100vh - 64px)' }}>
      <Card style={{ marginBottom: 16 }}>
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          <Title level={4} style={{ margin: 0 }}>
            Node instance mgnts
          </Title>
          <Space>
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={() => navigate('/admin/workflow/node-instances/create')}
            >
              New Instance
            </Button>
            <Button icon={<ReloadOutlined />} onClick={fetchData} />
          </Space>
        </div>
      </Card>

      <Card style={{ marginBottom: 16 }}>
        <Space wrap>
          <Select
            placeholder="Node Type"
            allowClear
            value={filterNodeType}
            onChange={(v) => updateParams({ nodeTypeId: v, page: undefined })}
            style={{ width: 200 }}
            showSearch
            optionFilterProp="label"
            options={nodeTypes.map((nt) => ({
              label: `${nt.label} (${nt.category})`,
              value: String(nt.id),
            }))}
          />
          <Input
            placeholder="Search by name"
            allowClear
            defaultValue={filterName}
            onChange={(e) => {
              const v = e.target.value;
              if (debounceRef.current) clearTimeout(debounceRef.current);
              debounceRef.current = setTimeout(
                () => updateParams({ name: v || undefined, page: undefined }),
                300,
              );
            }}
            style={{ width: 220 }}
          />
        </Space>
      </Card>

      <Card>
        <Table
          rowKey="id"
          loading={loading}
          columns={columns}
          dataSource={data}
          pagination={{
            current: page,
            pageSize: PAGE_SIZE,
            total,
            onChange: (p) =>
              updateParams({ page: p > 1 ? String(p) : undefined }),
            showTotal: (t) => `Total ${t}`,
          }}
          size="small"
        />
      </Card>
    </div>
  );
}
