"use client";

import { useEffect, useMemo, useState } from "react";
import { Skeleton } from "@/components/atoms/loading-skeleton";
import { Button } from "@/components/atoms/button";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
import { CreditCardIcon, CheckCircleIcon } from "@heroicons/react/24/outline";
import type { PaymentMethod } from "@customer-portal/domain/payments";

export interface PaymentFormProps {
  existingMethods?: PaymentMethod[];
  selectedMethodId?: string;
  onMethodSelect?: (methodId: string) => void;
  onAddNewMethod?: () => void;
  onValidationChange?: (isValid: boolean, errors: string[]) => void;
  title?: string;
  description?: string;
  showTitle?: boolean;
  allowNewMethod?: boolean;
  requirePaymentMethod?: boolean;
  loading?: boolean;
  disabled?: boolean;
  children?: React.ReactNode;
  footerContent?: React.ReactNode;
}

export function PaymentForm({
  existingMethods = [],
  selectedMethodId,
  onMethodSelect,
  onAddNewMethod,
  onValidationChange,
  title = "Payment Method",
  description,
  showTitle = true,
  allowNewMethod = true,
  requirePaymentMethod = true,
  loading = false,
  disabled = false,
  children,
  footerContent,
}: PaymentFormProps) {
  const [selectedMethod, setSelectedMethod] = useState<string>(selectedMethodId ?? "");
  const [errors, setErrors] = useState<string[]>([]);

  useEffect(() => {
    if (selectedMethodId !== undefined) {
      setSelectedMethod(selectedMethodId);
    }
  }, [selectedMethodId]);

  useEffect(() => {
    const validationErrors: string[] = [];

    if (requirePaymentMethod) {
      if (existingMethods.length === 0) {
        validationErrors.push("No payment methods on file. Add one to continue.");
      } else if (!selectedMethod) {
        validationErrors.push("Select a payment method to continue.");
      }
    }

    setErrors(validationErrors);
    onValidationChange?.(validationErrors.length === 0, validationErrors);
  }, [existingMethods, requirePaymentMethod, selectedMethod, onValidationChange]);

  const methods = useMemo(() => existingMethods, [existingMethods]);

  if (loading) {
    return (
      <div className="p-6 bg-white border border-gray-200 rounded-lg">
        <div className="space-y-4">
          {Array.from({ length: 2 }).map((_, index) => (
            <div key={index} className="flex items-center justify-between">
              <div className="flex items-center gap-3">
                <Skeleton className="h-8 w-12" />
                <div className="space-y-2">
                  <Skeleton className="h-4 w-40" />
                  <Skeleton className="h-3 w-24" />
                </div>
              </div>
              <Skeleton className="h-9 w-28" />
            </div>
          ))}
        </div>
      </div>
    );
  }

  const renderMethod = (method: PaymentMethod) => {
    const methodId = String(method.id);
    const isSelected = selectedMethod === methodId;
    const label = method.cardType
      ? `${method.cardType.toUpperCase()} ${method.cardLastFour ? `•••• ${method.cardLastFour}` : ""}`.trim()
      : (method.description ?? method.type);

    return (
      <label
        key={method.id}
        className={[
          "flex items-center justify-between p-4 border-2 rounded-lg cursor-pointer transition-colors",
          isSelected ? "border-blue-500 bg-blue-50" : "border-gray-200 hover:border-gray-300",
          disabled ? "opacity-50 cursor-not-allowed" : "",
        ].join(" ")}
      >
        <div className="flex items-center gap-3">
          <CreditCardIcon className="h-6 w-6 text-gray-400" />
          <div>
            <div className="text-sm font-medium text-gray-900 flex items-center gap-2">
              {label}
              {method.isDefault ? (
                <span className="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">
                  Default
                </span>
              ) : null}
            </div>
            {method.expiryDate ? (
              <div className="text-xs text-gray-500">Expires {method.expiryDate}</div>
            ) : null}
          </div>
        </div>

        <input
          type="radio"
          name="paymentMethod"
          value={methodId}
          checked={isSelected}
          disabled={disabled}
          onChange={() => {
            if (disabled) return;
            setSelectedMethod(methodId);
            onMethodSelect?.(methodId);
          }}
          className="text-blue-600 focus:ring-blue-500"
        />
      </label>
    );
  };

  return (
    <div className="p-6 bg-white border border-gray-200 rounded-lg space-y-4">
      {showTitle && (
        <div>
          <div className="flex items-center gap-2 mb-1">
            <CreditCardIcon className="h-5 w-5 text-blue-600" />
            <h3 className="text-lg font-semibold text-gray-900">{title}</h3>
          </div>
          {description ? <p className="text-sm text-gray-600">{description}</p> : null}
        </div>
      )}

      {methods.length === 0 ? (
        <div className="py-8 text-center">
          <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-gray-100">
            <CreditCardIcon className="h-6 w-6 text-gray-400" />
          </div>
          <p className="text-sm text-gray-600 mb-4">Add a payment method to continue.</p>
          {allowNewMethod && onAddNewMethod ? (
            <Button onClick={onAddNewMethod} disabled={disabled}>
              Add Payment Method
            </Button>
          ) : null}
        </div>
      ) : (
        <div className="space-y-3">
          {methods.map(renderMethod)}
          {allowNewMethod && onAddNewMethod ? (
            <div className="pt-3">
              <Button
                variant="outline"
                className="w-full"
                onClick={onAddNewMethod}
                disabled={disabled}
              >
                Add Another Method
              </Button>
            </div>
          ) : null}
        </div>
      )}

      {children}

      {errors.length > 0 ? (
        <AlertBanner variant="error" title="Payment Required" elevated size="sm">
          <ul className="list-disc list-inside">
            {errors.map((msg, index) => (
              <li key={index}>{msg}</li>
            ))}
          </ul>
        </AlertBanner>
      ) : (
        selectedMethod && (
          <div className="flex items-center gap-2 text-sm text-green-600">
            <CheckCircleIcon className="h-4 w-4" />
            Payment method selected
          </div>
        )
      )}

      {footerContent ? <div className="pt-4 border-t border-gray-200">{footerContent}</div> : null}
    </div>
  );
}
