'use client';

import * as React from 'react';
import { QRInput } from './QRInput';
import { QRPreview } from './QRPreview';
import { QROptions } from './QROptions';
import { generateSvg, generateDataUrl } from '@/lib/qrcode/qrcodeService';
import { decodeQRFromUrl, updateQRUrl, getQRShareableUrl } from '@/lib/qrcode/urlSharing';
import { downloadBlob } from '@/lib/media/utils/fileUtils';
import { debounce } from '@/lib/utils/debounce';
import { toast } from 'sonner';
import { cn } from '@/lib/utils/cn';
import { MobileTabs } from '@/components/ui/mobile-tabs';
import type { ErrorCorrectionLevel, ExportSize } from '@/types/qrcode';

type MobileTab = 'configure' | 'preview';

export function QRCodeGenerator() {
  const [text, setText] = React.useState('https://kit.pivoine.art');
  const [errorCorrection, setErrorCorrection] = React.useState<ErrorCorrectionLevel>('M');
  const [foregroundColor, setForegroundColor] = React.useState('#000000');
  const [backgroundColor, setBackgroundColor] = React.useState('#ffffff');
  const [margin, setMargin] = React.useState(4);
  const [exportSize, setExportSize] = React.useState<ExportSize>(512);
  const [svgString, setSvgString] = React.useState('');
  const [isGenerating, setIsGenerating] = React.useState(false);
  const [mobileTab, setMobileTab] = React.useState<MobileTab>('configure');

  // Load state from URL on mount
  React.useEffect(() => {
    const urlState = decodeQRFromUrl();
    if (urlState) {
      if (urlState.text !== undefined) setText(urlState.text);
      if (urlState.errorCorrection) setErrorCorrection(urlState.errorCorrection);
      if (urlState.foregroundColor) setForegroundColor(urlState.foregroundColor);
      if (urlState.backgroundColor) setBackgroundColor(urlState.backgroundColor);
      if (urlState.margin !== undefined) setMargin(urlState.margin);
    }
  }, []);

  // Debounced generation
  const generate = React.useMemo(
    () =>
      debounce(async (t: string, ec: ErrorCorrectionLevel, fg: string, bg: string, m: number) => {
        if (!t) { setSvgString(''); setIsGenerating(false); return; }
        setIsGenerating(true);
        try {
          const svg = await generateSvg(t, ec, fg, bg, m);
          setSvgString(svg);
        } catch (error) {
          console.error('QR generation error:', error);
          setSvgString('');
          toast.error('Failed to generate QR code. Text may be too long.');
        } finally {
          setIsGenerating(false);
        }
      }, 200),
    [],
  );

  React.useEffect(() => {
    generate(text, errorCorrection, foregroundColor, backgroundColor, margin);
    updateQRUrl(text, errorCorrection, foregroundColor, backgroundColor, margin);
  }, [text, errorCorrection, foregroundColor, backgroundColor, margin, generate]);

  const handleDownloadPng = async () => {
    if (!text) return;
    try {
      const dataUrl = await generateDataUrl(text, errorCorrection, foregroundColor, backgroundColor, margin, exportSize);
      const res = await fetch(dataUrl);
      const blob = await res.blob();
      downloadBlob(blob, `qrcode-${Date.now()}.png`);
    } catch { toast.error('Failed to export PNG'); }
  };

  const handleDownloadSvg = () => {
    if (!svgString) return;
    const blob = new Blob([svgString], { type: 'image/svg+xml' });
    downloadBlob(blob, `qrcode-${Date.now()}.svg`);
  };

  const handleCopyImage = async () => {
    if (!text) return;
    try {
      const dataUrl = await generateDataUrl(text, errorCorrection, foregroundColor, backgroundColor, margin, exportSize);
      const res = await fetch(dataUrl);
      const blob = await res.blob();
      await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]);
      toast.success('Image copied to clipboard!');
    } catch { toast.error('Failed to copy image'); }
  };

  const handleShare = async () => {
    const shareUrl = getQRShareableUrl(text, errorCorrection, foregroundColor, backgroundColor, margin);
    try {
      await navigator.clipboard.writeText(shareUrl);
      toast.success('Shareable URL copied!');
    } catch { toast.error('Failed to copy URL'); }
  };

  return (
    <div className="flex flex-col gap-4">

      <MobileTabs
        tabs={[{ value: 'configure', label: 'Configure' }, { value: 'preview', label: 'Preview' }]}
        active={mobileTab}
        onChange={(v) => setMobileTab(v as MobileTab)}
      />

      {/* ── Main layout ─────────────────────────────────────── */}
      <div
        className="grid grid-cols-1 lg:grid-cols-5 gap-4"
        style={{ height: 'calc(100svh - 120px)'  }}
      >

        {/* Left: Input + Options */}
        <div className={cn('lg:col-span-2 flex flex-col overflow-hidden', mobileTab !== 'configure' && 'hidden lg:flex')}>
          <div className="glass rounded-xl p-4 flex flex-col flex-1 min-h-0 overflow-hidden">
            <div className="flex-1 min-h-0 overflow-y-auto scrollbar-thin scrollbar-thumb-primary/20 scrollbar-track-transparent pr-0.5 space-y-5">
              <QRInput value={text} onChange={setText} />
              <div className="border-t border-border/25" />
              <QROptions
                errorCorrection={errorCorrection}
                foregroundColor={foregroundColor}
                backgroundColor={backgroundColor}
                margin={margin}
                onErrorCorrectionChange={setErrorCorrection}
                onForegroundColorChange={setForegroundColor}
                onBackgroundColorChange={setBackgroundColor}
                onMarginChange={setMargin}
              />
            </div>
          </div>
        </div>

        {/* Right: Preview */}
        <div className={cn('lg:col-span-3 flex flex-col overflow-hidden', mobileTab !== 'preview' && 'hidden lg:flex')}>
          <QRPreview
            svgString={svgString}
            isGenerating={isGenerating}
            exportSize={exportSize}
            onExportSizeChange={setExportSize}
            onCopyImage={handleCopyImage}
            onShare={handleShare}
            onDownloadPng={handleDownloadPng}
            onDownloadSvg={handleDownloadSvg}
          />
        </div>
      </div>
    </div>
  );
}
