import { For, createMemo } from 'solid-js';
import { marked } from '../../markdown';
import { getLayerStyle } from './hooks/dimensions';
import type { DeckStore } from './hooks/deckStore';

export interface PrintPreviewProps {
  store: DeckStore;
  onClose: () => void;
  onPrint: () => void;
}

/**
 * 渲染 layer 内容
 */
function renderLayerContent(layer: { prop: string }, cardData: { [key: string]: string }): string {
  const content = cardData[layer.prop] || '';
  return marked.parse(content) as string;
}

/**
 * 打印预览组件：在 A4 纸张上排列所有卡牌
 */
export function PrintPreview(props: PrintPreviewProps) {
  const { store } = props;

  // A4 纸张尺寸（mm）：210 x 297
  const A4_WIDTH_PORTRAIT = 210;
  const A4_HEIGHT_PORTRAIT = 297;
  const A4_WIDTH_LANDSCAPE = 297;
  const A4_HEIGHT_LANDSCAPE = 210;
  const PRINT_MARGIN = 5; // 打印边距

  // 获取打印设置
  const orientation = () => store.state.printOrientation;
  const oddPageOffsetX = () => store.state.printOddPageOffsetX;
  const oddPageOffsetY = () => store.state.printOddPageOffsetY;

  // 根据方向获取 A4 尺寸
  const getA4Size = () => {
    if (orientation() === 'landscape') {
      return { width: A4_WIDTH_LANDSCAPE, height: A4_HEIGHT_LANDSCAPE };
    }
    return { width: A4_WIDTH_PORTRAIT, height: A4_HEIGHT_PORTRAIT };
  };

  // 计算每张卡牌在 A4 纸上的位置（居中布局）
  const pages = createMemo(() => {
    const cards = store.state.cards;
    const cardWidth = store.state.dimensions?.cardWidth || 56;
    const cardHeight = store.state.dimensions?.cardHeight || 88;
    const { width: a4Width, height: a4Height } = getA4Size();

    // 每行可容纳的卡牌数量
    const usableWidth = a4Width - PRINT_MARGIN * 2;
    const cardsPerRow = Math.floor(usableWidth / cardWidth);

    // 每页可容纳的行数
    const usableHeight = a4Height - PRINT_MARGIN * 2;
    const rowsPerPage = Math.floor(usableHeight / cardHeight);

    // 每页的卡牌数量
    const cardsPerPage = cardsPerRow * rowsPerPage;

    // 计算最大卡牌区域的尺寸（用于居中和外围框）
    const maxGridWidth = cardsPerRow * cardWidth;
    const maxGridHeight = rowsPerPage * cardHeight;

    // 居中偏移量（使卡牌区域在 A4 纸上居中）
    const baseOffsetX = (a4Width - maxGridWidth) / 2;
    const baseOffsetY = (a4Height - maxGridHeight) / 2;

    // 分页
    const result: {
      pageIndex: number;
      cards: Array<{ data: typeof cards[0]; x: number; y: number }>;
      bounds: { minX: number; minY: number; maxX: number; maxY: number };
    }[] = [];
    let currentPage: typeof result[0] = { pageIndex: 0, cards: [], bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity } };

    for (let i = 0; i < cards.length; i++) {
      const pageIndex = Math.floor(i / cardsPerPage);
      const indexInPage = i % cardsPerPage;
      const row = Math.floor(indexInPage / cardsPerRow);
      const col = indexInPage % cardsPerRow;

      if (pageIndex !== currentPage.pageIndex) {
        result.push(currentPage);
        currentPage = { pageIndex, cards: [], bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity } };
      }

      // 奇数页应用偏移（pageIndex 从 0 开始，所以偶数索引是奇数页）
      const isOddPage = pageIndex % 2 === 0;
      const pageOffsetX = isOddPage ? oddPageOffsetX() : 0;
      const pageOffsetY = isOddPage ? oddPageOffsetY() : 0;

      // 使用居中偏移量 + 奇数页偏移计算卡牌位置
      const cardX = baseOffsetX + col * cardWidth + pageOffsetX;
      const cardY = baseOffsetY + row * cardHeight + pageOffsetY;

      currentPage.cards.push({
        data: cards[i],
        x: cardX,
        y: cardY
      });

      // 更新边界（含 1mm 边距）
      currentPage.bounds.minX = Math.min(currentPage.bounds.minX, cardX);
      currentPage.bounds.minY = Math.min(currentPage.bounds.minY, cardY);
      currentPage.bounds.maxX = Math.max(currentPage.bounds.maxX, cardX + cardWidth);
      currentPage.bounds.maxY = Math.max(currentPage.bounds.maxY, cardY + cardHeight);
    }

    if (currentPage.cards.length > 0) {
      result.push(currentPage);
    }

    // 为每页添加固定的外围框尺寸（基于最大网格）
    return result.map(page => ({
      ...page,
      frameBounds: {
        minX: baseOffsetX + (page.pageIndex % 2 === 0 ? oddPageOffsetX() : 0),
        minY: baseOffsetY + (page.pageIndex % 2 === 0 ? oddPageOffsetY() : 0),
        maxX: baseOffsetX + maxGridWidth + (page.pageIndex % 2 === 0 ? oddPageOffsetX() : 0),
        maxY: baseOffsetY + maxGridHeight + (page.pageIndex % 2 === 0 ? oddPageOffsetY() : 0)
      }
    }));
  });

  // 计算裁切线和外围框位置
  const cropMarks = createMemo(() => {
    const pagesData = pages();
    return pagesData.map(page => {
      const { frameBounds, cards } = page;
      const cardWidth = store.state.dimensions?.cardWidth || 56;
      const cardHeight = store.state.dimensions?.cardHeight || 88;

      // 收集所有唯一的裁切线位置
      const xPositions = new Set<number>();
      const yPositions = new Set<number>();

      cards.forEach(card => {
        xPositions.add(card.x);
        xPositions.add(card.x + cardWidth);
        yPositions.add(card.y);
        yPositions.add(card.y + cardHeight);
      });

      const sortedX = Array.from(xPositions).sort((a, b) => a - b);
      const sortedY = Array.from(yPositions).sort((a, b) => a - b);

      // 裁切线超出外围框的距离
      const OVERLAP = 3; // 3mm

      // 生成水平裁切线（沿 Y 轴）
      const horizontalLines = sortedY.map(y => ({
        y,
        xStart: frameBounds.minX - OVERLAP,
        xEnd: frameBounds.maxX + OVERLAP
      }));

      // 生成垂直裁切线（沿 X 轴）
      const verticalLines = sortedX.map(x => ({
        x,
        yStart: frameBounds.minY - OVERLAP,
        yEnd: frameBounds.maxY + OVERLAP
      }));

      // 外围框边界（离卡牌区域边缘 1mm）
      const frameBoundsWithMargin = {
        x: frameBounds.minX - 1,
        y: frameBounds.minY - 1,
        width: frameBounds.maxX - frameBounds.minX + 2,
        height: frameBounds.maxY - frameBounds.minY + 2
      };

      return { horizontalLines, verticalLines, frameBounds, frameBoundsWithMargin };
    });
  });

  const visibleLayers = createMemo(() => store.state.layerConfigs.filter((l) => l.visible));

  return (
    <div class="fixed inset-0 bg-black/50 z-50 overflow-auto print:overflow-visible print:absolute">
      {/* 打印样式：根据方向设置 @page 规则 */}
      <style>{`
        @media print {
          @page {
            size: A4 ${orientation() === 'landscape' ? 'landscape' : 'portrait'};
            margin: 0;
          }
        }
      `}</style>
      <div class="min-h-screen py-20 px-4 print:p-0">
        {/* 打印预览控制栏 */}
        <div class="fixed top-0 left-0 right-0 z-50 bg-white shadow-lg rounded-lg mx-4 mt-4 px-4 py-3 flex items-center justify-between gap-4">
          <div class="flex items-center gap-4">
            <h2 class="text-base font-bold mt-0 mb-0">打印预览</h2>
            <p class="text-xs text-gray-500 mb-0">共 {pages().length} 页，{store.state.cards.length} 张卡牌</p>
          </div>
          <div class="flex items-center gap-4">
            {/* 方向选择 */}
            <div class="flex items-center gap-2">
              <label class="text-sm text-gray-600">方向:</label>
              <div class="flex gap-1">
                <button
                  onClick={() => store.actions.setPrintOrientation('portrait')}
                  class={`px-3 py-1 rounded text-sm font-medium cursor-pointer border ${
                    orientation() === 'portrait'
                      ? 'bg-blue-600 text-white border-blue-600'
                      : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'
                  }`}
                >
                  竖向
                </button>
                <button
                  onClick={() => store.actions.setPrintOrientation('landscape')}
                  class={`px-3 py-1 rounded text-sm font-medium cursor-pointer border ${
                    orientation() === 'landscape'
                      ? 'bg-blue-600 text-white border-blue-600'
                      : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'
                  }`}
                >
                  横向
                </button>
              </div>
            </div>
            {/* 奇数页偏移 */}
            <div class="flex items-center gap-2">
              <label class="text-sm text-gray-600">奇数页偏移:</label>
              <div class="flex items-center gap-1">
                <span class="text-xs text-gray-500">X:</span>
                <input
                  type="number"
                  value={oddPageOffsetX()}
                  onChange={(e) => store.actions.setPrintOddPageOffsetX(Number(e.target.value))}
                  class="w-16 px-2 py-1 border border-gray-300 rounded text-sm"
                  step="0.1"
                />
                <span class="text-xs text-gray-500 ml-1">mm</span>
              </div>
              <div class="flex items-center gap-1">
                <span class="text-xs text-gray-500">Y:</span>
                <input
                  type="number"
                  value={oddPageOffsetY()}
                  onChange={(e) => store.actions.setPrintOddPageOffsetY(Number(e.target.value))}
                  class="w-16 px-2 py-1 border border-gray-300 rounded text-sm"
                  step="0.1"
                />
                <span class="text-xs text-gray-500 ml-1">mm</span>
              </div>
            </div>
          </div>
          <div class="flex gap-2">
            <button
              onClick={props.onPrint}
              class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-1.5 rounded text-sm font-medium cursor-pointer flex items-center gap-2"
            >
              <span>🖨️</span>
              <span>打印</span>
            </button>
            <button
              onClick={props.onClose}
              class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-1.5 rounded text-sm font-medium cursor-pointer"
            >
              关闭
            </button>
          </div>
        </div>

        {/* A4 纸张预览 */}
        <div class="flex flex-col items-center gap-8 print-root">
          <For each={pages()}>
            {(page) => (
              <div
                class="bg-white shadow-xl print:shadow-none print:w-full"
                style={{
                  width: `${getA4Size().width}mm`,
                  height: `${getA4Size().height}mm`
                }}
                data-page={page.pageIndex + 1}
              >
                {/* 渲染该页的所有卡牌 */}
                <div class="relative w-full h-full">
                  {/* 裁切线和外围框层 */}
                  <svg class="absolute inset-0 w-full h-full pointer-events-none" style={{ overflow: 'visible' }}>
                    {/* 外围边框：黑色 0.2mm */}
                    <rect
                      x={`${cropMarks()[page.pageIndex]?.frameBoundsWithMargin.x}mm`}
                      y={`${cropMarks()[page.pageIndex]?.frameBoundsWithMargin.y}mm`}
                      width={`${cropMarks()[page.pageIndex]?.frameBoundsWithMargin.width}mm`}
                      height={`${cropMarks()[page.pageIndex]?.frameBoundsWithMargin.height}mm`}
                      fill="none"
                      stroke="black"
                      stroke-width="0.2"
                    />

                    {/* 水平裁切线 */}
                    <For each={cropMarks()[page.pageIndex]?.horizontalLines}>
                      {(line) => (
                        <>
                          {/* 左侧裁切线（外围框外部） */}
                          <line
                            x1={`${line.xStart}mm`}
                            y1={`${line.y}mm`}
                            x2={`${page.frameBounds.minX}mm`}
                            y2={`${line.y}mm`}
                            stroke="#888"
                            stroke-width="0.1"
                          />
                          {/* 右侧裁切线（外围框外部） */}
                          <line
                            x1={`${page.frameBounds.maxX}mm`}
                            y1={`${line.y}mm`}
                            x2={`${line.xEnd}mm`}
                            y2={`${line.y}mm`}
                            stroke="#888"
                            stroke-width="0.1"
                          />
                        </>
                      )}
                    </For>
                    {/* 垂直裁切线 */}
                    <For each={cropMarks()[page.pageIndex]?.verticalLines}>
                      {(line) => (
                        <>
                          {/* 上方裁切线（外围框外部） */}
                          <line
                            x1={`${line.x}mm`}
                            y1={`${line.yStart}mm`}
                            x2={`${line.x}mm`}
                            y2={`${page.frameBounds.minY}mm`}
                            stroke="#888"
                            stroke-width="0.1"
                          />
                          {/* 下方裁切线（外围框外部） */}
                          <line
                            x1={`${line.x}mm`}
                            y1={`${page.frameBounds.maxY}mm`}
                            x2={`${line.x}mm`}
                            y2={`${line.yEnd}mm`}
                            stroke="#888"
                            stroke-width="0.1"
                          />
                        </>
                      )}
                    </For>
                  </svg>

                  <For each={page.cards}>
                    {(card) => (
                      <div
                        class="absolute bg-white"
                        style={{
                          left: `${card.x}mm`,
                          top: `${card.y}mm`,
                          width: `${store.state.dimensions?.cardWidth}mm`,
                          height: `${store.state.dimensions?.cardHeight}mm`
                        }}
                      >
                        {/* 网格区域容器 */}
                        <div
                          class="absolute"
                          style={{
                            left: `${store.state.dimensions?.gridOriginX}mm`,
                            top: `${store.state.dimensions?.gridOriginY}mm`,
                            width: `${store.state.dimensions?.gridAreaWidth}mm`,
                            height: `${store.state.dimensions?.gridAreaHeight}mm`
                          }}
                        >
                          {/* 渲染每个 layer */}
                          <For each={visibleLayers()}>
                            {(layer) => (
                              <div
                                class="absolute flex items-center justify-center text-center prose prose-sm"
                                style={{
                                  ...getLayerStyle(layer, store.state.dimensions!),
                                  'font-size': `${store.state.dimensions?.fontSize}mm`
                                }}
                                innerHTML={renderLayerContent(layer, card.data)}
                              />
                            )}
                          </For>
                        </div>
                      </div>
                    )}
                  </For>
                </div>
              </div>
            )}
          </For>
        </div>
      </div>
    </div>
  );
}
