"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import {
  Button,
  Input,
  Table,
  Space,
  Spin,
  Alert,
  Typography,
  Empty,
  Modal,
  Checkbox,
  AutoComplete,
} from "antd";
import { SearchOutlined, SettingOutlined, HolderOutlined, ClockCircleOutlined, DownloadOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import {
  DndContext,
  closestCenter,
  PointerSensor,
  useSensor,
  useSensors,
} from "@dnd-kit/core";
import type { DragEndEvent } from "@dnd-kit/core";
import {
  SortableContext,
  useSortable,
  verticalListSortingStrategy,
  arrayMove,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { nextLockedRow, type DataRow } from "./table-filters";

const { Title, Text } = Typography;

interface ColumnConfig {
  key: string;
  visible: boolean;
}

const COLUMN_DEFS: { key: string; width: number }[] = [
  { key: "ID", width: 70 },
  { key: "总排号", width: 100 },
  { key: "序号", width: 60 },
  { key: "生产订单号", width: 150 },
  { key: "车间号", width: 100 },
  { key: "订单号", width: 120 },
  { key: "经办人", width: 80 },
  { key: "签订日期", width: 110 },
  { key: "交货日期", width: 110 },
  { key: "客户名称", width: 180 },
  { key: "产品型号", width: 200 },
  { key: "量程", width: 120 },
  { key: "数量", width: 60 },
  { key: "技术参数", width: 300 },
  { key: "车间", width: 80 },
  { key: "工令号", width: 100 },
  { key: "备注", width: 150 },
  { key: "隔膜类型", width: 100 },
  { key: "标准", width: 80 },
  { key: "隔膜大小", width: 100 },
  { key: "隔膜材质", width: 100 },
  { key: "膜片尺寸", width: 100 },
  { key: "膜片材质", width: 100 },
  { key: "新参数", width: 300 },
  { key: "盘号", width: 80 },
  { key: "特殊要求", width: 200 },
  { key: "位号", width: 80 },
  { key: "CRM订单明细ID", width: 160 },
  { key: "成品物料码", width: 120 },
  { key: "接单日期", width: 110 },
  { key: "执行卡下发日期", width: 130 },
  { key: "缺件明细", width: 250 },
  { key: "物料类别", width: 100 },
  { key: "焊接领料日期", width: 130 },
  { key: "领料单签收日期", width: 140 },
  { key: "库房发出日期", width: 130 },
  { key: "焊接接收日期", width: 130 },
  { key: "操作者", width: 80 },
  { key: "日期", width: 110 },
  { key: "超压日期", width: 110 },
  { key: "退火日期", width: 110 },
  { key: "氦测日期", width: 110 },
  { key: "壳焊接员", width: 80 },
  { key: "表壳焊接日期", width: 130 },
  { key: "隔膜接收", width: 110 },
  { key: "隔离膜片接收", width: 140 },
  { key: "车波纹日期", width: 110 },
  { key: "膜片焊", width: 110 },
  { key: "喷涂发出", width: 110 },
  { key: "喷涂回来", width: 110 },
  { key: "调校人", width: 80 },
  { key: "调试日期", width: 110 },
  { key: "检验员", width: 80 },
  { key: "检验日期", width: 110 },
  { key: "入库日期", width: 110 },
  { key: "烘洗", width: 110 },
];

const DEFAULT_CONFIG: ColumnConfig[] = COLUMN_DEFS.map((d) => ({
  key: d.key,
  visible: true,
}));

const STORAGE_KEY = "web-table-column-config";

function loadConfig(): ColumnConfig[] {
  try {
    const saved = localStorage.getItem(STORAGE_KEY);
    if (saved) {
      const parsed: ColumnConfig[] = JSON.parse(saved);
      const savedKeys = new Set(parsed.map((c) => c.key));
      if (COLUMN_DEFS.every((d) => savedKeys.has(d.key))) return parsed;
    }
  } catch {
    /* ignore */
  }
  return DEFAULT_CONFIG.map((c) => ({ ...c }));
}

function saveConfig(config: ColumnConfig[]) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(config));
}

