"use client";

/**
 * JapanAddressForm - Complete Japanese address form with ZIP code lookup
 *
 * Features:
 * - ZIP code lookup via Japan Post API (required)
 * - Auto-fill prefecture, city, town from ZIP (read-only)
 * - Progressive disclosure with smooth animations
 * - House/Apartment toggle with conditional room number
 * - Captures both Japanese and English (romanized) addresses
 * - Compatible with WHMCS and Salesforce field mapping
 */

import { Home, Building2, CheckCircle2, MapPin, ChevronRight, Sparkles } from "lucide-react";
import { Input } from "@/components/atoms";
import { FormField } from "@/components/molecules/FormField/FormField";
import { cn } from "@/shared/utils";
import { ZipCodeInput } from "./ZipCodeInput";
import { AnimatedSection } from "./AnimatedSection";
import { ProgressIndicator } from "./ProgressIndicator";
import { BilingualValue } from "./BilingualValue";
import {
  type BilingualAddress,
  RESIDENCE_TYPE,
  type ResidenceType,
  ADDRESS_INPUT_LIMITS,
} from "@customer-portal/domain/address";
import { useJapanAddressForm } from "@/features/address/hooks";
import {
  TOTAL_FORM_STEPS,
  isValidStreetAddress,
  getStreetAddressError,
} from "@/features/address/utils";

// ============================================================================
// Types
// ============================================================================

export type JapanAddressFormData = BilingualAddress;

/**
 * Type for partial initial values that allows undefined residenceType.
 */
type JapanAddressFormInitialValues = Omit<JapanAddressFormData, "residenceType"> & {
  residenceType?: ResidenceType | undefined;
};

export interface JapanAddressFormProps {
  /** Initial address values */
  initialValues?: Partial<JapanAddressFormInitialValues> | undefined;
  /** Called when any address field changes */
  onChange?: ((address: JapanAddressFormData, isComplete: boolean) => void) | undefined;
  /** Field-level errors (keyed by field name) */
  errors?: Partial<Record<keyof JapanAddressFormData, string | undefined>> | undefined;
  /** Fields that have been touched */
  touched?: Partial<Record<keyof JapanAddressFormData, boolean | undefined>> | undefined;
  /** Mark a field as touched */
  onBlur?: ((field: keyof JapanAddressFormData) => void) | undefined;
  /** Whether the form is disabled */
  disabled?: boolean | undefined;
  /** Custom class name for container */
  className?: string | undefined;
  /** Custom content to render when address is complete (replaces default success message) */
  completionContent?: React.ReactNode | undefined;
}

// ============================================================================
// Step Header Component
// ============================================================================

function StepHeader({
  stepNumber,
  label,
  isComplete,
  badge,
}: {
  stepNumber: number;
  label: string;
  isComplete: boolean;
  badge?: React.ReactNode;
}) {
  return (
    <div className="flex items-center gap-2 mb-3">
      <div
        className={cn(
          "flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold transition-all duration-300",
          isComplete ? "bg-success text-success-foreground" : "bg-primary/10 text-primary"
        )}
      >
        {isComplete ? <CheckCircle2 className="w-4 h-4" /> : stepNumber}
      </div>
      <span className="text-sm font-medium text-foreground">{label}</span>
      {badge}
    </div>
  );
}

// ============================================================================
// Verified Address Display Component
// ============================================================================

