"use client";

import { useMemo, useState } from "react";
import {
  ArrowRight,
  Check,
  Sparkles,
  Wifi,
  Zap,
  Languages,
  FileText,
  Wrench,
  Globe,
  ChevronDown,
  Home,
  Building,
} from "lucide-react";
import { usePublicInternetCatalog } from "@/features/services/hooks";
import type {
  InternetInstallationCatalogItem,
  InternetPlanCatalogItem,
} from "@customer-portal/domain/services";
import { Skeleton } from "@/components/atoms/loading-skeleton";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
import { ServicesBackLink } from "@/features/services/components/base/ServicesBackLink";
import { ServicesHero } from "@/features/services/components/base/ServicesHero";
import { useServicesBasePath } from "@/features/services/hooks/useServicesBasePath";
import { Button } from "@/components/atoms/button";
import {
  ServiceHighlights,
  HighlightFeature,
} from "@/features/services/components/base/ServiceHighlights";
import { HowItWorksSection } from "@/features/services/components/internet/HowItWorksSection";
import {
  type InternetTier,
  TIER_ORDER_MAP,
  getTierDescription,
  getTierFeatures,
} from "@/features/services/utils/internet-config";
import { AnimatePresence, motion } from "framer-motion";
import { cn } from "@/shared/utils";
import { motionVariants } from "@/components/atoms";

// ─── Types ────────────────────────────────────────────────────────────────────

interface TierInfo {
  tier: InternetTier;
  monthlyPrice: number;
  maxMonthlyPrice?: number;
  description: string;
  features: string[];
  pricingNote?: string;
}

type OfferingKey = "all" | "home10g" | "home1g" | "apartment";

interface OfferingOption {
  key: OfferingKey;
  label: string;
  shortLabel: string;
  icon: React.ReactNode;
}

// ─── Constants ────────────────────────────────────────────────────────────────

const tierStyles = {
  Silver: {
    card: "border-border bg-card border-l-4 border-l-muted-foreground/60",
    accent: "text-muted-foreground",
  },
  Gold: {
    card: "border-border bg-card border-l-4 border-l-amber-500",
    accent: "text-amber-600",
  },
  Platinum: {
    card: "border-border bg-card border-l-4 border-l-primary",
    accent: "text-primary",
  },
} as const;

const OFFERING_OPTIONS: OfferingOption[] = [
  {
    key: "all",
    label: "All Plans",
    shortLabel: "All",
    icon: <Wifi className="h-3.5 w-3.5" />,
  },
  {
    key: "home10g",
    label: "Home 10Gbps",
    shortLabel: "10G",
    icon: <Home className="h-3.5 w-3.5" />,
  },
  {
    key: "home1g",
    label: "Home 1Gbps",
    shortLabel: "1G",
    icon: <Home className="h-3.5 w-3.5" />,
  },
  {
    key: "apartment",
    label: "Apartment",
    shortLabel: "Apt",
    icon: <Building className="h-3.5 w-3.5" />,
  },
];

// ─── Helpers ──────────────────────────────────────────────────────────────────

function getOfferingTypeId(offeringType: string | undefined): string {
  if (!offeringType) return "home1g";
  const type = offeringType.toLowerCase();
  if (type.includes("10g") || type.includes("10gbps")) return "home10g";
  if (type.includes("apartment") || type.includes("mansion")) return "apartment";
  if (type.includes("1g") || type.includes("1gbps") || type.includes("home")) return "home1g";
  return "home1g";
}

const cardVariants = motionVariants.fadeUp;

const tierContainerVariants = {
  ...motionVariants.staggerContainer(0.08),
  exit: {
    opacity: 0,
    x: -24,
    transition: { duration: 0.2 },
  },
};

// ─── Unified Internet Card ────────────────────────────────────────────────────

const OFFERING_DESCRIPTIONS: Record<string, string> = {
  home10g: "Ultra-fast fiber — available in select areas.",
  home1g: "High-speed fiber — the most popular choice for homes.",
  apartment: "For mansions and apartment buildings. Speed depends on building infrastructure.",
  all: "Select a connection type above to see exact pricing, or browse all tiers below.",
};