function buildTableColumns(
  config: ColumnConfig[],
  dataColumns: string[]
): ColumnsType<DataRow> {
  const available = new Set(dataColumns);
  return config
    .filter((c) => c.visible && available.has(c.key))
    .map((c) => {
      const def = COLUMN_DEFS.find((d) => d.key === c.key);
      return {
        title: c.key,
        dataIndex: c.key,
        key: c.key,
        width: def?.width ?? 120,
        ellipsis: true,
        render: (val: string | number | null) =>
          val === null || val === undefined ? "" : String(val),
      };
    });
}

/* ─── Sortable Row in Modal ─── */

function SortableRow({
  id,
  label,
  visible,
  onToggle,
}: {
  id: string;
  label: string;
  visible: boolean;
  onToggle: () => void;
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id });
  const style: React.CSSProperties = {
    transform: CSS.Transform.toString(transform),
    transition,
    display: "flex",
    alignItems: "center",
    gap: 8,
    padding: "6px 8px",
    borderBottom: "1px solid #f5f5f5",
    background: isDragging ? "#e6f4ff" : "#fff",
    cursor: "default",
  };

  return (
    <div ref={setNodeRef} style={style}>
      <span
        {...attributes}
        {...listeners}
        style={{ cursor: "grab", color: "#bbb", fontSize: 16, flexShrink: 0 }}
      >
        <HolderOutlined />
      </span>
      <Checkbox checked={visible} onChange={onToggle} style={{ flexShrink: 0 }} />
      <span style={{ userSelect: "none" }}>{label}</span>
    </div>
  );
}

/* ─── Column Settings Modal ─── */

function ColumnSettingsModal({
  open,
  config,
  onApply,
  onCancel,
}: {
  open: boolean;
  config: ColumnConfig[];
  onApply: (newConfig: ColumnConfig[]) => void;
  onCancel: () => void;
}) {
  const [local, setLocal] = useState<ColumnConfig[]>([]);
  const [search, setSearch] = useState("");
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));

  // Sync when modal opens
  useEffect(() => {
    if (open) {
      setLocal(config.map((c) => ({ ...c })));
      setSearch("");
    }
  }, [open, config]);

  const filtered = search
    ? local.filter((c) => c.key.toLowerCase().includes(search.toLowerCase()))
    : local;

  const visibleCount = local.filter((c) => c.visible).length;

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (!over || active.id === over.id) return;
    setLocal((prev) => {
      const oldIdx = prev.findIndex((c) => c.key === active.id);
      const newIdx = prev.findIndex((c) => c.key === over.id);
      return arrayMove(prev, oldIdx, newIdx);
    });
  };

  const toggle = (key: string) => {
    setLocal((prev) =>
      prev.map((c) => (c.key === key ? { ...c, visible: !c.visible } : c))
    );
  };

  const selectAll = () => setLocal((prev) => prev.map((c) => ({ ...c, visible: true })));
  const deselectAll = () => setLocal((prev) => prev.map((c) => ({ ...c, visible: false })));
  const resetDefault = () => setLocal(DEFAULT_CONFIG.map((c) => ({ ...c })));

  return (
    <Modal
      title="列设置"
      open={open}
      onCancel={onCancel}
      width={480}
      footer={[
        <Button key="cancel" onClick={onCancel}>
          取消
        </Button>,
        <Button key="apply" type="primary" onClick={() => onApply(local)}>
          确定 ({visibleCount}/{local.length})
        </Button>,
      ]}
    >
      <div style={{ marginBottom: 12, display: "flex", gap: 8, flexWrap: "wrap" }}>
        <Input
          placeholder="搜索字段名"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          allowClear
          style={{ width: 180 }}
          size="small"
        />
        <Button size="small" onClick={selectAll}>
          全选
        </Button>
        <Button size="small" onClick={deselectAll}>
          取消全选
        </Button>
        <Button size="small" onClick={resetDefault}>
          恢复默认
        </Button>
      </div>

      <div style={{ maxHeight: 420, overflowY: "auto", border: "1px solid #f0f0f0", borderRadius: 6 }}>
        <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
          <SortableContext items={filtered.map((c) => c.key)} strategy={verticalListSortingStrategy}>
            {filtered.map((c) => (
              <SortableRow
                key={c.key}
                id={c.key}
                label={c.key}
                visible={c.visible}
                onToggle={() => toggle(c.key)}
              />
            ))}
          </SortableContext>
        </DndContext>
      </div>
    </Modal>
  );
}