function VerifiedAddressDisplay({
  address,
  isVerified,
}: {
  address: {
    prefecture: string;
    prefectureJa: string;
    city: string;
    cityJa: string;
    town: string;
    townJa: string;
  };
  isVerified: boolean;
}) {
  return (
    <div
      className={cn(
        "rounded-xl border transition-all duration-500",
        "bg-gradient-to-br from-success/5 via-success/[0.02] to-transparent",
        "border-success/20"
      )}
    >
      <div className="p-4 space-y-3">
        <div className="flex items-center gap-2 text-success">
          <MapPin className="w-4 h-4" />
          <span className="text-sm font-semibold">Address from Japan Post</span>
        </div>

        <div className="grid gap-2">
          <div className="flex items-center gap-3 py-2 px-3 rounded-lg bg-background/50">
            <span className="text-xs text-muted-foreground w-20 shrink-0">Prefecture</span>
            <ChevronRight className="w-3 h-3 text-muted-foreground/50" />
            <BilingualValue
              romaji={address.prefecture}
              japanese={address.prefectureJa}
              placeholder="—"
              verified={isVerified}
            />
          </div>

          <div className="flex items-center gap-3 py-2 px-3 rounded-lg bg-background/50">
            <span className="text-xs text-muted-foreground w-20 shrink-0">City / Ward</span>
            <ChevronRight className="w-3 h-3 text-muted-foreground/50" />
            <BilingualValue
              romaji={address.city}
              japanese={address.cityJa}
              placeholder="—"
              verified={isVerified}
            />
          </div>

          <div className="flex items-center gap-3 py-2 px-3 rounded-lg bg-background/50">
            <span className="text-xs text-muted-foreground w-20 shrink-0">Town</span>
            <ChevronRight className="w-3 h-3 text-muted-foreground/50" />
            <BilingualValue
              romaji={address.town}
              japanese={address.townJa}
              placeholder="—"
              verified={isVerified}
            />
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// Residence Type Selector Component
// ============================================================================

function ResidenceTypeSelector({
  value,
  onChange,
  disabled,
  error,
}: {
  value: ResidenceType | "";
  onChange: (type: ResidenceType) => void;
  disabled: boolean;
  error?: string | undefined;
}) {
  return (
    <div>
      <div className="grid grid-cols-2 gap-3">
        <button
          type="button"
          onClick={() => onChange(RESIDENCE_TYPE.HOUSE)}
          disabled={disabled}
          className={cn(
            "group relative flex flex-col items-center gap-2 p-4 rounded-xl border-2 transition-all duration-300",
            "hover:scale-[1.02] active:scale-[0.98]",
            value === RESIDENCE_TYPE.HOUSE
              ? "border-primary bg-primary/5 shadow-[0_0_0_4px] shadow-primary/10"
              : "border-border bg-card hover:border-primary/50 hover:bg-primary/[0.02]",
            disabled && "opacity-50 cursor-not-allowed hover:scale-100"
          )}
        >
          <div
            className={cn(
              "w-12 h-12 rounded-xl flex items-center justify-center transition-all duration-300",
              value === RESIDENCE_TYPE.HOUSE
                ? "bg-primary text-primary-foreground"
                : "bg-muted text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary"
            )}
          >
            <Home className="w-6 h-6" />
          </div>
          <span
            className={cn(
              "text-sm font-semibold transition-colors",
              value === RESIDENCE_TYPE.HOUSE ? "text-primary" : "text-foreground"
            )}
          >
            House
          </span>
        </button>

        <button
          type="button"
          onClick={() => onChange(RESIDENCE_TYPE.APARTMENT)}
          disabled={disabled}
          className={cn(
            "group relative flex flex-col items-center gap-2 p-4 rounded-xl border-2 transition-all duration-300",
            "hover:scale-[1.02] active:scale-[0.98]",
            value === RESIDENCE_TYPE.APARTMENT
              ? "border-primary bg-primary/5 shadow-[0_0_0_4px] shadow-primary/10"
              : "border-border bg-card hover:border-primary/50 hover:bg-primary/[0.02]",
            disabled && "opacity-50 cursor-not-allowed hover:scale-100"
          )}
        >
          <div
            className={cn(
              "w-12 h-12 rounded-xl flex items-center justify-center transition-all duration-300",
              value === RESIDENCE_TYPE.APARTMENT
                ? "bg-primary text-primary-foreground"
                : "bg-muted text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary"
            )}
          >
            <Building2 className="w-6 h-6" />
          </div>
          <span
            className={cn(
              "text-sm font-semibold transition-colors",
              value === RESIDENCE_TYPE.APARTMENT ? "text-primary" : "text-foreground"
            )}
          >
            Apartment
          </span>
        </button>
      </div>

      {error && <p className="text-sm text-danger mt-2">{error}</p>}
    </div>
  );
}

// ============================================================================
// Main Component
// ============================================================================

function ZipCodeStep({
  form,
  disabled,
}: {
  form: ReturnType<typeof useJapanAddressForm>;
  disabled: boolean;
}) {
  return (
    <div>
      <StepHeader
        stepNumber={1}
        label="Enter ZIP Code"
        isComplete={form.isAddressVerified}
        badge={
          form.isAddressVerified && (
            <span className="text-xs text-success font-medium ml-auto flex items-center gap-1">
              <Sparkles className="w-3 h-3" />
              Verified
            </span>
          )
        }
      />
      <ZipCodeInput
        value={form.address.postcode}
        onChange={form.handlers.handleZipChange}
        onAddressFound={form.handlers.handleAddressFound}
        onLookupComplete={form.handlers.handleLookupComplete}
        error={form.getError("postcode")}
        required
        disabled={disabled}
        autoFocus
      />
    </div>
  );
}

function StreetAddressStep({
  form,
  disabled,
  onBlur,
}: {
  form: ReturnType<typeof useJapanAddressForm>;
  disabled: boolean;
  onBlur?: ((field: keyof BilingualAddress) => void) | undefined;
}) {
  const streetAddressError = getStreetAddressError(form.address.streetAddress);
  const hasInput = form.address.streetAddress.trim();
  const helperText = hasInput
    ? streetAddressError
      ? undefined
      : "Valid format"
    : "Enter chome-banchi-go (e.g., 1-5-3)";
  return (
    <div>
      <StepHeader
        stepNumber={2}
        label="Street Address"
        isComplete={isValidStreetAddress(form.address.streetAddress)}
      />
      <FormField
        label=""
        error={form.getError("streetAddress") || (hasInput && streetAddressError)}
        required
        helperText={helperText}
      >
        <Input
          ref={form.streetAddressRef}
          value={form.address.streetAddress}
          onChange={e => form.handlers.handleStreetAddressChange(e.target.value)}
          onBlur={() => onBlur?.("streetAddress")}
          placeholder="1-5-3"
          disabled={disabled}
          className="font-mono text-lg tracking-wider"
          data-field="address.streetAddress"
        />
      </FormField>
    </div>
  );
}

function BuildingDetailsStep({
  form,
  disabled,
  onBlur,
}: {
  form: ReturnType<typeof useJapanAddressForm>;
  disabled: boolean;
  onBlur?: ((field: keyof BilingualAddress) => void) | undefined;
}) {
  return (
    <div className="space-y-4">
      <StepHeader stepNumber={4} label="Building Details" isComplete={form.showSuccess} />
      <FormField
        label="Building Name"
        error={form.getError("buildingName")}
        required
        helperText={
          form.isApartment
            ? "e.g., Sunshine Mansion (サンシャインマンション)"
            : "e.g., Tanaka Residence (田中邸)"
        }
      >
        <Input
          value={form.address.buildingName ?? ""}
          onChange={e => form.handlers.handleBuildingNameChange(e.target.value)}
          onBlur={() => onBlur?.("buildingName")}
          placeholder={form.isApartment ? "Sunshine Mansion" : "Tanaka Residence"}
          disabled={disabled}
          maxLength={ADDRESS_INPUT_LIMITS.BUILDING_NAME_MAX}
          data-field="address.buildingName"
        />
      </FormField>
      {form.isApartment && (
        <FormField
          label="Room Number"
          error={form.getError("roomNumber")}
          required
          helperText="Required for apartments (部屋番号)"
        >
          <Input
            value={form.address.roomNumber ?? ""}
            onChange={e => form.handlers.handleRoomNumberChange(e.target.value)}
            onBlur={() => onBlur?.("roomNumber")}
            placeholder="201"
            disabled={disabled}
            maxLength={ADDRESS_INPUT_LIMITS.ROOM_NUMBER_MAX}
            className="font-mono"
            data-field="address.roomNumber"
          />
        </FormField>
      )}
    </div>
  );
}

function DefaultCompletionContent() {
  return (
    <div className="rounded-xl bg-gradient-to-br from-success/10 via-success/5 to-transparent border border-success/20 p-4">
      <div className="flex items-center gap-3">
        <div className="w-10 h-10 rounded-full bg-success/20 flex items-center justify-center">
          <CheckCircle2 className="w-5 h-5 text-success" />
        </div>
        <div>
          <p className="text-sm font-semibold text-foreground">Address Complete</p>
          <p className="text-xs text-muted-foreground">All address fields have been filled</p>
        </div>
      </div>
    </div>
  );
}

export function JapanAddressForm({
  initialValues,
  onChange,
  errors = {},
  touched = {},
  onBlur,
  disabled = false,
  className,
  completionContent,
}: JapanAddressFormProps) {
  const form = useJapanAddressForm({ initialValues, onChange, errors, touched, disabled });

  return (
    <div className={cn("space-y-6", className)}>
      <ProgressIndicator currentStep={form.completion.currentStep} totalSteps={TOTAL_FORM_STEPS} />
      <ZipCodeStep form={form} disabled={disabled} />
      <AnimatedSection show={form.isAddressVerified}>
        <VerifiedAddressDisplay address={form.address} isVerified={form.isAddressVerified} />
      </AnimatedSection>
      <AnimatedSection show={form.isAddressVerified} delay={100}>
        <StreetAddressStep form={form} disabled={disabled} onBlur={onBlur} />
      </AnimatedSection>
      <AnimatedSection
        show={form.isAddressVerified && isValidStreetAddress(form.address.streetAddress)}
        delay={150}
      >
        <div>
          <StepHeader
            stepNumber={3}
            label="Residence Type"
            isComplete={form.completion.hasResidenceType}
          />
          <ResidenceTypeSelector
            value={form.address.residenceType}
            onChange={form.handlers.handleResidenceTypeChange}
            disabled={disabled}
            error={form.completion.hasResidenceType ? undefined : form.getError("residenceType")}
          />
        </div>
      </AnimatedSection>
      <AnimatedSection
        show={form.isAddressVerified && form.completion.hasResidenceType}
        delay={200}
      >
        <BuildingDetailsStep form={form} disabled={disabled} onBlur={onBlur} />
      </AnimatedSection>
      <AnimatedSection show={form.showSuccess} delay={250}>
        {completionContent ?? <DefaultCompletionContent />}
      </AnimatedSection>
    </div>
  );
}
