

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import Layout from '../../components/Layout';
import CardFrame, { CARD_W, CARD_H } from '../../components/designer/CardFrame';
import { Button } from '../../components/ui';
import { useAuth } from '../../lib/use-auth';

// US Letter at 300 DPI. Standard TCG card = 63 x 88 mm -> 744 x 1040 px.
const SHEET_W = 2550;
const SHEET_H = 3300;
const CARD_PRINT_W = 744;
const CARD_PRINT_H = 1040;
const CARD_SCALE = CARD_PRINT_W / CARD_W; // 420 -> 744

const LAYOUTS = {
  '3x3': { cols: 3, rows: 3, label: '3 × 3 (9 cards)' },
  '2x2': { cols: 2, rows: 2, label: '2 × 2 (4 cards)' },
};

export default function PrintSheet() {
  const router = useRouter();
  const { user, loading: authLoading } = useAuth();

  const [designs, setDesigns] = useState([]);
  const [symbolsMap, setSymbolsMap] = useState({});
  const [loading, setLoading] = useState(true);
  const [selected, setSelected] = useState(new Set());
  const [layout, setLayout] = useState('3x3');
  const [exporting, setExporting] = useState(false);
  const [error, setError] = useState(null);

  const sheetRef = useRef(null);

  useEffect(() => {
    if (!authLoading && !user) {
      router.push('/login');
    }
  }, [authLoading, user, router]);

  useEffect(() => {
    if (!user) return undefined;

    const load = async () => {
      try {
        const token = localStorage.getItem('auth_token');
        const headers = token ? { Authorization: `Bearer ${token}` } : {};
        const [cardsRes, symbolsRes] = await Promise.all([
          fetch('/api/custom-cards', { headers }),
          fetch('/api/custom-symbols', { headers }),
        ]);
        if (cardsRes.ok) {
          const data = await cardsRes.json();
          setDesigns(data.designs);
          // Preselect via ?ids=1,2,3 — otherwise everything.
          const idsParam = router.query.ids;
          if (typeof idsParam === 'string' && idsParam.length > 0) {
            const ids = new Set(
              idsParam.split(',').map((n) => parseInt(n, 10)).filter(Number.isInteger)
            );
            setSelected(new Set(data.designs.filter((d) => ids.has(d.id)).map((d) => d.id)));
          } else {
            setSelected(new Set(data.designs.map((d) => d.id)));
          }
        } else {
          setError('Failed to load your designs.');
        }
        if (symbolsRes.ok) {
          const data = await symbolsRes.json();
          setSymbolsMap(Object.fromEntries(data.symbols.map((s) => [s.code, s.image_url])));
        }
      } catch {
        setError('Failed to load your designs.');
      } finally {
        setLoading(false);
      }
    };

    load();
    return undefined;
  }, [user, router.query.ids]);

  const toggle = (id) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const selectedDesigns = useMemo(
    () => designs.filter((d) => selected.has(d.id)),
    [designs, selected]
  );

  // Preview scale so the full sheet fits the preview pane.
  const [previewScale, setPreviewScale] = useState(0.25);
  const previewWrapRef = useRef(null);

  const updatePreviewScale = useCallback(() => {
    const el = previewWrapRef.current;
    if (el) setPreviewScale(Math.min(0.35, el.clientWidth / SHEET_W));
  }, []);

  useEffect(() => {
    updatePreviewScale();
    const observer = new ResizeObserver(updatePreviewScale);
    if (previewWrapRef.current) observer.observe(previewWrapRef.current);
    return () => observer.disconnect();
  }, [updatePreviewScale]);

  const handleExport = async () => {
    if (!sheetRef.current || selectedDesigns.length === 0) return;
    setExporting(true);
    setError(null);
    try {
      const { toPng } = await import('html-to-image');
      const dataUrl = await toPng(sheetRef.current, {
        width: SHEET_W,
        height: SHEET_H,
        pixelRatio: 1,
        cacheBust: true,
      });
      const link = document.createElement('a');
      link.download = `deckhearth-print-sheet-${selectedDesigns.length}cards.png`;
      link.href = dataUrl;
      link.click();
    } catch {
      setError('Export failed. Please try again.');
    } finally {
      setExporting(false);
    }
  };

  if (loading) {
    return (
      <Layout user={user}>
        <div className="flex items-center justify-center min-h-screen">
          <div className="animate-spin rounded-full h-32 w-32 border-b-2" style={{ borderColor: 'var(--accent-ember)' }} />
        </div>
      </Layout>
    );
  }

  const { cols, rows } = LAYOUTS[layout];
  const perSheet = cols * rows;
  const slots = Array.from({ length: perSheet }, (_, i) => selectedDesigns[i] || null);
  const sheetCount = Math.max(1, Math.ceil(selectedDesigns.length / perSheet));

  return (
    <Layout user={user}>
      <div className="p-4 sm:p-6 max-w-[1500px] mx-auto space-y-6">
        <div className="pt-2 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
          <div>
            <h1 className="text-2xl sm:text-3xl font-bold mb-1" style={{ color: 'var(--text-primary)' }}>
              Print Sheet
            </h1>
            <p className="text-base" style={{ color: 'var(--text-secondary)' }}>
              Arrange cards on a US Letter sheet (63 × 88 mm cards, cut guides included).
            </p>
          </div>
          <div className="flex gap-2">
            <Button variant="secondary" onClick={() => router.push('/my-designs')}>Back</Button>
            <Button
              variant="primary"
              onClick={handleExport}
              disabled={exporting || selectedDesigns.length === 0}
            >
              {exporting ? 'Exporting…' : 'Download Sheet PNG'}
            </Button>
          </div>
        </div>

        {error && (
          <div className="glass-panel rounded-xl px-4 py-3 text-sm" style={{ color: '#f87171' }} role="alert">
            {error}
          </div>
        )}

        <div className="grid grid-cols-1 lg:grid-cols-[minmax(0,380px)_minmax(0,1fr)] gap-6">
          {/* Controls + card picker */}
          <div className="space-y-5 min-w-0">
            <section className="glass-panel rounded-2xl p-5 space-y-3">
              <h2 className="text-sm font-semibold uppercase tracking-wide" style={{ color: 'var(--text-secondary)' }}>
                Layout
              </h2>
              <div className="flex rounded-xl overflow-hidden border" style={{ borderColor: 'var(--border)' }}>
                {Object.entries(LAYOUTS).map(([key, cfg]) => (
                  <button
                    key={key}
                    type="button"
                    onClick={() => setLayout(key)}
                    className="flex-1 px-4 py-2 text-xs font-semibold transition-all duration-200"
                    style={{
                      backgroundColor: layout === key ? 'var(--accent-ember)' : 'var(--bg-tertiary)',
                      color: layout === key ? 'white' : 'var(--text-secondary)',
                    }}
                    aria-pressed={layout === key}
                  >
                    {cfg.label}
                  </button>
                ))}
              </div>
              <p className="text-xs" style={{ color: 'var(--text-secondary)' }}>
                {selectedDesigns.length} card{selectedDesigns.length === 1 ? '' : 's'} selected
                {selectedDesigns.length > perSheet
                  ? ` · ${sheetCount} sheets (export one at a time)`
                  : ''}
              </p>
            </section>

            <section className="glass-panel rounded-2xl p-5">
              <h2 className="text-sm font-semibold uppercase tracking-wide mb-3" style={{ color: 'var(--text-secondary)' }}>
                Cards
              </h2>
              {designs.length === 0 ? (
                <p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
                  No designs yet — create some in the{' '}
                  <Link href="/designer" style={{ color: 'var(--accent-ember)' }}>designer</Link> first.
                </p>
              ) : (
                <div className="space-y-2 max-h-[480px] overflow-y-auto pr-1">
                  {designs.map((design) => (
                    <label
                      key={design.id}
                      className="flex items-center gap-3 rounded-xl px-3 py-2 cursor-pointer transition-all duration-150 hover:shadow-md"
                      style={{ backgroundColor: 'var(--bg-tertiary)' }}
                    >
                      <input
                        type="checkbox"
                        checked={selected.has(design.id)}
                        onChange={() => toggle(design.id)}
                        className="w-4 h-4"
                      />
                      <span className="text-sm truncate" style={{ color: 'var(--text-primary)' }}>
                        {design.name}
                      </span>
                    </label>
                  ))}
                </div>
              )}
            </section>
          </div>

          {/* Sheet preview */}
          <div>
            <div className="glass-panel rounded-2xl p-5">
              <h2 className="text-sm font-semibold uppercase tracking-wide mb-4" style={{ color: 'var(--text-secondary)' }}>
                Sheet Preview
              </h2>
              <div ref={previewWrapRef} style={{ width: '100%', overflow: 'hidden' }}>
                <div
                  style={{
                    width: SHEET_W * previewScale,
                    height: SHEET_H * previewScale,
                    margin: '0 auto',
                  }}
                >
                  <div style={{ transform: `scale(${previewScale})`, transformOrigin: 'top left' }}>
                    <PrintSheetSurface
                      slots={slots}
                      cols={cols}
                      rows={rows}
                      sheetRef={sheetRef}
                      symbolsMap={symbolsMap}
                    />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </Layout>
  );
}