/* ─── Search History ─── */

const HISTORY_KEY = "web-table-search-history";
const MAX_HISTORY = 10;

function loadHistory(): string[] {
  try {
    const saved = localStorage.getItem(HISTORY_KEY);
    return saved ? JSON.parse(saved) : [];
  } catch {
    return [];
  }
}

function saveHistoryToStorage(history: string[]) {
  localStorage.setItem(HISTORY_KEY, JSON.stringify(history));
}

function addToHistory(value: string, history: string[]): string[] {
  const filtered = history.filter((h) => h !== value);
  return [value, ...filtered].slice(0, MAX_HISTORY);
}

/* ─── Search Bar (isolated) ─── */

function SearchBar({
  loading,
  resultCount,
  searched,
  onSearch,
  onClear,
  onOpenColumnSettings,
  exporting,
  onExport,
}: {
  loading: boolean;
  resultCount: number;
  searched: boolean;
  onSearch: (workshopNo: string) => Promise<void>;
  onClear: () => void;
  onOpenColumnSettings: () => void;
  exporting: boolean;
  onExport: () => void;
}) {
  const [inputValue, setInputValue] = useState("");
  const [history, setHistory] = useState<string[]>(() => loadHistory());
  const [open, setOpen] = useState(false);

  const filteredHistory = inputValue
    ? history.filter((h) => h.toLowerCase().includes(inputValue.toLowerCase()))
    : history;

  const options = filteredHistory.map((h) => ({
    value: h,
    label: (
      <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <ClockCircleOutlined style={{ color: "#bbb" }} />
        {h}
      </span>
    ),
  }));

  const handleSearch = useCallback(() => {
    const val = inputValue.trim();
    if (!val) return;
    const updated = addToHistory(val, history);
    setHistory(updated);
    saveHistoryToStorage(updated);
    onSearch(val);
  }, [inputValue, history, onSearch]);

  const handleSelect = useCallback(
    (val: string) => {
      setInputValue(val);
      const updated = addToHistory(val, history);
      setHistory(updated);
      saveHistoryToStorage(updated);
      onSearch(val);
    },
    [history, onSearch]
  );

  return (
    <div
      style={{
        flexShrink: 0,
        padding: "16px 24px",
        borderBottom: "1px solid #f0f0f0",
        background: "#fff",
      }}
    >
      <Title level={4} style={{ margin: 0, marginBottom: 12 }}>
        压力表合同生产数据
      </Title>
      <Space>
        <Space.Compact>
          <AutoComplete
            open={open && filteredHistory.length > 0}
            options={options}
            value={inputValue}
            onChange={(val) => setInputValue(val)}
            onSelect={handleSelect}
            onFocus={() => setOpen(true)}
            onBlur={() => setOpen(false)}
            style={{ width: 320 }}
          >
            <Input
              prefix={<SearchOutlined />}
              placeholder="支持模糊搜索，输入排产号数字部分即可查询"
              onPressEnter={handleSearch}
              allowClear
            />
          </AutoComplete>
          <Button type="primary" onClick={handleSearch} loading={loading}>
            查询
          </Button>
          <Button onClick={onClear}>清除</Button>
        </Space.Compact>
        <Button icon={<SettingOutlined />} onClick={onOpenColumnSettings}>
          列设置
        </Button>
        <Button
          icon={<DownloadOutlined />}
          onClick={onExport}
          loading={exporting}
        >
          导出全部
        </Button>
      </Space>
      {searched && !loading && (
        <Text type="secondary" style={{ marginLeft: 16 }}>
          共 {resultCount} 条记录
        </Text>
      )}
    </div>
  );
}

