"use client";

import React, { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import {
  ExclamationTriangleIcon,
  ArrowPathIcon,
  PhoneIcon,
  ArrowsRightLeftIcon,
  ArrowPathRoundedSquareIcon,
  XCircleIcon,
} from "@heroicons/react/24/outline";
import { apiClient } from "@/core/api";
import { useSubscription } from "@/features/subscriptions/hooks";
import { Formatting } from "@customer-portal/domain/toolkit";
import { Button } from "@/components/atoms/button";
import { formatIsoDate } from "@/shared/utils";

const { formatCurrency } = Formatting;

interface SimManagementSectionProps {
  subscriptionId: number;
}

interface SimDetails {
  account: string;
  msisdn: string;
  iccid?: string;
  imsi?: string;
  eid?: string;
  planCode: string;
  status: "active" | "suspended" | "cancelled" | "pending";
  simType: "physical" | "esim" | "standard" | "nano" | "micro";
  remainingQuotaMb: number;
  remainingQuotaKb: number;
  voiceMailEnabled?: boolean;
  callWaitingEnabled?: boolean;
  internationalRoamingEnabled?: boolean;
  networkType?: string;
  hasVoice?: boolean;
  hasSms?: boolean;
}

interface SimInfo {
  details: SimDetails;
  usage?: {
    todayUsageMb: number;
    monthlyUsageMb?: number;
    recentDaysUsage?: Array<{ date: string; usageMb: number }>;
  };
}

export function SimManagementSection({ subscriptionId }: SimManagementSectionProps) {
  const router = useRouter();
  const [simInfo, setSimInfo] = useState<SimInfo | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Voice feature states
  const [featureLoading, setFeatureLoading] = useState<{
    voiceMail?: boolean;
    callWaiting?: boolean;
    internationalRoaming?: boolean;
    networkType?: boolean;
  }>({});
  const [featureError, setFeatureError] = useState<string | null>(null);

  // Navigation handlers
  const navigateToTopUp = () => router.push(`/account/subscriptions/${subscriptionId}/sim/top-up`);
  const navigateToChangePlan = () =>
    router.push(`/account/subscriptions/${subscriptionId}/sim/change-plan`);
  const navigateToReissue = () =>
    router.push(`/account/subscriptions/${subscriptionId}/sim/reissue`);
  const navigateToCancel = () => router.push(`/account/subscriptions/${subscriptionId}/cancel`);
  const navigateToCallHistory = () =>
    router.push(`/account/subscriptions/${subscriptionId}/sim/call-history`);

  // Fetch subscription data
  const { data: subscription } = useSubscription(subscriptionId);

  // SSO link mutation for payment
  const fetchSimInfo = useCallback(async () => {
    try {
      setError(null);

      const response = await apiClient.GET("/api/subscriptions/{id}/sim", {
        params: { path: { id: subscriptionId } },
      });

      const payload = response.data as
        | { details: SimDetails; usage?: SimInfo["usage"] }
        | undefined;

      if (!payload) {
        throw new Error("Failed to load SIM information");
      }

      setSimInfo({
        details: payload.details,
        usage: payload.usage ?? { todayUsageMb: 0 },
      });
    } catch (err: unknown) {
      const hasStatus = (v: unknown): v is { status: number } =>
        typeof v === "object" &&
        v !== null &&
        "status" in v &&
        typeof (v as { status: unknown }).status === "number";
      if (hasStatus(err) && err.status === 400) {
        setError("This subscription is not a SIM service");
      } else {
        setError(
          process.env.NODE_ENV === "development"
            ? err instanceof Error
              ? err.message
              : "Failed to load SIM information"
            : "Unable to load SIM information right now. Please try again."
        );
      }
    } finally {
      setLoading(false);
    }
  }, [subscriptionId]);

  useEffect(() => {
    void fetchSimInfo();
  }, [fetchSimInfo]);

  // Update a single voice feature
  const updateFeature = useCallback(
    async (
      featureKey: "voiceMail" | "callWaiting" | "internationalRoaming" | "networkType",
      value: boolean | "4G" | "5G"
    ) => {
      setFeatureLoading(prev => ({ ...prev, [featureKey]: true }));
      setFeatureError(null);

      try {
        const body: {
          voiceMailEnabled?: boolean;
          callWaitingEnabled?: boolean;
          internationalRoamingEnabled?: boolean;
          networkType?: "4G" | "5G";
        } = {};

        switch (featureKey) {
          case "voiceMail":
            body.voiceMailEnabled = value as boolean;
            break;
          case "callWaiting":
            body.callWaitingEnabled = value as boolean;
            break;
          case "internationalRoaming":
            body.internationalRoamingEnabled = value as boolean;
            break;
          case "networkType":
            body.networkType = value as "4G" | "5G";
            break;
        }

        await apiClient.POST("/api/subscriptions/{id}/sim/features", {
          params: { path: { id: subscriptionId } },
          body,
        });

        // Update local state optimistically
        setSimInfo(prev => {
          if (!prev) return prev;
          const updated = { ...prev, details: { ...prev.details } };
          switch (featureKey) {
            case "voiceMail":
              updated.details.voiceMailEnabled = value as boolean;
              break;
            case "callWaiting":
              updated.details.callWaitingEnabled = value as boolean;
              break;
            case "internationalRoaming":
              updated.details.internationalRoamingEnabled = value as boolean;
              break;
            case "networkType":
              updated.details.networkType = value as string;
              break;
          }
          return updated;
        });
      } catch (err: unknown) {
        let errorMessage = "Failed to update feature. Please try again.";

        if (err instanceof Error) {
          const msg = err.message.toLowerCase();
          // Check for rate limiting errors
          if (msg.includes("30 minutes") || msg.includes("must be requested")) {
            errorMessage =
              "Please wait 30 minutes between voice/network/plan changes before trying again.";
          } else if (msg.includes("another") && msg.includes("in progress")) {
            errorMessage = "Another operation is in progress. Please wait a moment.";
          } else {
            errorMessage = err.message;
          }
        }

        setFeatureError(errorMessage);
        // Revert by refetching
        void fetchSimInfo();
      } finally {
        setFeatureLoading(prev => ({ ...prev, [featureKey]: false }));
      }
    },
    [subscriptionId, fetchSimInfo]
  );

  const handleRefresh = () => {
    setLoading(true);
    void fetchSimInfo();
  };

  const formatDate = (dateString: string | undefined) => formatIsoDate(dateString);

  if (loading) {
    return (
      <div className="space-y-6">
        <div className="bg-card shadow-[var(--cp-shadow-1)] rounded-lg border border-border p-8">
          <div className="animate-pulse space-y-6">
            <div className="h-6 bg-muted rounded-lg w-3/4" />
            <div className="h-48 bg-muted rounded-xl" />
          </div>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="bg-card shadow-[var(--cp-shadow-1)] rounded-lg border border-border p-8">
        <div className="text-center py-10 max-w-xl mx-auto">
          <div className="w-20 h-20 mx-auto mb-6 rounded-full bg-danger-soft flex items-center justify-center border border-danger/25">
            <ExclamationTriangleIcon className="h-10 w-10 text-danger" />
          </div>
          <h3 className="text-xl font-semibold text-foreground mb-3">
            Unable to Load SIM Information
          </h3>
          <p className="text-muted-foreground mb-6">{error}</p>
          <Button onClick={handleRefresh} leftIcon={<ArrowPathIcon className="h-5 w-5" />}>
            Retry
          </Button>
        </div>
      </div>
    );
  }

  if (!simInfo) {
    return null;
  }

  const remainingMB = simInfo.details.remainingQuotaMb.toFixed(1);
  const usedMB = simInfo.usage?.monthlyUsageMb
    ? simInfo.usage.monthlyUsageMb.toFixed(2)
    : simInfo.usage?.todayUsageMb
      ? simInfo.usage.todayUsageMb.toFixed(2)
      : "0.00";

  // Calculate percentage for circle
  const totalMB = Number.parseFloat(remainingMB) + Number.parseFloat(usedMB);
  const usagePercentage = totalMB > 0 ? (Number.parseFloat(usedMB) / totalMB) * 100 : 0;
  const circumference = 2 * Math.PI * 96;
  const strokeDashoffset = circumference - (usagePercentage / 100) * circumference;

  return (
    <div id="sim-management" className="space-y-4">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <p className="text-xs uppercase tracking-wide text-muted-foreground">SIM Management</p>
          <h2 className="text-xl font-semibold text-foreground">
            {simInfo.details.msisdn || "SIM Summary"}
          </h2>
        </div>
        <Button onClick={navigateToTopUp} className="sm:w-auto w-full">
          Top Up Data
        </Button>
      </div>

      <div className="grid grid-cols-1 gap-6 md:grid-cols-[1.85fr_1fr]">
        {/* Left Column */}
        <div className="order-2 md:order-1 bg-card border border-border rounded-2xl shadow-[var(--cp-shadow-1)] p-6 space-y-6">
          {/* Actions grid */}
          <div className="grid grid-cols-2 gap-4">
            <ActionTile
              label="Call History"
              icon={<PhoneIcon className="h-7 w-7 text-muted-foreground" />}
              onClick={navigateToCallHistory}
            />
            <ActionTile
              label="Change Plan"
              icon={<ArrowsRightLeftIcon className="h-7 w-7 text-muted-foreground" />}
              onClick={navigateToChangePlan}
            />
            <ActionTile
              label="Reissue SIM"
              icon={<ArrowPathRoundedSquareIcon className="h-7 w-7 text-muted-foreground" />}
              onClick={navigateToReissue}
            />
            <ActionTile
              label="Cancel SIM"
              intent="danger"
              icon={<XCircleIcon className="h-7 w-7 text-danger" />}
              onClick={navigateToCancel}
            />
          </div>

          {/* Voice & Network toggles */}
          <div className="space-y-3">
            <h4 className="text-md font-semibold text-foreground">
              {simInfo.details.hasVoice === false ? "Network Status" : "Voice Status"}
            </h4>
            {featureError && (
              <div className="p-3 bg-danger-soft border border-danger/25 rounded-lg text-sm text-danger">
                {featureError}
              </div>
            )}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              {simInfo.details.hasVoice !== false && (
                <StatusToggle
                  label="Voice Mail"
                  subtitle={simInfo.details.voiceMailEnabled ? "Enabled" : "Disabled"}
                  checked={simInfo.details.voiceMailEnabled || false}
                  loading={featureLoading.voiceMail ?? false}
                  onChange={checked => void updateFeature("voiceMail", checked)}
                />
              )}
              <StatusToggle
                label="Network Type"
                subtitle={simInfo.details.networkType === "5G" ? "5G" : "4G"}
                checked={simInfo.details.networkType === "5G"}
                loading={featureLoading.networkType ?? false}
                onChange={checked => void updateFeature("networkType", checked ? "5G" : "4G")}
              />
              {simInfo.details.hasVoice !== false && (
                <StatusToggle
                  label="Call Waiting"
                  subtitle={simInfo.details.callWaitingEnabled ? "Enabled" : "Disabled"}
                  checked={simInfo.details.callWaitingEnabled || false}
                  loading={featureLoading.callWaiting ?? false}
                  onChange={checked => void updateFeature("callWaiting", checked)}
                />
              )}
              {simInfo.details.hasVoice !== false && (
                <StatusToggle
                  label="International Roaming"
                  subtitle={simInfo.details.internationalRoamingEnabled ? "Enabled" : "Disabled"}
                  checked={simInfo.details.internationalRoamingEnabled || false}
                  loading={featureLoading.internationalRoaming ?? false}
                  onChange={checked => void updateFeature("internationalRoaming", checked)}
                />
              )}
            </div>
            {simInfo.details.hasVoice === false && (
              <p className="text-xs text-muted-foreground">
                Voice features are not available on data-only plans.
              </p>
            )}
          </div>
        </div>

        {/* Right Column */}
        <div className="order-1 md:order-2 bg-card border border-border rounded-2xl shadow-[var(--cp-shadow-1)] p-6 space-y-6">
          <div className="flex items-center justify-center">
            <div className="relative w-56 h-56">
              <div className="absolute inset-4 rounded-full bg-muted/40" />
              <svg className="w-full h-full transform -rotate-90 text-border">
                <circle
                  cx="112"
                  cy="112"
                  r="96"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="12"
                />
                <circle
                  cx="112"
                  cy="112"
                  r="96"
                  fill="none"
                  stroke="currentColor"
                  className="text-primary transition-all duration-500"
                  strokeWidth="12"
                  strokeLinecap="round"
                  strokeDasharray={circumference}
                  strokeDashoffset={strokeDashoffset}
                />
              </svg>
              <div className="absolute inset-0 flex flex-col items-center justify-center text-center space-y-1">
                <p className="text-xs text-muted-foreground">Remaining Data</p>
                <p className="text-4xl font-bold text-foreground">{remainingMB} MB</p>
                <p className="text-xs text-muted-foreground">Used: {usedMB} MB</p>
              </div>
            </div>
          </div>

          <div className="space-y-1 text-sm">
            <div className="flex items-center justify-between rounded-lg border border-border bg-muted/40 px-3 py-2">
              <span className="text-muted-foreground">Monthly Cost</span>
              <span className="font-semibold text-foreground">
                {subscription ? formatCurrency(subscription.amount) : "—"}
              </span>
            </div>
            <div className="flex items-center justify-between rounded-lg border border-border bg-muted/40 px-3 py-2">
              <span className="text-muted-foreground">Next Bill on</span>
              <span className="font-semibold text-foreground">
                {subscription?.nextDue ? formatDate(subscription.nextDue) : "—"}
              </span>
            </div>
            <div className="flex items-center justify-between rounded-lg border border-border bg-muted/40 px-3 py-2">
              <span className="text-muted-foreground">Registered</span>
              <span className="font-semibold text-foreground">
                {subscription?.registrationDate ? formatDate(subscription.registrationDate) : "—"}
              </span>
            </div>
          </div>

          <div className="rounded-xl border border-border bg-muted/50 p-4">
            <h4 className="text-md font-semibold text-foreground mb-3">Important Notes</h4>
            <ul className="space-y-2 text-sm text-muted-foreground">
              <li className="flex items-start">
                <span className="mr-2">•</span>
                <span>Changes will take effect instantaneously (approx. 30min)</span>
              </li>
              <li className="flex items-start">
                <span className="mr-2">•</span>
                <span>May require smartphone device restart after changes are applied</span>
              </li>
              <li className="flex items-start">
                <span className="mr-2">•</span>
                <span>
                  Voice, network, and plan changes must be requested at least 30 minutes apart.
                </span>
              </li>
              <li className="flex items-start">
                <span className="mr-2">•</span>
                <span>
                  Changes to Voice Mail / Call Waiting must be requested before the 25th of the
                  month
                </span>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  );
}

type ActionTileProps = {
  label: string;
  icon: React.ReactNode;
  onClick: () => void;
  intent?: "default" | "danger";
};

function ActionTile({ label, icon, onClick, intent = "default" }: ActionTileProps) {
  const isDanger = intent === "danger";
  return (
    <button
      onClick={onClick}
      className={`flex flex-col gap-2 items-center justify-center rounded-xl border transition-all duration-200 p-5 text-center ${
        isDanger
          ? "border-danger/25 bg-danger-soft/40 hover:bg-danger-soft hover:shadow-[var(--cp-shadow-2)]"
          : "border-border bg-muted/40 hover:bg-background hover:shadow-[var(--cp-shadow-2)]"
      }`}
    >
      <div className="flex items-center justify-center h-10 w-10 rounded-full bg-background">
        {icon}
      </div>
      <span className={`text-sm font-medium ${isDanger ? "text-danger" : "text-foreground"}`}>
        {label}
      </span>
    </button>
  );
}

type StatusToggleProps = {
  label: string;
  subtitle?: string;
  checked: boolean;
  onChange?: (checked: boolean) => void;
  loading?: boolean;
  disabled?: boolean;
};

function StatusToggle({
  label,
  subtitle,
  checked,
  onChange,
  loading,
  disabled,
}: StatusToggleProps) {
  const isDisabled = disabled || loading;

  const handleClick = () => {
    if (!isDisabled && onChange) {
      onChange(!checked);
    }
  };

  return (
    <div
      className={`p-4 bg-card border border-border rounded-lg ${isDisabled ? "opacity-60" : ""}`}
    >
      <div className="flex items-center justify-between">
        <div>
          <p className="font-medium text-foreground">{label}</p>
          {subtitle && <p className="text-xs text-muted-foreground mt-0.5">{subtitle}</p>}
        </div>
        <label
          className={`relative inline-flex items-center ${isDisabled ? "cursor-not-allowed" : "cursor-pointer"}`}
        >
          <input
            type="checkbox"
            checked={checked}
            onChange={handleClick}
            disabled={isDisabled}
            className="sr-only peer"
          />
          <div
            className={`w-11 h-6 bg-muted peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-ring/20 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-background after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-background after:border-border after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary ${loading ? "animate-pulse" : ""}`}
          ></div>
        </label>
      </div>
    </div>
  );
}
