"use client";

import { useState, useCallback } from "react";
import { api } from "@/lib/api-client";
import { isLegacyMockSessionId } from "@/lib/auth-cookie";

function isAuthError(message: string): boolean {
  return /unauthorized|token_legacy|sign in again/i.test(message);
}

export const ONBOARDING_STEPS = [
  "ACCOUNT",
  "CONSENT",
  "KYC",
  "FARM_PROFILE",
  "LAND_SKETCH",
  "GIS_MAPPING",
  "CROP_PLAN",
  "FARM_ASSETS",
  "DOCUMENTS",
  "FINANCE_REQUEST",
  "REVIEW",
  "SCORING",
  "RESULT",
] as const;

export type StepKey = (typeof ONBOARDING_STEPS)[number];

export const STEP_LABELS: Record<StepKey, string> = {
  ACCOUNT: "Account",
  CONSENT: "Consent",
  KYC: "Identity",
  FARM_PROFILE: "Profile",
  LAND_SKETCH: "Land",
  GIS_MAPPING: "GIS Map",
  CROP_PLAN: "Crops",
  FARM_ASSETS: "Assets",
  FINANCE_REQUEST: "Finance",
  DOCUMENTS: "Documents",
  REVIEW: "Review",
  SCORING: "Scoring",
  RESULT: "Result",
};

export function useOnboardingSession() {
  const [session, setSession] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const createOrResume = useCallback(async (forceNew = false) => {
    setLoading(true);
    setError(null);
    try {
      const data = await api.onboarding.createOrResume("UZ", "farmer", forceNew);
      setSession(data);
      return data;
    } catch (e: any) {
      setError(e.message);
      throw e;
    } finally {
      setLoading(false);
    }
  }, []);

  const loadSession = useCallback(async (id: string) => {
    setLoading(true);
    try {
      const data = await api.onboarding.get(id);
      setSession(data);
      return data;
    } catch (e: any) {
      setError(e.message);
      throw e;
    } finally {
      setLoading(false);
    }
  }, []);

  const saveStep = useCallback(
    async (step: StepKey, data: any, markComplete = true) => {
      if (!session) return;
      setLoading(true);
      setError(null);
      try {
        let activeSession = session;
        try {
          const updated = await api.onboarding.updateStep(
            activeSession.id,
            step,
            data,
            markComplete,
          );
          setSession(updated);
          return updated;
        } catch (e: unknown) {
          const message = e instanceof Error ? e.message : String(e);
          if (isAuthError(message)) {
            setSession(null);
            try {
              await api.auth.logout();
            } catch {
              // ignore
            }
            throw e;
          }
          if (
            step === "SCORING" &&
            markComplete &&
            /session already completed/i.test(message)
          ) {
            const refreshed = await api.onboarding.get(activeSession.id);
            setSession(refreshed);
            return refreshed;
          }
          if (isLegacyMockSessionId(activeSession.id) || message === "Not your session") {
            activeSession = await api.onboarding.createOrResume("UZ", "farmer", true);
            setSession(activeSession);
            const updated = await api.onboarding.updateStep(
              activeSession.id,
              step,
              data,
              markComplete,
            );
            setSession(updated);
            return updated;
          }
          throw e;
        }
      } catch (e: any) {
        setError(e.message);
        throw e;
      } finally {
        setLoading(false);
      }
    },
    [session],
  );

  const submitForProcessing = useCallback(async () => {
    if (!session) return;
    setLoading(true);
    try {
      const data = await api.onboarding.submit(session.id);
      setSession(data);
      return data;
    } catch (e: any) {
      setError(e.message);
      throw e;
    } finally {
      setLoading(false);
    }
  }, [session]);

  const pollStatus = useCallback(async () => {
    if (!session) return null;
    try {
      return await api.onboarding.status(session.id);
    } catch {
      return null;
    }
  }, [session]);

  return {
    session,
    setSession,
    loading,
    error,
    createOrResume,
    loadSession,
    saveStep,
    submitForProcessing,
    pollStatus,
  };
}