function InternetCardHeader({
  displayMinPrice,
  displayMaxPrice,
  selectedOffering,
}: {
  displayMinPrice: number;
  displayMaxPrice: number;
  selectedOffering: OfferingKey;
}) {
  const showRange = displayMinPrice !== displayMaxPrice;
  return (
    <div className="p-5 border-b border-border bg-muted/20">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div className="flex items-center gap-3">
          <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary">
            <Wifi className="h-5 w-5" />
          </div>
          <div>
            <h3 className="text-lg font-bold text-foreground">NTT Fiber Internet</h3>
            <p className="text-sm text-muted-foreground">Home & Apartment plans available</p>
          </div>
        </div>
        <div className="text-left sm:text-right">
          <div className="flex items-baseline gap-1 transition-opacity duration-200">
            <span className="text-2xl font-bold text-foreground">
              ¥{displayMinPrice.toLocaleString()}
              {showRange && `~${displayMaxPrice.toLocaleString()}`}
            </span>
            <span className="text-sm text-muted-foreground">/mo</span>
          </div>
          <p className="text-xs text-muted-foreground">
            {selectedOffering === "all"
              ? "Price varies by location & tier"
              : "Price varies by tier"}
          </p>
        </div>
      </div>
    </div>
  );
}

function TierCard({ tier }: { tier: TierInfo }) {
  const pricingNoteClass = tier.tier === "Platinum" ? "text-primary" : "text-amber-600";
  return (
    <div
      className={cn(
        "rounded-xl border p-4 pt-6 transition-all duration-200 flex flex-col relative h-full",
        tierStyles[tier.tier].card
      )}
    >
      {tier.tier === "Gold" && (
        <div className="absolute -top-3 left-1/2 -translate-x-1/2">
          <span className="inline-flex items-center gap-1 px-3 py-1 rounded-full bg-amber-500 text-white text-xs font-semibold shadow-sm">
            <Sparkles className="h-3 w-3" />
            Popular
          </span>
        </div>
      )}
      <h4 className={cn("font-bold text-lg mb-2", tierStyles[tier.tier].accent)}>{tier.tier}</h4>
      <div className="mb-3 flex items-baseline gap-1 flex-wrap">
        <span className="text-2xl font-bold text-foreground whitespace-nowrap">
          ¥{tier.monthlyPrice.toLocaleString()}
          {tier.maxMonthlyPrice &&
            tier.maxMonthlyPrice > tier.monthlyPrice &&
            `~${tier.maxMonthlyPrice.toLocaleString()}`}
        </span>
        <span className="text-sm text-muted-foreground">/mo</span>
        {tier.pricingNote && (
          <span className={`text-xs ${pricingNoteClass}`}>{tier.pricingNote}</span>
        )}
      </div>
      <p className="text-sm text-muted-foreground mb-3">{tier.description}</p>
      <ul className="space-y-2 flex-grow">
        {tier.features.map((feature, index) => (
          <li key={index} className="flex items-start gap-2 text-sm">
            <Check className="h-4 w-4 text-muted-foreground flex-shrink-0 mt-0.5" />
            <span className="text-muted-foreground">{feature}</span>
          </li>
        ))}
      </ul>
    </div>
  );
}

