"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, useRef } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { accountService } from "@/features/account/api/account.api";
import { logger } from "@/core/logger";
import { StatusPill } from "@/components/atoms/status-pill";
import { MapPinIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { getCountryName } from "@/shared/constants";
import { queryKeys } from "@/core/api";

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

// Japan address form with ZIP lookup
import { JapanAddressForm } from "@/features/address/components/JapanAddressForm";

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
  titleOverride?: string;
  confirmationPrompt?: string;
}

export function AddressConfirmation({
  onAddressConfirmed,
  onAddressIncomplete,
  orderType,
  embedded = false,
  titleOverride,
  confirmationPrompt,
}: AddressConfirmationProps) {
  const queryClient = useQueryClient();
  const [billingInfo, setBillingInfo] = useState<BillingInfo | null>(null);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState(false);
  const [bilingualAddress, setBilingualAddress] = useState<Partial<BilingualAddress> | null>(null);
  const [isAddressComplete, setIsAddressComplete] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [addressConfirmed, setAddressConfirmed] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const onAddressConfirmedRef = useRef(onAddressConfirmed);
  const onAddressIncompleteRef = useRef(onAddressIncomplete);

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

  useEffect(() => {
    onAddressConfirmedRef.current = onAddressConfirmed;
  }, [onAddressConfirmed]);

  useEffect(() => {
    onAddressIncompleteRef.current = onAddressIncomplete;
  }, [onAddressIncomplete]);

  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);
        onAddressIncompleteRef.current();
      } else if (isComplete && normalizedAddress) {
        onAddressConfirmedRef.current(normalizedAddress);
        setAddressConfirmed(true);
      } else {
        onAddressIncompleteRef.current();
        setAddressConfirmed(false);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to load address");
    } finally {
      setLoading(false);
    }
  }, [requiresAddressVerification, setAddressConfirmed]);

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

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

    setEditing(true);
    setError(null);
    // Initialize with empty bilingual address - user will use ZIP lookup
    setBilingualAddress(null);
    setIsAddressComplete(false);
  };

  // Handle JapanAddressForm changes
  const handleBilingualAddressChange = useCallback(
    (address: BilingualAddress, complete: boolean) => {
      setBilingualAddress(address);
      setIsAddressComplete(complete);
      setError(null);
    },
    []
  );

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

    if (!bilingualAddress || !isAddressComplete) {
      setError("Please complete all required address fields");
      return;
    }

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

        // Dual-write: English to WHMCS, Japanese to Salesforce
        const updatedAddress = await accountService.updateBilingualAddress(
          bilingualAddress as BilingualAddress
        );

        // Address changes can affect server-personalized services results (eligibility).
        await queryClient.invalidateQueries({ queryKey: queryKeys.services.all() });

        // 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);

        logger.info("Address updated with dual-write (WHMCS + Salesforce)", {
          hasJapaneseAddress: !!bilingualAddress.prefectureJa,
        });
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to update address");
      } finally {
        setIsSaving(false);
      }
    })();
  };

  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();

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

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

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

    setEditing(false);
    setBilingualAddress(null);
    setIsAddressComplete(false);
    setError(null);
  };

  const statusVariant = addressConfirmed || !requiresAddressVerification ? "success" : "warning";
  const headerTitle = (() => {
    if (titleOverride) return titleOverride;
    if (isInternetOrder) return "Installation Address";
    if (billingInfo?.isComplete) return "Service Address";
    return "Complete Your Address";
  })();
  const confirmationMessage =
    confirmationPrompt ??
    "Please confirm this is the correct installation address for your internet service.";

  // 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-muted-foreground">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;

  const showConfirmAction =
    isInternetOrder && !addressConfirmed && !editing && billingInfo.isComplete;
  const showEditAction = billingInfo.isComplete && !editing;

  return wrap(
    <>
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mb-4">
        <div className="flex items-center space-x-3">
          <MapPinIcon className="h-5 w-5 text-primary" />
          <div>
            <h3 className="text-lg font-semibold text-foreground">{headerTitle}</h3>
          </div>
        </div>
        <div className="flex flex-wrap items-center gap-2 sm:justify-end">
          <StatusPill
            label={statusVariant === "success" ? "Verified" : "Pending confirmation"}
            variant={statusVariant}
          />
          {showConfirmAction ? (
            <Button
              type="button"
              size="sm"
              onClick={handleConfirmAddress}
              onKeyDown={e => {
                if (e.key === "Enter" || e.key === " ") {
                  e.preventDefault();
                  e.stopPropagation();
                }
              }}
            >
              Confirm Address
            </Button>
          ) : null}
          {showEditAction ? (
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={handleEdit}
              leftIcon={<PencilIcon className="h-4 w-4" />}
            >
              Edit Address
            </Button>
          ) : null}
        </div>
      </div>

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

      {editing ? (
        <div className="space-y-4">
          <AlertBanner variant="info" title="Japan Address" size="sm">
            Enter your ZIP code to auto-fill address fields from Japan Post.
          </AlertBanner>

          <JapanAddressForm onChange={handleBilingualAddressChange} disabled={isSaving} />

          {error && (
            <AlertBanner variant="error" title="Error" size="sm">
              {error}
            </AlertBanner>
          )}

          <div className="flex items-center space-x-3 pt-4">
            <Button
              type="button"
              onClick={handleSave}
              leftIcon={<CheckIcon className="h-4 w-4" />}
              disabled={!isAddressComplete || isSaving}
              isLoading={isSaving}
              loadingText="Saving..."
            >
              Save Address
            </Button>
            <Button
              type="button"
              onClick={handleCancel}
              variant="outline"
              leftIcon={<XMarkIcon className="h-4 w-4" />}
              disabled={isSaving}
            >
              Cancel
            </Button>
          </div>
        </div>
      ) : (
        <div>
          {address?.address1 ? (
            <div className="space-y-4">
              <div className="text-foreground space-y-1">
                {(address.address2 || address.address1) && (
                  <p className="font-semibold text-base">{address.address2 || address.address1}</p>
                )}
                {address.address2 && address.address1 ? (
                  <p className="text-muted-foreground">{address.address1}</p>
                ) : null}
                <p className="text-muted-foreground">
                  {[address.city, address.state].filter(Boolean).join(", ")}
                  {address.postcode ? ` ${address.postcode}` : ""}
                </p>
                {countryLabel && <p className="text-muted-foreground">{countryLabel}</p>}
              </div>

              {/* Status message for Internet orders when pending */}
              {isInternetOrder && !addressConfirmed && (
                <AlertBanner variant="warning" title="Verification Required" size="sm" elevated>
                  {confirmationMessage}
                </AlertBanner>
              )}
            </div>
          ) : (
            <div className="text-center py-8">
              <div className="w-16 h-16 bg-muted rounded-full flex items-center justify-center mx-auto mb-4 border border-border shadow-[var(--cp-shadow-1)]">
                <MapPinIcon className="h-8 w-8 text-muted-foreground" />
              </div>
              <h4 className="text-lg font-medium text-foreground mb-2">No Address on File</h4>
              <p className="text-muted-foreground mb-6">
                Please add your installation address to continue.
              </p>
              <Button type="button" onClick={handleEdit}>
                Add Address
              </Button>
            </div>
          )}
        </div>
      )}
    </>
  );
}
