import React, {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState
} from "react";
import PermitExpiryWarningModal from "../components/common/PermitExpiryWarningModal.jsx";

const STORAGE_KEY = "ptw_active_permit";
const WARN_DISMISS_PREFIX = "ptw_expiry_warn_";
const WARNING_LEAD_MS = 30 * 60 * 1000;

const PermitValidityContext = createContext(null);

function readStoredPermit() {
  try {
    const raw = sessionStorage.getItem(STORAGE_KEY);
    if (!raw) return null;
    const parsed = JSON.parse(raw);
    if (!parsed?.permitId || !parsed?.validUntil) return null;
    return parsed;
  } catch {
    return null;
  }
}

function writeStoredPermit(permit) {
  if (!permit) {
    sessionStorage.removeItem(STORAGE_KEY);
    return;
  }
  sessionStorage.setItem(STORAGE_KEY, JSON.stringify(permit));
}

function isPermitActive(permit) {
  if (!permit?.validUntil) return false;
  return new Date(permit.validUntil).getTime() > Date.now();
}

export function PermitValidityProvider({ children, onNavigate }) {
  const [activePermit, setActivePermitState] = useState(() => readStoredPermit());
  const [workflowView, setWorkflowView] = useState(null);
  const [warningOpen, setWarningOpen] = useState(false);
  const timerRef = useRef(null);

  const setActivePermit = useCallback((permit) => {
    const next = permit
      ? {
          permitId: Number(permit.permitId),
          permitNumber: permit.permitNumber || "",
          validFrom: permit.validFrom,
          validUntil: permit.validUntil
        }
      : null;
    setActivePermitState(next);
    writeStoredPermit(next);
  }, []);

  const clearActivePermit = useCallback(() => {
    setActivePermit(null);
    setWarningOpen(false);
  }, [setActivePermit]);

  const navigateToHandover = useCallback((permitId) => {
    const pid = Number(permitId ?? activePermit?.permitId);
    if (!Number.isFinite(pid) || pid <= 0) return;
    sessionStorage.setItem("ptw_lifecycle_permit_id", String(pid));
    setWorkflowView({ type: "handover", permitId: pid });
    setWarningOpen(false);
    onNavigate?.("permit-handover");
  }, [activePermit?.permitId, onNavigate]);

  const navigateToHandback = useCallback((permitId) => {
    const pid = Number(permitId ?? activePermit?.permitId);
    if (!Number.isFinite(pid) || pid <= 0) return;
    sessionStorage.setItem("ptw_lifecycle_permit_id", String(pid));
    setWorkflowView({ type: "handback", permitId: pid });
    setWarningOpen(false);
    onNavigate?.("permit-handback");
  }, [activePermit?.permitId, onNavigate]);

  const navigateToAudit = useCallback((permitId) => {
    const pid = Number(permitId ?? activePermit?.permitId);
    if (!Number.isFinite(pid) || pid <= 0) return;
    sessionStorage.setItem("ptw_lifecycle_permit_id", String(pid));
    setWorkflowView({ type: "audit", permitId: pid });
    setWarningOpen(false);
    onNavigate?.("permit-audit");
  }, [activePermit?.permitId, onNavigate]);

  const clearWorkflowView = useCallback(() => {
    setWorkflowView(null);
  }, []);

  const dismissWarning = useCallback(() => {
    if (activePermit?.permitId) {
      sessionStorage.setItem(`${WARN_DISMISS_PREFIX}${activePermit.permitId}`, "1");
    }
    setWarningOpen(false);
  }, [activePermit?.permitId]);

  useEffect(() => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
      timerRef.current = null;
    }

    if (!activePermit?.validUntil || !isPermitActive(activePermit)) {
      if (activePermit && !isPermitActive(activePermit)) {
        setActivePermit(null);
      }
      return undefined;
    }

    const permitId = activePermit.permitId;
    const dismissed = sessionStorage.getItem(`${WARN_DISMISS_PREFIX}${permitId}`) === "1";
    const validUntilMs = new Date(activePermit.validUntil).getTime();
    const warnAtMs = validUntilMs - WARNING_LEAD_MS;
    const now = Date.now();

    const showWarning = () => {
      if (sessionStorage.getItem(`${WARN_DISMISS_PREFIX}${permitId}`) === "1") return;
      if (Date.now() < validUntilMs) {
        setWarningOpen(true);
      }
    };

    if (!dismissed) {
      if (now >= warnAtMs && now < validUntilMs) {
        showWarning();
      } else if (now < warnAtMs) {
        timerRef.current = setTimeout(showWarning, warnAtMs - now);
      }
    }

    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current);
        timerRef.current = null;
      }
    };
  }, [activePermit, setActivePermit]);

  const value = useMemo(
    () => ({
      activePermit: isPermitActive(activePermit) ? activePermit : null,
      setActivePermit,
      clearActivePermit,
      navigateToHandover,
      navigateToHandback,
      navigateToAudit,
      workflowView,
      clearWorkflowView
    }),
    [
      activePermit,
      setActivePermit,
      clearActivePermit,
      navigateToHandover,
      navigateToHandback,
      navigateToAudit,
      workflowView,
      clearWorkflowView
    ]
  );

  return (
    <PermitValidityContext.Provider value={value}>
      {children}
      <PermitExpiryWarningModal
        open={warningOpen}
        permit={activePermit}
        onDismiss={dismissWarning}
        onHandover={() => navigateToHandover()}
        onHandback={() => navigateToHandback()}
      />
    </PermitValidityContext.Provider>
  );
}

export function usePermitValidity() {
  const ctx = useContext(PermitValidityContext);
  if (!ctx) {
    throw new Error("usePermitValidity must be used within PermitValidityProvider");
  }
  return ctx;
}

export function formatPermitValidity(iso) {
  if (!iso) return "—";
  const d = new Date(iso);
  return Number.isNaN(d.getTime()) ? String(iso) : d.toLocaleString();
}