function UnifiedInternetCard({
  consolidatedTiers,
  consolidatedMinPrice,
  consolidatedMaxPrice,
  plansByOffering,
  setupFee,
  ctaPath,
  ctaLabel,
  onCtaClick,
}: {
  consolidatedTiers: TierInfo[];
  consolidatedMinPrice: number;
  consolidatedMaxPrice: number;
  plansByOffering: Record<string, { minPrice: number; tiers: TierInfo[] }>;
  setupFee: number;
  ctaPath: string;
  ctaLabel: string;
  onCtaClick?: (e: React.MouseEvent) => void;
}) {
  const [selectedOffering, setSelectedOffering] = useState<OfferingKey>("all");

  const { displayTiers, displayMinPrice, displayMaxPrice } = useMemo(() => {
    if (selectedOffering === "all" || !plansByOffering[selectedOffering]) {
      return {
        displayTiers: consolidatedTiers,
        displayMinPrice: consolidatedMinPrice,
        displayMaxPrice: consolidatedMaxPrice,
      };
    }
    const offeringData = plansByOffering[selectedOffering];
    const prices = offeringData.tiers.map(t => t.monthlyPrice);
    return {
      displayTiers: offeringData.tiers,
      displayMinPrice: Math.min(...prices),
      displayMaxPrice: Math.max(...prices),
    };
  }, [
    selectedOffering,
    consolidatedTiers,
    consolidatedMinPrice,
    consolidatedMaxPrice,
    plansByOffering,
  ]);

  const availableOptions = OFFERING_OPTIONS.filter(
    opt => opt.key === "all" || plansByOffering[opt.key]
  );

  return (
    <div className="rounded-xl border border-border bg-card shadow-[var(--cp-shadow-1)] overflow-hidden">
      <InternetCardHeader
        displayMinPrice={displayMinPrice}
        displayMaxPrice={displayMaxPrice}
        selectedOffering={selectedOffering}
      />

      <div className="px-5 pt-5 pb-2">
        <p className="text-sm font-medium text-foreground mb-3">Choose your connection type:</p>
        <div className="flex overflow-x-auto scrollbar-hide -mx-1 px-1 pb-1">
          <div className="inline-flex rounded-lg bg-muted/60 p-0.5 border border-border/60">
            {availableOptions.map(option => (
              <button
                key={option.key}
                type="button"
                onClick={() => setSelectedOffering(option.key)}
                className={cn(
                  "flex items-center gap-1.5 px-3 py-2 rounded-md text-sm font-medium transition-all whitespace-nowrap",
                  selectedOffering === option.key
                    ? "bg-card text-foreground shadow-sm"
                    : "text-muted-foreground hover:text-foreground"
                )}
              >
                {option.icon}
                <span className="hidden sm:inline">{option.label}</span>
                <span className="sm:hidden">{option.shortLabel}</span>
              </button>
            ))}
          </div>
        </div>
        <p className="text-xs text-muted-foreground mt-2">
          {OFFERING_DESCRIPTIONS[selectedOffering]}
        </p>
      </div>

      <div className="p-5 pt-3">
        <AnimatePresence mode="wait">
          <motion.div
            key={selectedOffering}
            className="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-6"
            initial="hidden"
            animate="visible"
            exit="exit"
            variants={tierContainerVariants}
          >
            {displayTiers.map(tier => (
              <motion.div key={tier.tier} variants={cardVariants} className="h-full">
                <TierCard tier={tier} />
              </motion.div>
            ))}
          </motion.div>
        </AnimatePresence>
        <div className="flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-4 pt-4 border-t border-border">
          <p className="text-sm text-muted-foreground">
            <span className="font-semibold text-foreground">
              + ¥{setupFee.toLocaleString()} one-time setup
            </span>{" "}
            (or 12/24-month installment)
          </p>
          {onCtaClick ? (
            <Button onClick={onCtaClick} size="lg" className="whitespace-nowrap">
              {ctaLabel}
            </Button>
          ) : (
            <Button as="a" href={ctaPath} size="lg" className="whitespace-nowrap">
              {ctaLabel}
            </Button>
          )}
        </div>
      </div>
    </div>
  );
}

// ─── Public Internet Plans Content ────────────────────────────────────────────

export interface PublicInternetPlansContentProps {
  onCtaClick?: (e: React.MouseEvent) => void;
  ctaPath?: string;
  ctaLabel?: string;
  heroTitle?: string;
  heroDescription?: string;
}