/* ─── Main Page ─── */

export default function Home() {
  const [data, setData] = useState<DataRow[]>([]);
  const [columns, setColumns] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [searched, setSearched] = useState(false);
  const [columnConfig, setColumnConfig] = useState<ColumnConfig[]>(loadConfig);
  const [modalOpen, setModalOpen] = useState(false);
  const [exporting, setExporting] = useState(false);
  const [lockedRowKey, setLockedRowKey] = useState<string | null>(null);

  // Persist config
  useEffect(() => {
    saveConfig(columnConfig);
  }, [columnConfig]);

  const handleSearch = useCallback(async (workshopNo: string) => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch(
        `/api/production-data?workshopNo=${encodeURIComponent(workshopNo)}`
      );
      const json = await res.json();
      if (!res.ok) {
        setError(json.error || "查询失败");
        return;
      }
      setColumns(json.columns);
      setData(json.data);
      setSearched(true);
      setLockedRowKey(null);
    } catch {
      setError("网络请求失败");
    } finally {
      setLoading(false);
    }
  }, []);

  const handleClear = useCallback(() => {
    setData([]);
    setColumns([]);
    setSearched(false);
    setError(null);
    setLockedRowKey(null);
  }, []);

  const handleExport = useCallback(async () => {
    setExporting(true);
    try {
      const res = await fetch("/api/export-excel");
      if (!res.ok) {
        const json = await res.json().catch(() => null);
        setError(json?.error || "导出失败");
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = "压力表合同生产数据.xlsx";
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    } catch {
      setError("导出请求失败");
    } finally {
      setExporting(false);
    }
  }, []);

  const handleApplyConfig = useCallback((newConfig: ColumnConfig[]) => {
    setColumnConfig(newConfig);
    setModalOpen(false);
  }, []);

  const tableColumns = useMemo(
    () => buildTableColumns(columnConfig, columns),
    [columnConfig, columns]
  );
  const totalWidth = useMemo(
    () => tableColumns.reduce((sum, col) => sum + (col.width as number), 0),
    [tableColumns]
  );
  const scrollConfig = useMemo(
    () => ({ x: totalWidth, y: "calc(100vh - 140px)" }),
    [totalWidth]
  );

  return (
    <div style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
      <SearchBar
        loading={loading}
        resultCount={data.length}
        searched={searched}
        onSearch={handleSearch}
        onClear={handleClear}
        onOpenColumnSettings={() => setModalOpen(true)}
        exporting={exporting}
        onExport={handleExport}
      />

      <div style={{ flex: 1, minHeight: 0 }}>
        {error && (
          <Alert
            message={error}
            type="error"
            showIcon
            style={{ margin: "16px 24px" }}
          />
        )}

        {loading && (
          <div
            style={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              height: "100%",
            }}
          >
            <Spin size="large" tip="查询中..." />
          </div>
        )}

        {!loading && !error && !searched && (
          <div
            style={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              height: "100%",
            }}
          >
            <Empty description="请输入车间号并点击查询" />
          </div>
        )}

        {!loading && !error && searched && data.length > 0 && (
          <Table<DataRow>
            columns={tableColumns}
            dataSource={data}
            rowKey="ID"
            onRow={(record) => ({
              onClick: () =>
                setLockedRowKey((prev) => nextLockedRow(prev, String(record.ID))),
            })}
            rowClassName={(record) =>
              String(record.ID) === lockedRowKey ? "row-locked" : ""
            }
            bordered
            size="small"
            pagination={false}
            scroll={scrollConfig}
            sticky
          />
        )}

        {!loading && !error && searched && data.length === 0 && (
          <div
            style={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              height: "100%",
            }}
          >
            <Empty description="未找到匹配的数据" />
          </div>
        )}
      </div>

      <ColumnSettingsModal
        open={modalOpen}
        config={columnConfig}
        onApply={handleApplyConfig}
        onCancel={() => setModalOpen(false)}
      />
    </div>
  );
}
