// app/components/admin/orders/SubmitLinksModal.tsx
'use client';

import { useState, useEffect, useCallback, useMemo } from 'react';
import { Order, OrderItem, PackageOrderItem } from '@/types/order';
import toast from 'react-hot-toast';

interface SubmitLinksModalProps {
  order: Order;
  onClose: () => void;
  onSuccess: () => void;
}

interface LinkInput {
  id: string;
  itemId: string;
  index: number;
  url: string;
}

interface SubmissionData {
  order_type: string;
  individual_links: Record<string, string[]>;
  package_sheets: Record<string, string>;
}

// FIX: Tightened regex to avoid false positives
const URL_REGEX = /^https?:\/\/([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/i;
const GSHEET_REGEX = /^https?:\/\/(www\.)?(docs\.google\.com\/spreadsheets\/d\/|sheets\.google\.com)/;

// ─── Sub-components ───────────────────────────────────────────────────────────

function InfoBanner({ children }: { children: React.ReactNode }) {
  return (
    <div className="bg-var-info-bg border border-var-info-border rounded-xl p-4">
      <div className="flex items-start">
        <svg
          className="w-5 h-5 text-var-info mt-0.5 mr-3 shrink-0"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
          />
        </svg>
        <div className="text-sm text-var-info-text">{children}</div>
      </div>
    </div>
  );
}

function ExistingLinksWarning({ links }: { links: NonNullable<OrderItem['live_links']> }) {
  if (!links || links.length === 0) return null;

  return (
    <div className="bg-var-warning-bg border border-var-warning-border rounded-lg p-3 mb-4">
      <p className="text-sm text-var-warning-text font-medium">
        Previously submitted links (awaiting review):
      </p>
      <ul className="mt-2 space-y-1">
        {links.map((link, idx) => (
          <li key={`${link.url}-${idx}`} className="text-sm text-var-warning-text">
            Link {idx + 1}:{' '}
            <a
              href={link.url}
              target="_blank"
              rel="noopener noreferrer"
              className="underline break-all text-var-primary hover:text-var-primary-hover"
            >
              {link.url}
            </a>
            <span className="ml-2 text-xs text-var-warning-text">
              (Submitted: {new Date(link.submitted_at).toLocaleDateString()})
            </span>
          </li>
        ))}
      </ul>
    </div>
  );
}

function ExistingSheetWarning({ url }: { url: string }) {
  if (!url) return null;

  return (
    <div className="bg-var-warning-bg border border-var-warning-border rounded-lg p-3 mb-4">
      <p className="text-sm text-var-warning-text font-medium">Previously submitted Google Sheet:</p>
      <a
        href={url}
        target="_blank"
        rel="noopener noreferrer"
        className="text-sm text-var-primary hover:underline break-all mt-1 inline-block"
      >
        {url}
      </a>
    </div>
  );
}

interface IndividualItemSectionProps {
  item: OrderItem;
  itemLinks: LinkInput[];
  onLinkChange: (id: string, url: string) => void;
}

function IndividualItemSection({ item, itemLinks, onLinkChange }: IndividualItemSectionProps) {
  const existingLinks = item.live_links ?? [];
  const submittedCount = existingLinks.filter((link) => link.url?.trim()).length;
  const remainingCount = item.quantity - submittedCount;

  return (
    <div className="border border-var-border rounded-xl overflow-hidden">
      <div className="bg-var-surface-hover px-4 py-3 border-b border-var-border">
        <div className="flex justify-between items-center">
          <div>
            <h4 className="font-medium text-var-text">{item.website?.name ?? 'Website'}</h4>
            {item.website?.domain && (
              <p className="text-sm text-var-text-secondary">{item.website.domain}</p>
            )}
            {item.website?.da && (
              <p className="text-xs text-var-text-muted mt-1">DA: {item.website.da}</p>
            )}
          </div>
          <div className="text-right">
            <span className="text-sm text-var-text-muted">Quantity:</span>
            <span className="ml-2 text-lg font-semibold text-var-text">{item.quantity}</span>
            {submittedCount > 0 && (
              <p className="text-xs text-var-success-text mt-1">
                {submittedCount} of {item.quantity} submitted
              </p>
            )}
          </div>
        </div>
      </div>

      <div className="p-4 space-y-4">
        {existingLinks.length > 0 && <ExistingLinksWarning links={existingLinks} />}

        {remainingCount > 0 ? (
          <div className="space-y-3">
            <label className="block text-sm font-medium text-var-text">
              Live Links (Need {remainingCount} more)
            </label>
            {itemLinks.map((input, idx) => (
              <div key={input.id} className="flex items-start space-x-3">
                <div className="shrink-0 w-8 pt-2">
                  {/* FIX: Show actual link number (offset by already-submitted count) */}
                  <span className="text-sm font-medium text-var-text-muted">
                    #{submittedCount + idx + 1}
                  </span>
                </div>
                <div className="flex-1">
                  <input
                    type="url"
                    value={input.url}
                    onChange={(e) => onLinkChange(input.id, e.target.value)}
                    placeholder={`https://example.com/article-${submittedCount + idx + 1}`}
                    className="w-full px-3 py-2 bg-var-input border border-var-border rounded-lg focus:ring-2 focus:ring-var-primary focus:border-var-primary text-var-input placeholder-var-input"
                  />
                  <p className="mt-1 text-xs text-var-text-muted">
                    Enter the full URL where the content is published
                  </p>
                </div>
              </div>
            ))}
          </div>
        ) : (
          <div className="bg-var-success-bg rounded-lg p-3">
            <p className="text-sm text-var-success-text font-medium">
              ✓ All links submitted for this item
            </p>
          </div>
        )}
      </div>
    </div>
  );
}

interface PackageItemSectionProps {
  item: PackageOrderItem;
  googleSheetUrl: string;
  onGoogleSheetChange: (url: string) => void;
}

function PackageItemSection({
  item,
  googleSheetUrl,
  onGoogleSheetChange,
}: PackageItemSectionProps) {
  const hasExistingSheet = !!item.google_sheet_url;

  return (
    <div className="border border-var-border rounded-xl overflow-hidden">
      <div className="bg-var-surface-hover px-4 py-3 border-b border-var-border">
        <div className="flex justify-between items-center">
          <div>
            <h4 className="font-medium text-var-text">{item.package?.name ?? 'Package'}</h4>
            {item.package?.description && (
              <p className="text-sm text-var-text-secondary mt-1">{item.package.description}</p>
            )}
          </div>
          <div className="text-right">
            <span className="text-sm text-var-text-muted">Quantity:</span>
            <span className="ml-2 text-lg font-semibold text-var-text">{item.quantity}</span>
            {hasExistingSheet && <p className="text-xs text-var-success-text mt-1">✓ Sheet submitted</p>}
          </div>
        </div>
      </div>

      <div className="p-4 space-y-4">
        {hasExistingSheet ? (
          <>
            <ExistingSheetWarning url={item.google_sheet_url!} />
            <div className="bg-var-success-bg rounded-lg p-3">
              <p className="text-sm text-var-success-text font-medium">
                ✓ Google Sheet already submitted for this package
              </p>
            </div>
          </>
        ) : (
          <div>
            <label className="block text-sm font-medium text-var-text mb-2">
              Google Sheet URL
            </label>
            <input
              type="url"
              value={googleSheetUrl}
              onChange={(e) => onGoogleSheetChange(e.target.value)}
              placeholder="https://docs.google.com/spreadsheets/d/..."
              className="w-full px-3 py-2 bg-var-input border border-var-border rounded-lg focus:ring-2 focus:ring-var-primary focus:border-var-primary text-var-input placeholder-var-input"
            />
            <p className="mt-1 text-xs text-var-text-muted">
              Make sure the sheet has public access or is shared with the admin email
            </p>
          </div>
        )}
      </div>
    </div>
  );
}

// ─── Main Component ───────────────────────────────────────────────────────────

export default function SubmitLinksModal({ order, onClose, onSuccess }: SubmitLinksModalProps) {
  const [loading, setLoading] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [orderItems, setOrderItems] = useState<OrderItem[]>([]);
  const [packageOrderItems, setPackageOrderItems] = useState<PackageOrderItem[]>([]);
  const [linkInputs, setLinkInputs] = useState<LinkInput[]>([]);
  const [packageGoogleSheets, setPackageGoogleSheets] = useState<Record<string, string>>({});

  // FIX: Stable fetch — no state deps that cause re-creation loops
  const fetchOrderItems = useCallback(async () => {
    setLoading(true);
    try {
      const response = await fetch(`/api/backend/admin/orders/${order.id}/items`);
      const data = await response.json();

      if (!response.ok) {
        toast.error(data.error ?? 'Failed to fetch order items');
        return;
      }

      if (order.order_type === 'individual' || order.order_type === 'package_individual') {
        const items: OrderItem[] = data.items ?? [];
        setOrderItems(items);

        const inputs: LinkInput[] = [];
        items.forEach((item) => {
          const existingLinks = item.live_links ?? [];
          const existingCount = existingLinks.filter((link) => link.url?.trim()).length;
          const neededCount = item.quantity - existingCount;

          for (let i = 0; i < neededCount; i++) {
            inputs.push({
              id: `${item.id}_${existingCount + i}`,
              itemId: item.id,
              index: existingCount + i,
              url: '',
            });
          }
        });
        setLinkInputs(inputs);
      }

      if (order.order_type === 'package' || order.order_type === 'package_individual') {
        const items: PackageOrderItem[] = data.package_items ?? [];
        setPackageOrderItems(items);

        const sheets: Record<string, string> = {};
        items.forEach((item) => {
          if (!item.google_sheet_url) {
            sheets[item.id] = '';
          }
        });
        setPackageGoogleSheets(sheets);
      }
    } catch (error) {
      toast.error('Failed to fetch order items');
      console.error(error);
    } finally {
      setLoading(false);
    }
  }, [order.id, order.order_type]); // FIX: only truly stable deps

  useEffect(() => {
    fetchOrderItems();
  }, [fetchOrderItems]);

  const handleLinkChange = useCallback((inputId: string, url: string) => {
    setLinkInputs((prev) =>
      prev.map((input) => (input.id === inputId ? { ...input, url } : input))
    );
  }, []);

  const handlePackageSheetChange = useCallback((itemId: string, url: string) => {
    setPackageGoogleSheets((prev) => ({ ...prev, [itemId]: url }));
  }, []);

  // Group link inputs by item id
  const linksByItemId = useMemo(() => {
    const map: Record<string, LinkInput[]> = {};
    for (const input of linkInputs) {
      (map[input.itemId] ??= []).push(input);
    }
    return map;
  }, [linkInputs]);

  // FIX: Single consolidated pending check — no redundant intermediate memos
  const hasPendingItems = useMemo(() => {
    const hasLinks =
      orderItems.length > 0 && linkInputs.some((input) => input.url.trim());
    const hasSheets =
      packageOrderItems.length > 0 &&
      Object.values(packageGoogleSheets).some((url) => url?.trim());
    return hasLinks || hasSheets;
  }, [orderItems.length, packageOrderItems.length, linkInputs, packageGoogleSheets]);

  const handleSubmitAll = useCallback(async () => {
    setSubmitting(true);
    try {
      const submissionData: SubmissionData = {
        order_type: order.order_type,
        individual_links: {},
        package_sheets: {},
      };

      let hasIndividualSubmission = false;
      let hasPackageSubmission = false;

      // Validate & collect individual links
      if (
        (order.order_type === 'individual' || order.order_type === 'package_individual') &&
        orderItems.length > 0
      ) {
        const filledLinks = linkInputs.filter((input) => input.url.trim());
        const emptyLinks = linkInputs.filter((input) => !input.url.trim());

        if (filledLinks.length > 0) {
          // FIX: require ALL inputs to be filled before submitting, not just check counts
          if (emptyLinks.length > 0) {
            toast.error('Please fill in all link fields or remove empty ones');
            setSubmitting(false);
            return;
          }

          const invalidUrl = filledLinks.find((input) => !URL_REGEX.test(input.url));
          if (invalidUrl) {
            toast.error(`Invalid URL: ${invalidUrl.url}`);
            setSubmitting(false);
            return;
          }

          // Group by item
          const liveLinksByItem: Record<string, string[]> = {};
          for (const input of filledLinks) {
            (liveLinksByItem[input.itemId] ??= []).push(input.url);
          }
          submissionData.individual_links = liveLinksByItem;
          hasIndividualSubmission = true;
        }
      }

      // Validate & collect package sheets
      if (
        (order.order_type === 'package' || order.order_type === 'package_individual') &&
        packageOrderItems.length > 0
      ) {
        const pendingSheets = Object.entries(packageGoogleSheets).filter(
          ([, url]) => url?.trim()
        );

        if (pendingSheets.length > 0) {
          const invalidSheets = pendingSheets.filter(([, url]) => !GSHEET_REGEX.test(url));
          if (invalidSheets.length > 0) {
            toast.error('Please provide valid Google Sheets URLs (docs.google.com/spreadsheets)');
            setSubmitting(false);
            return;
          }

          submissionData.package_sheets = Object.fromEntries(pendingSheets);
          hasPackageSubmission = true;
        }
      }

      if (!hasIndividualSubmission && !hasPackageSubmission) {
        toast.error('No pending items to submit');
        setSubmitting(false);
        return;
      }

      const response = await fetch(`/api/backend/admin/orders/${order.id}/submit-links`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(submissionData),
      });

      const data = await response.json();

      if (response.ok) {
        toast.success(data.message || 'Links submitted successfully');
        onSuccess();
        onClose();
      } else {
        toast.error(data.error ?? 'Failed to submit links');
      }
    } catch (error) {
      toast.error('Failed to submit links');
      console.error(error);
    } finally {
      setSubmitting(false);
    }
  }, [
    order.id,
    order.order_type,
    orderItems.length,
    packageOrderItems.length,
    linkInputs,
    packageGoogleSheets,
    onSuccess,
    onClose,
  ]);

  // FIX: Derive these directly — no useMemo needed for simple boolean/string derivations
  const hasIndividualItems = orderItems.length > 0;
  const hasPackageItems = packageOrderItems.length > 0;

  const submitLabel = useMemo(() => {
    if (submitting) return 'Submitting...';
    if (!hasPendingItems) return 'No Pending Items';
    if (hasIndividualItems && hasPackageItems) return 'Submit All Links';
    if (hasIndividualItems) return 'Submit Live Links';
    if (hasPackageItems) return 'Submit Google Sheet URLs';
    return 'Submit';
  }, [submitting, hasPendingItems, hasIndividualItems, hasPackageItems]);

  const orderTypeDescription = useMemo(() => {
    switch (order.order_type) {
      case 'individual':
        return 'This order contains individual website items. Please provide live links for each pending entry.';
      case 'package':
        return 'This order contains package items. Please provide Google Sheet URLs for each pending package.';
      case 'package_individual':
        return 'This order contains both individual websites and package items. Please provide live links for individual items and Google Sheet URLs for package items.';
      default:
        return 'Please provide the required information for this order.';
    }
  }, [order.order_type]);

  return (
    <div className="fixed inset-0 bg-black/70 bg-opacity-50 flex items-center justify-center z-50">
      <div className="bg-var-surface rounded-2xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-y-auto shadow-var-modal">
        {/* Header */}
        <div className="sticky top-0 bg-var-surface border-b border-var-border px-6 py-4 flex justify-between items-center z-10">
          <div>
            <h2 className="text-xl font-bold text-var-text">Submit Live Links</h2>
            <p className="text-sm text-var-text-muted">Order #{order.order_number}</p>
            {order.order_type === 'package_individual' && (
              <span className="inline-flex items-center px-2 py-0.5 mt-2 rounded text-xs font-medium bg-var-info-bg text-var-info-text">
                Mixed Order (Package + Individual)
              </span>
            )}
          </div>
          <button
            onClick={onClose}
            aria-label="Close modal"
            className="text-var-text-muted hover:text-var-text transition-colors"
          >
            <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M6 18L18 6M6 6l12 12"
              />
            </svg>
          </button>
        </div>

        <div className="p-6">
          {loading ? (
            <div className="text-center py-8">
              <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-var-primary mx-auto" />
              <p className="mt-4 text-var-text-muted">Loading order items...</p>
            </div>
          ) : (
            <div className="space-y-6">
              <InfoBanner>
                <strong className="text-var-info-text block mb-1">Submit Required Information</strong>
                {orderTypeDescription} After submitting all required information, the order will be
                moved to &quot;Pending Review&quot; status.
              </InfoBanner>

              {/* Individual Items */}
              {hasIndividualItems && (
                <div className="space-y-4">
                  <h3 className="text-lg font-semibold text-var-text flex items-center gap-2">
                    <span className="bg-var-primary-muted text-var-primary-text text-xs font-medium px-2.5 py-0.5 rounded">
                      Individual Website Items
                    </span>
                    <span className="text-sm text-var-text-muted">
                      ({orderItems.length} item{orderItems.length !== 1 ? 's' : ''})
                    </span>
                  </h3>
                  <div className="space-y-6">
                    {orderItems.map((item) => (
                      <IndividualItemSection
                        key={item.id}
                        item={item}
                        itemLinks={linksByItemId[item.id] ?? []}
                        onLinkChange={handleLinkChange}
                      />
                    ))}
                  </div>
                </div>
              )}

              {/* Package Items */}
              {hasPackageItems && (
                <div className="space-y-4">
                  <h3 className="text-lg font-semibold text-var-text flex items-center gap-2">
                    <span className="bg-var-info-bg text-var-info-text text-xs font-medium px-2.5 py-0.5 rounded">
                      Package Items
                    </span>
                    <span className="text-sm text-var-text-muted">
                      ({packageOrderItems.length} package
                      {packageOrderItems.length !== 1 ? 's' : ''})
                    </span>
                  </h3>
                  <div className="space-y-6">
                    {packageOrderItems.map((item) => (
                      <PackageItemSection
                        key={item.id}
                        item={item}
                        googleSheetUrl={packageGoogleSheets[item.id] ?? ''}
                        onGoogleSheetChange={(url) => handlePackageSheetChange(item.id, url)}
                      />
                    ))}
                  </div>
                </div>
              )}

              <ModalFooter
                onClose={onClose}
                onSubmit={handleSubmitAll}
                submitting={submitting}
                submitLabel={submitLabel}
                disabled={!hasPendingItems}
              />
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ─── Footer ───────────────────────────────────────────────────────────────────

interface ModalFooterProps {
  onClose: () => void;
  onSubmit: () => void;
  submitting: boolean;
  submitLabel: string;
  disabled?: boolean;
}

function ModalFooter({ onClose, onSubmit, submitting, submitLabel, disabled }: ModalFooterProps) {
  return (
    <div className="flex justify-end space-x-3 pt-4 border-t border-var-border">
      <button
        onClick={onClose}
        className="px-4 py-2 text-var-text-secondary bg-var-surface-hover rounded-lg hover:bg-var-surface-hover hover:text-var-text transition-colors"
      >
        Cancel
      </button>
      <button
        onClick={onSubmit}
        disabled={submitting || disabled}
        className="px-4 py-2 bg-var-primary text-white rounded-lg hover:bg-var-primary-hover transition-colors disabled:opacity-50 disabled:cursor-not-allowed shadow-var-button"
      >
        {submitLabel}
      </button>
    </div>
  );
}