const INTERNET_FEATURES: HighlightFeature[] = [
  {
    icon: <Wifi className="h-6 w-6" />,
    title: "NTT Optical Fiber",
    description: "Japan's most reliable network with speeds up to 10Gbps",
    highlight: "99.9% uptime",
  },
  {
    icon: <Languages className="h-6 w-6" />,
    title: "No Japanese Required",
    description: "English contracts, English support, English installation coordination",
    highlight: "Fully bilingual",
  },
  {
    icon: <FileText className="h-6 w-6" />,
    title: "We Handle the Paperwork",
    description: "No need to navigate Japanese forms or phone calls",
    highlight: "Hassle-free setup",
  },
  {
    icon: <Zap className="h-6 w-6" />,
    title: "IPv6/IPoE Ready",
    description: "Next-gen protocol for congestion-free browsing",
    highlight: "No slowdowns",
  },
  {
    icon: <Wrench className="h-6 w-6" />,
    title: "English Onsite Support",
    description: "Our technicians speak English and can visit your home",
    highlight: "In-person help",
  },
  {
    icon: <Globe className="h-6 w-6" />,
    title: "Flexible Contracts",
    description: "Monthly billing, no long-term commitment required",
    highlight: "Cancel anytime",
  },
];

const DEFAULT_OFFERING_PRICES: Record<string, { Silver: number; Gold: number; Platinum: number }> =
  {
    home10g: { Silver: 8000, Gold: 8500, Platinum: 8500 },
    home1g: { Silver: 6000, Gold: 6500, Platinum: 6500 },
    apartment: { Silver: 4800, Gold: 5300, Platinum: 5300 },
  };

function buildTierInfo(tier: string, price: number): TierInfo {
  return {
    tier: tier as TierInfo["tier"],
    monthlyPrice: price,
    description: getTierDescription(tier, true),
    features: getTierFeatures(tier, true),
    ...(tier === "Platinum" && { pricingNote: "+ equipment fees" }),
  };
}

function buildConsolidatedPlanData(servicesCatalog: {
  plans: InternetPlanCatalogItem[];
  installations?: InternetInstallationCatalogItem[];
}) {
  const installationItem = servicesCatalog.installations?.[0] as
    | InternetInstallationCatalogItem
    | undefined;
  const setupFee = installationItem?.oneTimePrice ?? 22800;
  const allPrices = servicesCatalog.plans.map(p => p.monthlyPrice ?? 0).filter(p => p > 0);

  const tierData: Record<string, { minPrice: number; maxPrice: number }> = {};
  for (const plan of servicesCatalog.plans) {
    const tier = plan.internetPlanTier ?? "Silver";
    const price = plan.monthlyPrice ?? 0;
    if (!tierData[tier]) tierData[tier] = { minPrice: Infinity, maxPrice: 0 };
    tierData[tier].minPrice = Math.min(tierData[tier].minPrice, price);
    tierData[tier].maxPrice = Math.max(tierData[tier].maxPrice, price);
  }

  const tiers: TierInfo[] = Object.entries(tierData)
    .sort(([a], [b]) => (TIER_ORDER_MAP[a] ?? 99) - (TIER_ORDER_MAP[b] ?? 99))
    .map(([tier, data]) => ({
      ...buildTierInfo(tier, data.minPrice),
      maxMonthlyPrice: data.maxPrice,
    }));

  return { minPrice: Math.min(...allPrices), maxPrice: Math.max(...allPrices), setupFee, tiers };
}

function ensureOfferingDefaults(
  offeringData: Record<string, { minPrice: number; tierData: Record<string, { price: number }> }>
) {
  for (const [configId, defaults] of Object.entries(DEFAULT_OFFERING_PRICES)) {
    const existing = offeringData[configId];
    if (existing) {
      for (const [tier, price] of Object.entries(defaults)) {
        if (!existing.tierData[tier]) existing.tierData[tier] = { price };
      }
      const allPrices = Object.values(existing.tierData).map(t => t.price);
      existing.minPrice = Math.min(...allPrices);
    } else {
      const tierData: Record<string, { price: number }> = {};
      for (const [tier, price] of Object.entries(defaults)) {
        tierData[tier] = { price };
      }
      offeringData[configId] = { minPrice: defaults.Silver, tierData };
    }
  }
}

