"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { useParams } from "next/navigation";
import { PageLayout } from "@/components/templates/PageLayout";
import { SubCard } from "@/components/molecules/SubCard/SubCard";
import { DevicePhoneMobileIcon, CheckCircleIcon } from "@heroicons/react/24/outline";
import { simActionsService } from "@/features/subscriptions/api/sim-actions.api";
import type { SimAvailablePlan } from "@customer-portal/domain/sim";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
import { Formatting } from "@customer-portal/domain/toolkit";
import { Button } from "@/components/atoms";
import { devErrorMessage } from "@/shared/utils";

const { formatCurrency } = Formatting;

function CurrentPlanCard({ plan }: { plan: SimAvailablePlan }) {
  return (
    <div className="bg-info-soft border border-info/25 rounded-lg p-4 mb-6">
      <div className="flex items-center justify-between">
        <div>
          <div className="text-xs text-info font-medium uppercase">Current Plan</div>
          <div className="text-lg font-semibold text-foreground">{plan.name}</div>
          <div className="text-sm text-muted-foreground">{plan.simDataSize}</div>
        </div>
        <div className="text-right">
          <div className="text-xl font-bold text-foreground">
            {plan.monthlyPrice ? formatCurrency(plan.monthlyPrice) : "—"}
          </div>
          <div className="text-xs text-muted-foreground">/month</div>
        </div>
      </div>
    </div>
  );
}

function PlanOption({
  plan,
  isSelected,
  onSelect,
}: {
  plan: SimAvailablePlan;
  isSelected: boolean;
  onSelect: () => void;
}) {
  return (
    <label
      className={`relative flex items-center justify-between p-4 border rounded-lg cursor-pointer transition-colors ${
        isSelected ? "border-primary bg-primary-soft" : "border-border hover:bg-muted bg-card"
      }`}
    >
      <div className="flex items-center">
        <input
          type="radio"
          name="plan"
          value={plan.id}
          checked={isSelected}
          onChange={onSelect}
          className="sr-only"
        />
        <div
          className={`w-5 h-5 rounded-full border-2 mr-4 flex items-center justify-center ${
            isSelected ? "border-primary" : "border-border"
          }`}
        >
          {isSelected && <div className="w-3 h-3 rounded-full bg-primary"></div>}
        </div>
        <div>
          <div className="font-medium text-foreground">{plan.name}</div>
          <div className="text-sm text-muted-foreground">
            {plan.simDataSize} • {plan.simPlanType}
          </div>
        </div>
      </div>
      <div className="text-right">
        <div className="text-lg font-semibold text-foreground">
          {plan.monthlyPrice ? formatCurrency(plan.monthlyPrice) : "—"}
        </div>
        <div className="text-xs text-muted-foreground">/month</div>
      </div>
      {isSelected && <CheckCircleIcon className="absolute top-2 right-2 h-5 w-5 text-primary" />}
    </label>
  );
}

function ChangePlanForm({
  plans,
  currentPlan,
  selectedPlan,
  onSelectPlan,
  loading,
  subscriptionId,
  onSubmit,
}: {
  plans: SimAvailablePlan[];
  currentPlan: SimAvailablePlan | undefined;
  selectedPlan: SimAvailablePlan | null;
  onSelectPlan: (plan: SimAvailablePlan) => void;
  loading: boolean;
  subscriptionId: string;
  onSubmit: (e: React.FormEvent) => void;
}) {
  return (
    <form onSubmit={onSubmit} className="space-y-6">
      {currentPlan && <CurrentPlanCard plan={currentPlan} />}

      <div className="space-y-3">
        <label className="block text-sm font-medium text-muted-foreground">Select a New Plan</label>
        <div className="grid gap-3">
          {plans
            .filter(p => !p.isCurrentPlan)
            .map(plan => (
              <PlanOption
                key={plan.id}
                plan={plan}
                isSelected={selectedPlan?.id === plan.id}
                onSelect={() => onSelectPlan(plan)}
              />
            ))}
        </div>
      </div>

      <div className="bg-warning-soft border border-warning/25 rounded-lg p-4">
        <h3 className="text-sm font-medium text-foreground mb-1">Important Notes</h3>
        <ul className="text-sm text-muted-foreground space-y-1">
          {process.env.NODE_ENV === "development" ? (
            <>
              <li>• Test mode: plan changes are submitted for immediate processing</li>
              <li>• Changes may take a few hours to appear on the Freebit dashboard</li>
            </>
          ) : (
            <>
              <li>• Plan changes take effect on the 1st of the following month</li>
              <li>• Requests must be made before the 25th of the current month</li>
            </>
          )}
          <li>• Your current data balance will be reset when the new plan activates</li>
        </ul>
      </div>

      <div className="flex gap-3">
        <Button
          type="submit"
          disabled={loading || !selectedPlan}
          loading={loading}
          loadingText="Processing…"
        >
          Confirm Plan Change
        </Button>
        <Button
          as="a"
          href={`/account/subscriptions/${subscriptionId}#sim-management`}
          variant="outline"
        >
          Cancel
        </Button>
      </div>
    </form>
  );
}

