import { useState, type ReactNode } from "react";
import {
  Alert,
  Avatar,
  Badge,
  Button,
  Card,
  Group,
  Stack,
  Text,
} from "@mantine/core";
import {
  BadgeCheck,
  Clock,
  Mail,
  MapPin,
  Phone,
  ShieldCheck,
  XCircle,
} from "lucide-react";

import {
  stashPendingVerification,
  verifaydaService,
  type IdentitySubject,
  type IdentityVerificationState,
} from "@/services/verifayda.service";
import { isBypassEnv } from "@/utils/dev-bypass";

/** Sentinel code that skips the real eSignet exchange in dev/staging (see api's DEV_BYPASS_FAYDA_CODE). */
const DEV_BYPASS_FAYDA_CODE = "DEV_BYPASS";

interface FaydaVerifyPanelProps {
  subject: IdentitySubject;
  /** Heading — "General Manager" / "Power of Attorney". */
  title: string;
  /** What this person's verification is currently known to be. */
  state?: IdentityVerificationState;
  /**
   * False for a foreign company: verification is offered but nothing is gated
   * on it, so the panel says so rather than nagging.
   */
  required: boolean;
  disabled?: boolean;
  /**
   * True when a fresh verification for this person is already staged in a
   * pending change request. On an active company a re-verification never
   * touches the live record — it's staged for review — so `state` alone
   * would keep showing the OLD verified data with no sign anything happened.
   */
  pendingReview?: boolean;
}

function getInitials(name: string | null): string {
  if (!name) return "?";
  const parts = name.trim().split(/\s+/);
  const first = parts[0]?.[0] ?? "";
  const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? "") : "";
  return (first + last).toUpperCase();
}

/**
 * Verify one of the company's people through Fayda and show what came back.
 *
 * The identity is proved on eSignet, which the whole tab navigates to — no
 * popup, because a popup opened after the /start round-trip has lost its user
 * activation and iOS Safari blocks it outright. eSignet redirects back to
 * /fayda/callback, which completes the exchange and returns the user here; the API
 * writes the person's name, phone, email and address from the verified
 * payload. Nothing on this panel is typed.
 */
export default function FaydaVerifyPanel({
  subject,
  title,
  state,
  required,
  disabled,
  pendingReview,
}: FaydaVerifyPanelProps) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const startVerification = async () => {
    setError(null);
    setLoading(true);
    try {
      // Dev/staging only: send the tab straight to /fayda/callback with the
      // sentinel code instead of round-tripping through eSignet — that page's
      // existing completeIdentity()/navigate-back logic runs unchanged.
      if (isBypassEnv()) {
        stashPendingVerification({
          subject,
          returnTo:
            window.location.pathname +
            window.location.search +
            window.location.hash,
        });
        window.location.assign(
          `/fayda/callback?code=${DEV_BYPASS_FAYDA_CODE}&state=bypass`,
        );
        return;
      }

      const authorizationUrl = await verifaydaService.start();
      // Record who is being verified and where to come back to before the tab
      // leaves — /fayda/callback has no other way to know either.
      stashPendingVerification({
        subject,
        returnTo:
          window.location.pathname +
          window.location.search +
          window.location.hash,
      });
      window.location.assign(authorizationUrl);
    } catch (err) {
      setLoading(false);
      setError(
        (err as { response?: { data?: { message?: string } } })?.response?.data
          ?.message ??
        (err instanceof Error ? err.message : "Could not start verification"),
      );
    }
  };

  const verified = state?.verified ?? false;

  return (
    <Card padding="md" radius="md" withBorder>
      <Group justify="space-between" align="center" mb={verified ? "md" : "xs"}>
        <Group gap="sm">
          <ShieldCheck size={18} />
          <Text fw={600} c="edr-text">
            {title}
          </Text>
          {verified ? (
            <Badge
              size="sm"
              variant="light"
              color="green"
              leftSection={<BadgeCheck size={11} />}
            >
              Fayda verified
            </Badge>
          ) : (
            required && (
              <Badge size="sm" variant="light" color="amber">
                Verification required
              </Badge>
            )
          )}
          {pendingReview && (
            <Badge
              size="sm"
              variant="light"
              color="amber"
              leftSection={<Clock size={11} />}
            >
              Re-verification pending review
            </Badge>
          )}
        </Group>
        <Button
          type="button"
          variant="light"
          size="xs"
          loading={loading}
          disabled={disabled}
          onClick={startVerification}
        >
          {verified ? "Re-verify with Fayda" : "Verify with Fayda"}
        </Button>
      </Group>

      {!verified && (
        <Text c="edr-muted" size="xs">
          {required
            ? "Verify this person with Fayda. Their name, phone and address come from the verification — there is nothing to fill in by hand."
            : "Optional for a foreign company. If this person holds a Fayda ID, verifying it fills in their details."}
        </Text>
      )}

      {verified && state && (
        <Group align="flex-start" gap="sm" wrap="nowrap">
          <Avatar radius="xl" size={44} color="edr-green" variant="light">
            {getInitials(state.name)}
          </Avatar>
          <Stack gap={4} style={{ minWidth: 0, flex: 1 }}>
            <Text fw={600} size="sm" c="edr-text" truncate>
              {state.name}
            </Text>
            <Group gap="md" wrap="wrap">
              <DataRow icon={<Phone size={13} />} value={state.phone} />
              <DataRow icon={<Mail size={13} />} value={state.email} />
            </Group>
            <DataRow icon={<MapPin size={13} />} value={state.address} />
          </Stack>
        </Group>
      )}

      {error && (
        <Alert mt="sm" color="red" variant="light" icon={<XCircle size={18} />}>
          {error}
        </Alert>
      )}
    </Card>
  );
}

function DataRow({ icon, value }: { icon: ReactNode; value: string | null }) {
  if (!value) return null;
  return (
    <Group gap={6} wrap="nowrap">
      <span
        style={{
          color: "var(--mantine-color-edr-muted-6)",
          display: "flex",
          flexShrink: 0,
        }}
      >
        {icon}
      </span>
      <Text size="xs" c="edr-muted" truncate>
        {value}
      </Text>
    </Group>
  );
}
