'use client';

import { useState, useRef, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css';
import { SigningProgressBar } from './SigningProgressBar';
import { SignatureModal } from './SignatureModal';
import type { SignatureFieldData } from '@/lib/db/schema';
import { getFieldType } from '@/lib/db/schema';

// Worker setup — reuse same pattern as PdfViewerWrapper (no CDN, works in local/Docker)
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.mjs',
  import.meta.url,
).toString();

// PDF rendered at a fixed width for consistent coordinate math
const PDF_RENDER_WIDTH = 800;

interface PageDimensions {
  renderedWidth: number;
  renderedHeight: number;
  originalWidth: number;
  originalHeight: number;
}

export interface SignatureCapture {
  fieldId: string;
  dataURL: string;
}

interface SigningPageClientProps {
  token: string;
  documentName: string;
  signatureFields: SignatureFieldData[];
}

export function SigningPageClient({
  token,
  documentName,
  signatureFields,
}: SigningPageClientProps) {
  const router = useRouter();
  const [numPages, setNumPages] = useState(0);
  // Map from page number (1-indexed) to rendered dimensions
  const [pageDimensions, setPageDimensions] = useState<Record<number, PageDimensions>>({});
  // Map of fieldId -> dataURL for signed fields
  const [signedFields, setSignedFields] = useState<Map<string, string>>(new Map());
  const [submitting, setSubmitting] = useState(false);

  // Modal state
  const [modalOpen, setModalOpen] = useState(false);
  const [activeFieldId, setActiveFieldId] = useState<string | null>(null);
  const [activeFieldType, setActiveFieldType] = useState<'client-signature' | 'initials'>('client-signature');

  // Ref for all captured signatures (fieldId -> dataURL)
  const signaturesRef = useRef<SignatureCapture[]>([]);

  // Group fields by page for efficient lookup
  const fieldsByPage = signatureFields.reduce<Record<number, SignatureFieldData[]>>(
    (acc, field) => {
      const page = field.page;
      if (!acc[page]) acc[page] = [];
      acc[page].push(field);
      return acc;
    },
    {}
  );

  const handlePageLoadSuccess = useCallback(
    (pageNum: number, page: { width: number; height: number; view: number[] }) => {
      setPageDimensions((prev) => ({
        ...prev,
        [pageNum]: {
          renderedWidth: page.width,
          renderedHeight: page.height,
          originalWidth: Math.max(page.view[0], page.view[2]),
          originalHeight: Math.max(page.view[1], page.view[3]),
        },
      }));
    },
    []
  );

  const handleFieldClick = useCallback(
    (fieldId: string) => {
      const field = signatureFields.find((f) => f.id === fieldId);
      if (!field) return;
      const ft = getFieldType(field);
      // Only client-signature and initials require client action
      if (ft !== 'client-signature' && ft !== 'initials') return;
      if (signedFields.has(fieldId)) return;
      setActiveFieldId(fieldId);
      setActiveFieldType(ft as 'client-signature' | 'initials');
      setModalOpen(true);
    },
    [signatureFields, signedFields]
  );

  const handleModalConfirm = useCallback(
    (fieldId: string, dataURL: string, save: boolean) => {
      // Persist to ref for POST submission
      signaturesRef.current = [
        ...signaturesRef.current.filter((s) => s.fieldId !== fieldId),
        { fieldId, dataURL },
      ];

      // Update signed fields map (triggers re-render of overlay)
      setSignedFields((prev) => {
        const next = new Map(prev);
        next.set(fieldId, dataURL);
        return next;
      });

      // If save was requested, localStorage is already set by SignatureModal
      void save; // acknowledged — handled inside modal

      setModalOpen(false);
      setActiveFieldId(null);
    },
    []
  );

  const handleJumpToNext = useCallback(() => {
    const nextUnsigned = signatureFields.find(
      (f) => (getFieldType(f) === 'client-signature' || getFieldType(f) === 'initials') && !signedFields.has(f.id)
    );
    if (nextUnsigned) {
      document.getElementById(`field-${nextUnsigned.id}`)?.scrollIntoView({
        behavior: 'smooth',
        block: 'center',
      });
    }
  }, [signatureFields, signedFields]);

  const handleSubmit = useCallback(async () => {
    const requiredFields = signatureFields.filter(
      (f) => getFieldType(f) === 'client-signature' || getFieldType(f) === 'initials'
    );
    if (signedFields.size < requiredFields.length || submitting) return;
    setSubmitting(true);
    try {
      const res = await fetch(`/api/sign/${token}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ signatures: signaturesRef.current }),
      });
      if (res.ok) {
        router.push(`/sign/${token}/confirmed`);
      } else if (res.status === 409) {
        // Already signed — navigate to confirmed anyway
        router.push(`/sign/${token}/confirmed`);
      } else {
        const data = await res.json().catch(() => ({}));
        alert(`Submission failed: ${(data as { error?: string }).error ?? res.status}. Please try again.`);
        setSubmitting(false);
      }
    } catch {
      alert('Network error. Please check your connection and try again.');
      setSubmitting(false);
    }
  }, [signedFields.size, signatureFields, submitting, token]);

  /**
   * Convert PDF user-space coordinates (bottom-left origin) to screen overlay position.
   *
   * PDF coords: origin at bottom-left, Y increases upward.
   * Screen coords: origin at top-left, Y increases downward.
   *
   * Formula:
   *   screenTop = renderedHeight - (field.y / originalHeight * renderedHeight) - (field.height / originalHeight * renderedHeight)
   *   screenLeft = field.x / originalWidth * renderedWidth
   */
  const getFieldOverlayStyle = (
    field: SignatureFieldData,
    dims: PageDimensions
  ): React.CSSProperties => {
    const scaleX = dims.renderedWidth / dims.originalWidth;
    const scaleY = dims.renderedHeight / dims.originalHeight;

    const top = dims.renderedHeight - field.y * scaleY - field.height * scaleY;
    const left = field.x * scaleX;
    const width = field.width * scaleX;
    const height = field.height * scaleY;

    return {
      position: 'absolute',
      top: `${top}px`,
      left: `${left}px`,
      width: `${width}px`,
      height: `${height}px`,
      cursor: 'pointer',
      borderRadius: '3px',
      animation: 'pulse-border 2s infinite',
    };
  };

  return (
    <>
      {/* Pulse-border keyframes injected inline */}
      <style>{`
        @keyframes pulse-border {
          0%, 100% {
            box-shadow: 0 0 0 2px #3b82f6, 0 0 8px 2px rgba(59,130,246,0.4);
          }
          50% {
            box-shadow: 0 0 0 3px #3b82f6, 0 0 16px 4px rgba(59,130,246,0.6);
          }
        }
        @keyframes pulse-border-purple {
          0%, 100% { box-shadow: 0 0 0 2px #7c3aed, 0 0 8px 2px rgba(124,58,237,0.4); }
          50% { box-shadow: 0 0 0 3px #7c3aed, 0 0 16px 4px rgba(124,58,237,0.6); }
        }
        .signing-field-signed {
          box-shadow: 0 0 0 2px #22c55e !important;
          animation: none !important;
          background-color: rgba(34,197,94,0.08);
        }
      `}</style>

      <div
        style={{
          minHeight: '100vh',
          backgroundColor: '#FAF9F7',
          fontFamily: 'Georgia, serif',
          paddingBottom: '80px', /* space for sticky progress bar */
        }}
      >
        {/* Branded header */}
        <header
          style={{
            backgroundColor: '#1B2B4B',
            color: '#fff',
            padding: '20px 32px',
            textAlign: 'center',
          }}
        >
          <div style={{ fontSize: '20px', fontWeight: 'bold', letterSpacing: '0.02em' }}>
            Teressa Copeland Homes
          </div>
          <div
            style={{
              fontSize: '16px',
              marginTop: '6px',
              color: '#C9A84C',
              fontStyle: 'italic',
            }}
          >
            {documentName}
          </div>
          <p style={{ fontSize: '14px', marginTop: '8px', color: '#ccc', fontFamily: 'sans-serif' }}>
            Please review and sign the document below.
          </p>
        </header>

        {/* PDF viewer */}
        <main style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '32px 16px' }}>
          <Document
            file={`/api/sign/${token}/pdf`}
            onLoadSuccess={({ numPages: n }) => setNumPages(n)}
            loading={
              <div style={{ padding: '40px', color: '#555', fontFamily: 'sans-serif' }}>
                Loading document...
              </div>
            }
            error={
              <div style={{ padding: '40px', color: '#c00', fontFamily: 'sans-serif' }}>
                Failed to load document. Please try refreshing.
              </div>
            }
          >
            {Array.from({ length: numPages }, (_, i) => {
              const pageNum = i + 1;
              const dims = pageDimensions[pageNum];
              const fieldsOnPage = fieldsByPage[pageNum] ?? [];

              return (
                <div
                  key={pageNum}
                  style={{
                    position: 'relative',
                    marginBottom: '24px',
                    boxShadow: '0 2px 12px rgba(0,0,0,0.12)',
                  }}
                >
                  <Page
                    pageNumber={pageNum}
                    width={PDF_RENDER_WIDTH}
                    onLoadSuccess={(page) => handlePageLoadSuccess(pageNum, page)}
                    renderAnnotationLayer={false}
                    renderTextLayer={false}
                  />

                  {/* Signature field overlays — rendered once page dimensions are known */}
                  {dims &&
                    fieldsOnPage.map((field) => {
                      // Only render interactive overlays for client-signature and initials fields
                      // text/checkbox/date are embedded at prepare time — no client interaction needed
                      const ft = getFieldType(field);
                      const isInteractive = ft === 'client-signature' || ft === 'initials';
                      if (!isInteractive) return null;

                      const isSigned = signedFields.has(field.id);
                      const baseStyle = getFieldOverlayStyle(field, dims);
                      const animationStyle: React.CSSProperties = ft === 'initials'
                        ? { animation: 'pulse-border-purple 2s infinite' }
                        : { animation: 'pulse-border 2s infinite' };
                      const fieldOverlayStyle = { ...baseStyle, ...animationStyle };
                      const sigDataURL = signedFields.get(field.id);
                      return (
                        <div
                          key={field.id}
                          id={`field-${field.id}`}
                          className={isSigned ? 'signing-field-signed' : ''}
                          style={fieldOverlayStyle}
                          onClick={() => handleFieldClick(field.id)}
                          role="button"
                          tabIndex={0}
                          aria-label={ft === 'initials'
                            ? `Initials field${isSigned ? ' (initialed)' : ' — click to initial'}`
                            : `Signature field${isSigned ? ' (signed)' : ' — click to sign'}`}
                          onKeyDown={(e) => {
                            if (e.key === 'Enter' || e.key === ' ') {
                              e.preventDefault();
                              handleFieldClick(field.id);
                            }
                          }}
                        >
                          {/* Show signature/initials preview when signed */}
                          {isSigned && sigDataURL && (
                            /* eslint-disable-next-line @next/next/no-img-element */
                            <img
                              src={sigDataURL}
                              alt={ft === 'initials' ? 'Initials' : 'Signature'}
                              style={{
                                width: '100%',
                                height: '100%',
                                objectFit: 'contain',
                                display: 'block',
                              }}
                            />
                          )}
                        </div>
                      );
                    })}
                </div>
              );
            })}
          </Document>
        </main>
      </div>

      {/* Sticky progress bar */}
      <SigningProgressBar
        total={signatureFields.filter(
          (f) => getFieldType(f) === 'client-signature' || getFieldType(f) === 'initials'
        ).length}
        signed={signedFields.size}
        onJumpToNext={handleJumpToNext}
        onSubmit={handleSubmit}
        submitting={submitting}
      />

      {/* Signature capture modal */}
      <SignatureModal
        isOpen={modalOpen}
        fieldId={activeFieldId ?? ''}
        title={activeFieldType === 'initials' ? 'Add Initials' : 'Add Signature'}
        onConfirm={handleModalConfirm}
        onClose={() => {
          setModalOpen(false);
          setActiveFieldId(null);
        }}
      />
    </>
  );
}

// Export type for downstream use
export type { SigningPageClientProps };