function useChangePlanState(subscriptionId: string) {
  const [plans, setPlans] = useState<SimAvailablePlan[]>([]);
  const [selectedPlan, setSelectedPlan] = useState<SimAvailablePlan | null>(null);
  const [message, setMessage] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [loadingPlans, setLoadingPlans] = useState(true);

  useEffect(() => {
    const fetchPlans = async () => {
      try {
        setPlans(await simActionsService.getAvailablePlans(subscriptionId));
      } catch (e: unknown) {
        setError(
          devErrorMessage(
            e,
            "Failed to load available plans",
            "Unable to load available plans right now. Please try again."
          )
        );
      } finally {
        setLoadingPlans(false);
      }
    };
    void fetchPlans();
  }, [subscriptionId]);

  const submit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!selectedPlan) {
      setError("Please select a new plan");
      return;
    }
    setLoading(true);
    setMessage(null);
    setError(null);
    try {
      const result = await simActionsService.changePlanFull(subscriptionId, {
        newPlanCode: selectedPlan.freebitPlanCode,
        newPlanSku: selectedPlan.sku,
        newPlanName: selectedPlan.name,
      });
      const scheduled = result.scheduledAt;
      const today = new Date();
      const todayStr = `${today.getFullYear()}${String(today.getMonth() + 1).padStart(2, "0")}${String(today.getDate()).padStart(2, "0")}`;
      setMessage(
        scheduled === todayStr
          ? `Plan change submitted for immediate processing (${selectedPlan.name})`
          : `Plan change scheduled for ${scheduled || "the 1st of next month"}`
      );
      setSelectedPlan(null);
    } catch (e: unknown) {
      setError(
        devErrorMessage(
          e,
          "Failed to change plan",
          "Unable to submit your plan change right now. Please try again."
        )
      );
    } finally {
      setLoading(false);
    }
  };

  return { plans, selectedPlan, setSelectedPlan, message, error, loading, loadingPlans, submit };
}

export function SimChangePlanContainer() {
  const params = useParams();
  const subscriptionId = params["id"] as string;
  const { plans, selectedPlan, setSelectedPlan, message, error, loading, loadingPlans, submit } =
    useChangePlanState(subscriptionId);
  const currentPlan = plans.find(p => p.isCurrentPlan);

  return (
    <PageLayout
      icon={<DevicePhoneMobileIcon />}
      title="Change Plan"
      backLink={{ label: "Back to Subscription", href: `/account/subscriptions/${subscriptionId}` }}
    >
      <div className="max-w-4xl mx-auto">
        <div className="mb-4">
          <Link
            href={`/account/subscriptions/${subscriptionId}#sim-management`}
            className="text-primary hover:underline"
          >
            ← Back to SIM Management
          </Link>
        </div>

        <SubCard>
          <div className="mb-6">
            <h2 className="text-lg font-semibold text-foreground mb-2">Change Your Plan</h2>
            <p className="text-sm text-muted-foreground">
              {process.env.NODE_ENV === "development"
                ? "Select a new plan below. In test mode, plan changes are submitted for immediate processing."
                : "Select a new plan below. Plan changes will take effect on the 1st of the following month. Changes must be requested before the 25th of the current month."}
            </p>
          </div>

          {message && (
            <div className="mb-4">
              <AlertBanner variant="success" title="Plan Change Submitted">
                {message}
              </AlertBanner>
            </div>
          )}
          {error && (
            <div className="mb-4">
              <AlertBanner variant="error" title="Plan Change Failed">
                {error}
              </AlertBanner>
            </div>
          )}

          {loadingPlans ? (
            <div className="animate-pulse space-y-4">
              {[1, 2, 3, 4].map(i => (
                <div key={i} className="h-24 bg-muted rounded-lg"></div>
              ))}
            </div>
          ) : (
            <ChangePlanForm
              plans={plans}
              currentPlan={currentPlan}
              selectedPlan={selectedPlan}
              onSelectPlan={setSelectedPlan}
              loading={loading}
              subscriptionId={subscriptionId}
              onSubmit={e => void submit(e)}
            />
          )}
        </SubCard>
      </div>
    </PageLayout>
  );
}

export default SimChangePlanContainer;
