"use client";

import { Skeleton } from "@/components/atoms";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
import { Button } from "@/components/atoms/button";
import { SubCard } from "@/components/molecules/SubCard/SubCard";

import { useState, useEffect, useCallback } from "react";
import { accountService } from "@/features/account/services/account.service";
import { log } from "@/lib/logger";
import { StatusPill } from "@/components/atoms/status-pill";
import { MapPinIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { COUNTRY_OPTIONS, getCountryName } from "@/lib/constants/countries";

// Use canonical Address type from domain
import type { Address } from "@customer-portal/domain/customer";
import { ORDER_TYPE } from "@customer-portal/domain/orders";

interface BillingInfo {
  company: string | null;
  email: string;
  phone: string | null;
  address: Address | null;
  isComplete: boolean;
}

interface AddressConfirmationProps {
  onAddressConfirmed: (address?: Address) => void;
  onAddressIncomplete: () => void;
  orderType?: string; // Add order type to customize behavior
  embedded?: boolean; // When true, render without outer card wrapper
}

export function AddressConfirmation({
  onAddressConfirmed,
  onAddressIncomplete,
  orderType,
  embedded = false,
}: AddressConfirmationProps) {
  const [billingInfo, setBillingInfo] = useState<BillingInfo | null>(null);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState(false);
  const [editedAddress, setEditedAddress] = useState<Address | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [addressConfirmed, setAddressConfirmed] = useState(false);

  const isInternetOrder = orderType === ORDER_TYPE.INTERNET;
  const requiresAddressVerification = isInternetOrder;

  const fetchBillingInfo = useCallback(async () => {
    try {
      setLoading(true);
      const data = await accountService.getAddress();
      const normalizedAddress = data
        ? {
            ...data,
            country: data.country ?? "",
            countryCode: data.countryCode ?? data.country ?? "",
          }
        : null;
      const isComplete = !!(
        normalizedAddress &&
        normalizedAddress.address1 &&
        normalizedAddress.city &&
        normalizedAddress.state &&
        normalizedAddress.postcode &&
        normalizedAddress.country
      );

      setBillingInfo({
        company: null,
        email: "",
        phone: null,
        address: normalizedAddress,
        isComplete,
      });

      if (requiresAddressVerification) {
        setAddressConfirmed(false);
        onAddressIncomplete();
      } else if (isComplete && normalizedAddress) {
        onAddressConfirmed(normalizedAddress);
        setAddressConfirmed(true);
      } else {
        onAddressIncomplete();
        setAddressConfirmed(false);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to load address");
    } finally {
      setLoading(false);
    }
  }, [requiresAddressVerification, onAddressIncomplete, onAddressConfirmed]);

  useEffect(() => {
    log.info("Address confirmation component mounted");
    void fetchBillingInfo();
  }, [fetchBillingInfo]);

  const handleEdit = (e?: React.MouseEvent<HTMLButtonElement>) => {
    e?.preventDefault();
    e?.stopPropagation();

    setEditing(true);
    setEditedAddress(
      billingInfo?.address ?? {
        address1: "",
        address2: "",
        city: "",
        state: "",
        postcode: "",
        country: "",
        countryCode: "",
      }
    );
  };

  const handleSave = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    e.stopPropagation();

    if (!editedAddress) return;

    // Validate required fields
    const isComplete = !!(
      editedAddress.address1?.trim() &&
      editedAddress.city?.trim() &&
      editedAddress.state?.trim() &&
      editedAddress.postcode?.trim() &&
      editedAddress.country?.trim()
    );

    if (!isComplete) {
      setError("Please fill in all required address fields");
      return;
    }

    void (async () => {
      try {
        setError(null);

        const sanitizedAddress: Address = {
          address1: editedAddress.address1?.trim() || null,
          address2: editedAddress.address2?.trim() || null,
          city: editedAddress.city?.trim() || null,
          state: editedAddress.state?.trim() || null,
          postcode: editedAddress.postcode?.trim() || null,
          country: editedAddress.country?.trim() || null,
          countryCode: editedAddress.country?.trim() || null,
        };

        // Persist to server (WHMCS via BFF)
        const updatedAddress = await accountService.updateAddress(sanitizedAddress);

        // Rebuild BillingInfo from updated address
        const updatedInfo: BillingInfo = {
          company: null,
          email: "",
          phone: null,
          address: updatedAddress,
          isComplete: !!(
            updatedAddress.address1 &&
            updatedAddress.city &&
            updatedAddress.state &&
            updatedAddress.postcode &&
            updatedAddress.country
          ),
        };
        setBillingInfo(updatedInfo);

        // Use the edited address for the order (will be flagged as changed)
        onAddressConfirmed(updatedAddress);
        setEditing(false);
        setAddressConfirmed(true);
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to update address");
      }
    })();
  };

  const handleConfirmAddress = (e: React.MouseEvent<HTMLButtonElement>) => {
    // Defensively prevent any parent form/link behaviors from triggering navigation
    if (e && typeof e.preventDefault === "function") e.preventDefault();
    if (e && typeof e.stopPropagation === "function") e.stopPropagation();

    log.info("Confirm installation address clicked");

    // Ensure we have an address before confirming
    if (billingInfo?.address) {
      log.info("Address confirmed", { address: billingInfo.address });
      onAddressConfirmed(billingInfo.address);
      setAddressConfirmed(true);
    } else {
      log.warn("No billing info or address available");
      setAddressConfirmed(false);
    }
  };

  const handleCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    e.stopPropagation();

    setEditing(false);
    setEditedAddress(null);
    setError(null);
  };

  const statusVariant = addressConfirmed || !requiresAddressVerification ? "success" : "warning";

  // Note: Avoid defining wrapper components inside render to prevent remounts (focus loss)
  const wrap = (node: React.ReactNode) =>
    embedded ? <>{node}</> : <SubCard className="mb-6">{node}</SubCard>;

  if (loading) {
    return wrap(
      <div className="flex items-center space-x-3">
        <Skeleton className="h-4 w-4 rounded-full" />
        <span className="text-gray-600">Loading address information...</span>
      </div>
    );
  }

  if (error) {
    return wrap(
      <AlertBanner variant="error" title="Address Error" elevated>
        <div className="flex items-center justify-between">
          <span>{error}</span>
          <Button type="button" size="sm" variant="outline" onClick={() => void fetchBillingInfo()}>
            Try Again
          </Button>
        </div>
      </AlertBanner>
    );
  }

  if (!billingInfo) return null;

  const address = billingInfo.address;
  const countryLabel = address?.country
    ? (getCountryName(address.country) ?? address.country)
    : null;

  return wrap(
    <>
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center space-x-3">
          <MapPinIcon className="h-5 w-5 text-blue-600" />
          <div>
            <h3 className="text-lg font-semibold text-gray-900">
              {isInternetOrder
                ? "Installation Address"
                : billingInfo.isComplete
                  ? "Service Address"
                  : "Complete Your Address"}
            </h3>
          </div>
        </div>
        <div className="flex items-center gap-2">
          {/* Consistent status pill placement (right side) */}
          <StatusPill
            label={statusVariant === "success" ? "Verified" : "Pending confirmation"}
            variant={statusVariant}
          />
        </div>
      </div>

      {/* Consolidated single card without separate banner */}

      {editing ? (
        <div className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Street Address *</label>
            <input
              type="text"
              value={editedAddress?.address1 || ""}
              onChange={e => {
                setError(null); // Clear error on input
                setEditedAddress(prev => (prev ? { ...prev, address1: e.target.value } : null));
              }}
              className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
              placeholder="123 Main Street"
              required
            />
          </div>

          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Street Address Line 2
            </label>
            <input
              type="text"
              value={editedAddress?.address2 || ""}
              onChange={e => {
                setError(null);
                setEditedAddress(prev => (prev ? { ...prev, address2: e.target.value } : null));
              }}
              className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
              placeholder="Apartment, suite, etc. (optional)"
            />
          </div>

          <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">City *</label>
              <input
                type="text"
                value={editedAddress?.city || ""}
                onChange={e => {
                  setError(null);
                  setEditedAddress(prev => (prev ? { ...prev, city: e.target.value } : null));
                }}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                placeholder="Tokyo"
              />
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">
                State/Prefecture *
              </label>
              <input
                type="text"
                value={editedAddress?.state || ""}
                onChange={e => {
                  setError(null);
                  setEditedAddress(prev => (prev ? { ...prev, state: e.target.value } : null));
                }}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                placeholder="Tokyo"
              />
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">Postal Code *</label>
              <input
                type="text"
                value={editedAddress?.postcode || ""}
                onChange={e => {
                  setError(null);
                  setEditedAddress(prev => (prev ? { ...prev, postcode: e.target.value } : null));
                }}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                placeholder="100-0001"
              />
            </div>
          </div>

          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Country *</label>
            <select
              value={editedAddress?.country || ""}
              onChange={e => {
                setError(null);
                const next = e.target.value;
                setEditedAddress(prev =>
                  prev ? { ...prev, country: next, countryCode: next } : null
                );
              }}
              className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
            >
              <option value="">Select Country</option>
              {COUNTRY_OPTIONS.map(option => (
                <option key={option.code} value={option.code}>
                  {option.name}
                </option>
              ))}
            </select>
          </div>

          <div className="flex items-center space-x-3 pt-4">
            <button
              type="button"
              onClick={handleSave}
              className="flex items-center space-x-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
            >
              <CheckIcon className="h-4 w-4" />
              <span>Save Address</span>
            </button>
            <button
              type="button"
              onClick={handleCancel}
              className="flex items-center space-x-2 bg-gray-100 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-200 transition-colors"
            >
              <XMarkIcon className="h-4 w-4" />
              <span>Cancel</span>
            </button>
          </div>
        </div>
      ) : (
        <div>
          {address?.address1 ? (
            <div className="space-y-4">
              <div className="text-gray-900 space-y-1">
                <p className="font-semibold text-base">{address.address1}</p>
                {address.address2 ? <p className="text-gray-700">{address.address2}</p> : null}
                <p className="text-gray-700">
                  {[address.city, address.state].filter(Boolean).join(", ")}
                  {address.postcode ? ` ${address.postcode}` : ""}
                </p>
                {countryLabel && <p className="text-gray-600">{countryLabel}</p>}
              </div>

              {/* Status message for Internet orders when pending */}
              {isInternetOrder && !addressConfirmed && (
                <AlertBanner variant="warning" title="Verification Required" size="sm" elevated>
                  Please confirm this is the correct installation address for your internet service.
                </AlertBanner>
              )}

              {/* Action buttons */}
              <div className="flex items-center gap-3 pt-4 border-t border-gray-100">
                {/* Primary action when pending for Internet orders */}
                {isInternetOrder && !addressConfirmed && !editing && (
                  <Button
                    type="button"
                    onClick={handleConfirmAddress}
                    onKeyDown={e => {
                      if (e.key === "Enter" || e.key === " ") {
                        e.preventDefault();
                        e.stopPropagation();
                      }
                    }}
                  >
                    Confirm Address
                  </Button>
                )}

                {/* Edit button */}
                {billingInfo.isComplete && !editing && (
                  <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    onClick={handleEdit}
                    leftIcon={<PencilIcon className="h-4 w-4" />}
                  >
                    Edit Address
                  </Button>
                )}
              </div>
            </div>
          ) : (
            <div className="text-center py-8">
              <div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
                <MapPinIcon className="h-8 w-8 text-gray-400" />
              </div>
              <h4 className="text-lg font-medium text-gray-900 mb-2">No Address on File</h4>
              <p className="text-gray-600 mb-6">
                Please add your installation address to continue.
              </p>
              <Button type="button" onClick={handleEdit}>
                Add Address
              </Button>
            </div>
          )}
        </div>
      )}
    </>
  );
}