function buildPlansByOffering(plans: InternetPlanCatalogItem[]) {
  const offeringData: Record<
    string,
    { minPrice: number; tierData: Record<string, { price: number }> }
  > = {};

  for (const plan of plans) {
    const offeringType = getOfferingTypeId(plan.internetOfferingType);
    const tier = plan.internetPlanTier ?? "Silver";
    const price = plan.monthlyPrice ?? 0;
    if (!offeringData[offeringType])
      offeringData[offeringType] = { minPrice: Infinity, tierData: {} };
    offeringData[offeringType].minPrice = Math.min(offeringData[offeringType].minPrice, price);
    if (
      !offeringData[offeringType].tierData[tier] ||
      price < offeringData[offeringType].tierData[tier].price
    ) {
      offeringData[offeringType].tierData[tier] = { price };
    }
  }

  ensureOfferingDefaults(offeringData);

  const result: Record<string, { minPrice: number; tiers: TierInfo[] }> = {};
  for (const [offeringType, data] of Object.entries(offeringData)) {
    const tiers = Object.entries(data.tierData)
      .sort(([a], [b]) => (TIER_ORDER_MAP[a] ?? 99) - (TIER_ORDER_MAP[b] ?? 99))
      .map(([tier, tierInfo]) => buildTierInfo(tier, tierInfo.price));
    result[offeringType] = { minPrice: data.minPrice, tiers };
  }
  return result;
}

function FinalCtaSection({
  onCtaClick,
  ctaPath,
  ctaLabel,
}: {
  onCtaClick?: ((e: React.MouseEvent) => void) | undefined;
  ctaPath: string;
  ctaLabel: string;
}) {
  return (
    <section className="text-center py-8 mt-4 rounded-2xl bg-gradient-to-br from-primary/5 via-transparent to-info/5 border border-border/50">
      <div className="inline-flex items-center gap-1.5 text-xs font-medium text-primary mb-3 px-3 py-1 rounded-full bg-primary/10">
        <Sparkles className="h-3.5 w-3.5" />
        Get started in minutes
      </div>
      <h2 className="text-xl font-bold text-foreground mb-2">Ready to get connected?</h2>
      <p className="text-sm text-muted-foreground mb-5 max-w-sm mx-auto">
        Enter your address to see what&apos;s available at your location
      </p>
      {onCtaClick ? (
        <Button onClick={onCtaClick} size="lg" rightIcon={<ArrowRight className="h-4 w-4" />}>
          {ctaLabel}
        </Button>
      ) : (
        <Button as="a" href={ctaPath} size="lg" rightIcon={<ArrowRight className="h-4 w-4" />}>
          {ctaLabel}
        </Button>
      )}
    </section>
  );
}

export function PublicInternetPlansContent({
  onCtaClick,
  ctaPath: propCtaPath,
  ctaLabel = "Check Availability",
  heroTitle = "Internet for Expats in Japan",
  heroDescription = "Fast, reliable fiber internet with full English support. No Japanese required",
}: PublicInternetPlansContentProps) {
  const { data: servicesCatalog, error } = usePublicInternetCatalog();
  const isLoading = !servicesCatalog && !error;
  const servicesBasePath = useServicesBasePath();
  const ctaPath = propCtaPath ?? `${servicesBasePath}/internet/check-availability`;

  const consolidatedPlanData = useMemo(() => {
    if (!servicesCatalog?.plans) return null;
    return buildConsolidatedPlanData(servicesCatalog);
  }, [servicesCatalog]);

  const plansByOffering = useMemo(() => {
    return buildPlansByOffering(servicesCatalog?.plans ?? []);
  }, [servicesCatalog]);

  if (error) {
    return (
      <div className="space-y-6">
        <ServicesBackLink href={servicesBasePath} />
        <AlertBanner variant="error" title="Unable to load plans">
          We couldn&apos;t load internet plans. Please try again later.
        </AlertBanner>
      </div>
    );
  }

  let planCardContent: React.ReactNode = null;
  if (isLoading) {
    planCardContent = <Skeleton className="h-64 w-full rounded-xl" />;
  } else if (consolidatedPlanData) {
    planCardContent = (
      <UnifiedInternetCard
        consolidatedTiers={consolidatedPlanData.tiers}
        consolidatedMinPrice={consolidatedPlanData.minPrice}
        consolidatedMaxPrice={consolidatedPlanData.maxPrice}
        plansByOffering={plansByOffering}
        setupFee={consolidatedPlanData.setupFee}
        ctaPath={ctaPath}
        ctaLabel={ctaLabel}
        {...(onCtaClick && { onCtaClick })}
      />
    );
  }

  return (
    <div className="max-w-6xl mx-auto py-8 pb-16 space-y-12">
      <ServicesBackLink href={servicesBasePath} className="mb-0" />
      <ServicesHero title={heroTitle} description={heroDescription} />
      <ServiceHighlights features={INTERNET_FEATURES} />
      <section>{planCardContent}</section>
      <HowItWorksSection />
      <InternetFaqSection />
      <FinalCtaSection onCtaClick={onCtaClick} ctaPath={ctaPath} ctaLabel={ctaLabel} />
    </div>
  );
}

