"use client";

import { useState, useEffect } from "react";
import { getUserDataCookie, setUserDataCookie, logout } from "@/lib/cookies";
import { usePathname, useRouter } from "@/i18n/navigation";
import DashboardHeaderWrapper from "@/components/practitioner/DashboardHeaderWrapper";
import EditProfileModal from "@/components/practitioner/modals/EditProfileModal";
import ChangePasswordModal from "@/components/practitioner/modals/ChangePasswordModal";
import SupportModal from "@/components/practitioner/modals/SupportModal";
import { useLoginControllerLogoutV1 } from "@/api/user/user-authentication/user-authentication";
import { useSubscriptionControllerGetBillingHistoryV1, useSubscriptionControllerGetSubscriptionStatusV1 } from "@/api/user/practitioner-subscription/practitioner-subscription";

export default function PractitionerLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const pathname = usePathname();
  const router = useRouter();
  const [editProfileOpen, setEditProfileOpen] = useState(false);
  const [changePasswordOpen, setChangePasswordOpen] = useState(false);
  const [supportOpen, setSupportOpen] = useState(false);
  const [isForceChange, setIsForceChange] = useState(false);

  // Client-side auth guard: redirect to login if no session
  useEffect(() => {
    const data = getUserDataCookie();
    if (!data) {
      router.replace('/login');
    }
  }, [router]);

  // Check subscription status from cookie (set at login)
  const [userData, setUserData] = useState<ReturnType<typeof getUserDataCookie>>(null);
  useEffect(() => {
    const data = getUserDataCookie();
    setUserData(data);
    // Auto-open change password modal for invited practitioners
    if (data?.force_password_change) {
      setChangePasswordOpen(true);
      setIsForceChange(true);
    }
  }, []);


  // Re-check force password change on every navigation
  useEffect(() => {
    const data = getUserDataCookie();
    if (data?.force_password_change && !changePasswordOpen) {
      setChangePasswordOpen(true);
      setIsForceChange(true);
    }
  }, [pathname, changePasswordOpen]);

  // Fetch billing history as fallback check for subscription status
  const { data: billingData, isLoading: isLoadingBilling, isError: isBillingError } = useSubscriptionControllerGetBillingHistoryV1({
    query: { retry: false, refetchOnWindowFocus: false },
  });
  const hasBillingHistory = !isLoadingBilling && !isBillingError && (billingData?.data || []).length > 0;

  // Fetch subscription status — active/trialing grants access; 'none' or expired → redirect
  const { data: subStatusData, isLoading: isLoadingSubStatus, isError: isSubStatusError } = useSubscriptionControllerGetSubscriptionStatusV1({
    query: { retry: false, refetchOnWindowFocus: false },
  });
  const subData = subStatusData?.data;
  const subStatusValue = subData?.status;
  const currentPeriodEnd = subData?.current_period_end;

  // Complimentary fields — backend ships these but they are not yet declared
  // on FrontendSubscriptionStatusData. Read via local cast.
  const compStatusFields = subData as
    | { is_complimentary?: boolean; complimentary_ends_at?: string | null; canceled_at?: string | null }
    | undefined;
  // Detect a "complimentary access ended" state — covers BOTH:
  //   • Auto-expired (cron flips status=cancelled, keeps is_complimentary=true)
  //   • Manually revoked (status=cancelled, is_complimentary=false, canceled_at set)
  // For both cases, access ends immediately — the date-based grace period
  // does NOT apply (admin or cron explicitly ended it).
  const isComplimentaryEnded = subStatusValue === 'cancelled' &&
    (compStatusFields?.is_complimentary === true || !!compStatusFields?.complimentary_ends_at);

  // Access rule: date-based grace period applies to PAID cancellations only.
  // Complimentary cancellations skip the grace period — access ends now.
  const hasAccessByDate = !isComplimentaryEnded && !!currentPeriodEnd && new Date() <= new Date(currentPeriodEnd);
  // Fallback for non-cancelled active statuses (in case current_period_end is missing)
  const hasActiveSubFromApi = hasAccessByDate ||
    subStatusValue === 'active' || subStatusValue === 'past_due' ||
    subStatusValue === 'incomplete' || subStatusValue === 'paused';

  // Update cookie when billing history confirms subscription.
  // Skip when complimentary access has ended — billing history shows $0 entries
  // for prior comp grants, so reviving has_active_subscription here would fight
  // the "complimentary-ended" effect below and cause an infinite render loop.
  useEffect(() => {
    if (!isComplimentaryEnded && hasBillingHistory && userData && !userData.has_active_subscription) {
      const updated = { ...userData, has_active_subscription: true };
      setUserDataCookie(updated);
      setUserData(updated);
    }
  }, [hasBillingHistory, userData, isComplimentaryEnded]);

  // Clear stale cookie state when API confirms complimentary access has ended.
  // Without this, the cookie keeps reporting has_active_subscription=true from the
  // login response and the layout's redirect logic never fires on subsequent navigations.
  useEffect(() => {
    if (isComplimentaryEnded && userData?.has_active_subscription) {
      const updated = { ...userData, has_active_subscription: false };
      setUserDataCookie(updated);
      setUserData(updated);
    }
  }, [isComplimentaryEnded, userData]);

  const isOnSubscriptionPage = pathname.startsWith('/practitioner/subscription');
  // Bibliography is publicly accessible — never redirect even for unsubscribed users.
  const isOnPublicPage = pathname.startsWith('/practitioner/bibliography');

  // Combined check: cookie OR billing history OR managed by a Practice Manager OR active subscription/trial.
  // BUT — when the API explicitly reports a complimentary-ended state, that signal
  // is authoritative. Cookie (`has_active_subscription`) is set at login and never
  // refreshed; billing history shows $0 entries for prior comp grants. Both are
  // false-positives after revoke/expire — override them with the API truth.
  const isSubscribed = !isComplimentaryEnded && (
    !!userData?.has_active_subscription || hasBillingHistory || !!userData?.is_managed || hasActiveSubFromApi
  );

  useEffect(() => {
    // Don't redirect while data is loading, on subscription/public pages, or if APIs errored
    // (when API errors, give benefit of the doubt — don't incorrectly redirect subscribed users)
    if (!userData || isOnSubscriptionPage || isOnPublicPage || isLoadingBilling || isBillingError || isLoadingSubStatus || isSubStatusError) return;
    if (!isSubscribed) {
      router.replace('/practitioner/subscription');
    }
    // Redirect group subscribers to practice manager dashboard
    if (isSubscribed && userData?.subscription_type === 'group') {
      router.replace('/practice-manager/dashboard');
    }
    // Auto-update cookie when billing confirms subscription
    // (skip when complimentary access has ended — see comment on the effect above)
    if (!isComplimentaryEnded && hasBillingHistory && !userData.has_active_subscription) {
      setUserDataCookie({ ...userData, has_active_subscription: true });
    }
  }, [userData, isOnSubscriptionPage, isOnPublicPage, router, isSubscribed, isLoadingBilling, isBillingError, hasBillingHistory, isLoadingSubStatus, isSubStatusError, isComplimentaryEnded]);

  const logoutMutation = useLoginControllerLogoutV1({
    mutation: {
      onSuccess: () => {
        logout();
      },
      onError: () => {
        logout();
      },
    },
  });

  const handleLogout = () => {
    logoutMutation.mutate();
  };

  const handlePasswordChanged = () => {
    setChangePasswordOpen(false);
    setIsForceChange(false);
    const data = getUserDataCookie();
    if (data) {
      const updated = { ...data, force_password_change: false };
      setUserDataCookie(updated);
      setUserData(updated);
    }
  };

  // While subscription APIs are loading and cookie doesn't confirm access yet,
  // show a blank loading screen to prevent dashboard flash for new users
  const isCheckingSubscription = (isLoadingBilling || isLoadingSubStatus) && !userData?.has_active_subscription && !userData?.is_managed && !isOnSubscriptionPage && !isOnPublicPage;

  return (
    <div className="min-h-screen bg-gray-50">
      <DashboardHeaderWrapper
        onEditProfile={() => setEditProfileOpen(true)}
        onChangePassword={() => setChangePasswordOpen(true)}
        onSupport={() => setSupportOpen(true)}
        onLogout={handleLogout}
        hasActiveSubscription={isSubscribed}
      />
      {isCheckingSubscription ? (
        <div className="flex items-center justify-center min-h-[80vh]">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#3B9EC9]" />
        </div>
      ) : children}
      <EditProfileModal
        isOpen={editProfileOpen}
        onClose={() => setEditProfileOpen(false)}
      />
      <ChangePasswordModal
        isOpen={changePasswordOpen}
        onClose={() => {
          if (!isForceChange) {
            setChangePasswordOpen(false);
          }
        }}
        forceChange={isForceChange}
        onPasswordChanged={handlePasswordChanged}
      />
      <SupportModal
        isOpen={supportOpen}
        onClose={() => setSupportOpen(false)}
      />
    </div>
  );
}
