/**
 * useSubscription Hook — state-machine-aligned subscription management.
 *
 * Exposes the operative subscription, any scheduled successor, available plans,
 * and ID-based mutation functions (activate, cancel, reactivate).
 */

import { useState, useEffect, useCallback } from 'react';
import { useApiRequest } from './useApi';
import {
  fetchSelectablePlans,
  fetchSubscriptionStatus,
  activatePlan as activatePlanApi,
  cancelSubscription as cancelSubscriptionApi,
  reactivateSubscription as reactivateSubscriptionApi,
  verifyCheckout as verifyCheckoutApi,
  type SubscriptionPlan,
  type MandateSubscription,
  type SubscriptionStatusResponse,
  type SubscriptionUsage,
} from '../api/subscriptionApi';

export interface UseSubscriptionReturn {
  plans: SubscriptionPlan[];
  subscription: MandateSubscription | null;
  plan: SubscriptionPlan | null;
  scheduled: MandateSubscription | null;
  usage: SubscriptionUsage | null;
  active: boolean;
  loading: boolean;
  error: string | null;
  loadPlans: () => Promise<void>;
  loadStatus: () => Promise<void>;
  activatePlan: (planKey: string) => Promise<void>;
  cancelSubscription: (subscriptionId: string) => Promise<void>;
  reactivateSubscription: (subscriptionId: string) => Promise<void>;
  verifyCheckout: (sessionId: string) => Promise<{ status: string; message: string }>;
  refetch: () => Promise<void>;
}

export function useSubscription(mandateId?: string): UseSubscriptionReturn {
  const [plans, setPlans] = useState<SubscriptionPlan[]>([]);
  const [subscription, setSubscription] = useState<MandateSubscription | null>(null);
  const [plan, setPlan] = useState<SubscriptionPlan | null>(null);
  const [scheduled, setScheduled] = useState<MandateSubscription | null>(null);
  const [usage, setUsage] = useState<SubscriptionUsage | null>(null);
  const [active, setActive] = useState(false);
  const { request, isLoading: loading, error: apiError, clearCache } = useApiRequest();
  const [error, setError] = useState<string | null>(null);

  const loadPlans = useCallback(async () => {
    clearCache('/api/subscription/plans', 'get');
    try {
      const data = await fetchSelectablePlans(request, mandateId);
      setPlans(Array.isArray(data) ? data : []);
    } catch (err) {
      console.error('Error loading plans:', err);
      setPlans([]);
    }
  }, [request, mandateId, clearCache]);

  const loadStatus = useCallback(async () => {
    clearCache('/api/subscription/status', 'get');
    try {
      const data: SubscriptionStatusResponse = await fetchSubscriptionStatus(request, mandateId);
      setActive(data.active);
      setSubscription(data.subscription ?? null);
      setPlan(data.plan ?? null);
      setScheduled(data.scheduled ?? null);
      setUsage(data.usage ?? null);
    } catch (err) {
      console.error('Error loading subscription status:', err);
      setActive(false);
      setSubscription(null);
      setPlan(null);
      setScheduled(null);
      setUsage(null);
    }
  }, [request, mandateId, clearCache]);

  const activatePlan = useCallback(async (planKey: string) => {
    try {
      setError(null);
      const currentUrl = new URL(window.location.href);
      currentUrl.searchParams.delete('success');
      currentUrl.searchParams.delete('canceled');
      currentUrl.searchParams.delete('session_id');
      currentUrl.searchParams.set('tab', 'subscription');
      if (mandateId) currentUrl.searchParams.set('mandate', mandateId);
      const returnUrl = `${currentUrl.origin}${currentUrl.pathname}${currentUrl.search}`;

      const result = await activatePlanApi(request, planKey, mandateId, returnUrl);
      if (result?.redirectUrl) {
        window.location.href = result.redirectUrl;
        return;
      }
      await loadStatus();
    } catch (err: any) {
      const msg = err?.response?.data?.detail || err.message || 'Fehler beim Aktivieren';
      setError(msg);
      throw err;
    }
  }, [request, mandateId, loadStatus]);

  const cancelSub = useCallback(async (subscriptionId: string) => {
    try {
      setError(null);
      await cancelSubscriptionApi(request, subscriptionId, mandateId);
      await loadStatus();
    } catch (err: any) {
      const msg = err?.response?.data?.detail || err.message || 'Fehler beim Kündigen';
      setError(msg);
      throw err;
    }
  }, [request, mandateId, loadStatus]);

  const reactivateSub = useCallback(async (subscriptionId: string) => {
    try {
      setError(null);
      await reactivateSubscriptionApi(request, subscriptionId, mandateId);
      await loadStatus();
    } catch (err: any) {
      const msg = err?.response?.data?.detail || err.message || 'Fehler beim Reaktivieren';
      setError(msg);
      throw err;
    }
  }, [request, mandateId, loadStatus]);

  const verifyCheckout = useCallback(async (sessionId: string) => {
    const result = await verifyCheckoutApi(request, sessionId, mandateId);
    await loadStatus();
    return result;
  }, [request, mandateId, loadStatus]);

  const refetch = useCallback(async () => {
    await Promise.all([loadPlans(), loadStatus()]);
  }, [loadPlans, loadStatus]);

  useEffect(() => {
    if (mandateId) {
      loadPlans();
      loadStatus();
    } else {
      setPlans([]);
      setSubscription(null);
      setPlan(null);
      setScheduled(null);
      setUsage(null);
      setActive(false);
    }
  }, [mandateId]);

  return {
    plans,
    subscription,
    plan,
    scheduled,
    usage,
    active,
    loading,
    error: error || (apiError ? String(apiError) : null),
    loadPlans,
    loadStatus,
    activatePlan,
    cancelSubscription: cancelSub,
    reactivateSubscription: reactivateSub,
    verifyCheckout,
    refetch,
  };
}