/**
 * Public Internet Plans page
 */
export function PublicInternetPlansView() {
  return <PublicInternetPlansContent />;
}

// ─── FAQ ──────────────────────────────────────────────────────────────────────

const INTERNET_FAQ_ITEMS = [
  {
    question: "How can I check if the 10Gbps service is available in my apartment or home?",
    answer:
      "Service availability depends on your address and building's network infrastructure. Please contact us (info@asolutions.co.jp) with your full address (including apartment name and room number) so we can confirm if our 10Gbps plans can be installed at your location.",
  },
  {
    question:
      "My home requires multiple Wi-Fi routers for full residence coverage. Would you be able to assist with this?",
    answer:
      "Our tech consulting team will be able to make suggestions based on your residence layout and requirements. Please contact us at info@asolutions.co.jp for a free consultation.",
  },
  {
    question:
      "We already have an Internet contract with a different company. Would it be possible to transfer our current service over to Assist Solutions?",
    answer:
      "Depending on the service that you are currently subscribed to, you may be able to transfer the service without cancelling. Please contact us at info@asolutions.co.jp for more information.",
  },
  {
    question: "What is the service contract period?",
    answer:
      "We offer our home Internet service on a monthly basis and thus, you will not be bound by yearly contracts. A designated cancellation form will need to be submitted by the 25th to close the account at the end of the month. For example, cancellation requests will need to be sent in by May 25th, in order to cancel at the end of May.",
  },
  {
    question: "How are invoices sent every month?",
    answer:
      "E-statements (available only in English) will be sent to your primary Email address. The service fee will be charged automatically to your registered credit card on file. For corporate plans, please contact us with your requests.",
  },
  {
    question: "My Internet is not working as expected. What should I do?",
    answer:
      "Our Chatbot will be able to assist you 24/7 with the initial diagnosis and offer troubleshooting tips based on your situation. You are also welcome to contact us at info@asolutions.co.jp for tech support (our business hours are 10AM-6PM/Mon-Sat). When contacting us, please be sure to let us know of the account holder's name and residence address so that we would be able to locate your account quicker.",
  },
];

function InternetFaqSection() {
  return (
    <section className="mt-12 mb-8">
      <h2 className="text-2xl font-bold text-foreground mb-6 text-center">
        Frequently Asked Questions
      </h2>
      <div className="space-y-4 max-w-3xl mx-auto">
        {INTERNET_FAQ_ITEMS.map((item, index) => (
          <FaqItem key={index} question={item.question} answer={item.answer} />
        ))}
      </div>
    </section>
  );
}

function FaqItem({ question, answer }: { question: string; answer: string }) {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div className="border border-border rounded-xl overflow-hidden bg-card">
      <button
        type="button"
        onClick={() => setIsOpen(!isOpen)}
        className="w-full flex items-start justify-between gap-3 p-4 text-left hover:bg-muted/50 transition-colors"
      >
        <span className="font-medium text-foreground">{question}</span>
        <motion.div animate={{ rotate: isOpen ? 180 : 0 }} transition={{ duration: 0.2 }}>
          <ChevronDown className="w-5 h-5 text-muted-foreground flex-shrink-0 mt-0.5" />
        </motion.div>
      </button>
      <AnimatePresence initial={false}>
        {isOpen && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: "auto", opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            transition={{ duration: 0.3, ease: "easeOut" }}
            style={{ overflow: "hidden" }}
          >
            <div className="px-4 pb-4 text-sm text-muted-foreground leading-relaxed">{answer}</div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