/**
 * The actual 2550x3300 print surface. Cards render at natural 420x588
 * then scale up 1.771x to true print size; dashed guides mark cut lines.
 */
function PrintSheetSurface({ slots, cols, rows, sheetRef, symbolsMap }) {
  const marginX = (SHEET_W - cols * CARD_PRINT_W) / 2;
  const marginTop = (SHEET_H - rows * CARD_PRINT_H) / 2;

  return (
    <div
      ref={sheetRef}
      style={{
        width: SHEET_W,
        height: SHEET_H,
        backgroundColor: '#ffffff',
        position: 'relative',
        fontFamily: 'Georgia, serif',
      }}
    >
      {slots.map((design, i) => {
        const col = i % cols;
        const row = Math.floor(i / cols);
        const x = marginX + col * CARD_PRINT_W;
        const y = marginTop + row * CARD_PRINT_H;
        return (
          <div
            key={design ? design.id : `empty-${i}`}
            style={{
              position: 'absolute',
              left: x,
              top: y,
              width: CARD_PRINT_W,
              height: CARD_PRINT_H,
              outline: '2px dashed rgba(0,0,0,0.25)',
              overflow: 'hidden',
              backgroundColor: design ? 'transparent' : '#fafafa',
            }}
          >
            {design && (
              <div style={{ transform: `scale(${CARD_SCALE})`, transformOrigin: 'top left' }}>
                <CardFrame design={design} symbols={symbolsMap} />
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}
