"use client";

import React, { createContext, useState, useContext, useEffect } from "react";
import { toast } from "sonner";

interface LocationData {
  country: string;
  country_name?: string;
  country_code: string;
  timezone: string;
  currency: string;
  city: string;
  state: string;
  ip: string;
}

interface OrganizationData {
  name: string;
  email: string;
  phone: string;
  website: string;
  taxId?: string;
  address: {
    street: string;
    city: string;
    state: string;
    country: string;
    zipCode: string;
    country_code: string;
  };
  settings: { timezone: string; language: string; currency: string };
}

interface UserData {
  email: string;
  firstName: string;
  lastName: string;
  phone: string;
  country: string;
  password: string;
  confirmPassword: string;
  preferences: {
    notifications: { email: boolean; push: boolean };
    theme: string;
  };
}

interface OtpEmailState {
  sent: boolean;
  verified: boolean;
  otp: string;
  loading: boolean;
  timer: number;
}

interface OtpState {
  orgEmail: OtpEmailState;
  userEmail: OtpEmailState;
}

interface OnboardingContextType {
  currentStep: number;
  totalSteps: number;
  selectedPlan: string | null;
  billingPeriod: "monthly" | "yearly";
  organizationData: OrganizationData;
  userData: UserData;
  paymentData: { nameOnCard: string; billingZip: string };
  otpState: OtpState;
  signupResult: any;
  loading: boolean;
  detectingLocation: boolean;
  locationData: LocationData;
  plans: any[];
  leadId: string | null;
  leadCreated: boolean;
  setSelectedPlan: (id: string | null) => void;
  setBillingPeriod: (p: "monthly" | "yearly") => void;
  setOrganizationData: (data: Partial<OrganizationData>) => void;
  setUserData: (data: Partial<UserData>) => void;
  setPaymentData: (data: any) => void;
  setOtpState: (key: string, data: Partial<OtpEmailState>) => void;
  setSignupResult: (result: any) => void;
  setLoading: (loading: boolean) => void;
  nextStep: () => void;
  prevStep: () => void;
  goToStep: (step: number) => void;
  validateStep1: () => boolean;
  validateStep2: () => boolean;
  validateStep3: () => boolean;
  validateStep4: () => boolean;
  validateStep5: () => boolean;
  resetOnboarding: () => void;
  formatPhoneNumber: (phone: string, countryCode?: string) => string;
  isValidPhoneNumber: (phone: string) => boolean;
  detectLocation: () => Promise<void>;
  createLead: () => Promise<boolean>;
  updateLead: (data: any) => Promise<boolean>;
  deleteLead: () => Promise<void>;
}

const OnboardingContext = createContext<OnboardingContextType | null>(null);

export const useOnboarding = () => {
  const context = useContext(OnboardingContext);
  if (!context)
    throw new Error("useOnboarding must be used within OnboardingProvider");
  return context;
};

export const OnboardingProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const [currentStep, setCurrentStep] = useState(1);
  const [selectedPlan, setSelectedPlan] = useState<string | null>(null);
  const [billingPeriod, setBillingPeriod] = useState<"monthly" | "yearly">(
    "monthly",
  );
  const [plans, setPlans] = useState<any[]>([]);
  const [signupResult, setSignupResult] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [detectingLocation, setDetectingLocation] = useState(true);
  const [leadId, setLeadId] = useState<string | null>(null);
  const [leadCreated, setLeadCreated] = useState(false);

  const [locationData, setLocationData] = useState<LocationData>({
    country: "",
    country_code: "",
    timezone: "",
    currency: "",
    city: "",
    state: "",
    ip: "",
  });

  const [organizationData, setOrganizationDataState] =
    useState<OrganizationData>({
      name: "",
      email: "",
      phone: "",
      website: "",
      taxId:"",
      address: {
        street: "",
        city: "",
        state: "",
        country: "",
        zipCode: "",
        country_code: "",
      },
      settings: { timezone: "UTC", language: "en", currency: "USD" },
    });

  const [userData, setUserDataState] = useState<UserData>({
    email: "",
    firstName: "",
    lastName: "",
    phone: "",
    country: "",
     password:"",
  confirmPassword: "",
    preferences: { notifications: { email: true, push: true }, theme: "light" },
  });

  const [paymentData, setPaymentDataState] = useState({
    nameOnCard: "",
    billingZip: "",
  });

  const [otpState, setOtpStateData] = useState<OtpState>({
    orgEmail: {
      sent: false,
      verified: false,
      otp: "",
      loading: false,
      timer: 0,
    },
    userEmail: {
      sent: false,
      verified: false,
      otp: "",
      loading: false,
      timer: 0,
    },
  });

  const totalSteps = 5;

  const nextStep = () => {
    if (currentStep < totalSteps) {
      setCurrentStep((p) => p + 1);
      window.scrollTo({ top: 0, behavior: "smooth" });
    }
  };

  const prevStep = () => {
    if (currentStep > 1) {
      setCurrentStep((p) => p - 1);
      window.scrollTo({ top: 0, behavior: "smooth" });
    }
  };

  const goToStep = (step: number) => setCurrentStep(step);

  const setOrganizationData = (data: Partial<OrganizationData>) =>
    setOrganizationDataState((prev) => ({ ...prev, ...data }));

  const setUserData = (data: Partial<UserData>) =>
    setUserDataState((prev) => ({ ...prev, ...data }));

  const setPaymentData = (data: any) =>
    setPaymentDataState((prev) => ({ ...prev, ...data }));

  const setOtpState = (key: string, data: Partial<OtpEmailState>) =>
    setOtpStateData((prev) => ({
      ...prev,
      [key]: { ...prev[key as keyof OtpState], ...data },
    }));

  const isValidPhoneNumber = (phone: string) => {
    if (!phone) return false;
    const cleaned = phone.replace(/\D/g, "");
    return cleaned.length >= 10 && cleaned.length <= 15;
  };

  
  const formatPhoneNumber = (phone: string, countryCode?: string) => {
    let code = countryCode || organizationData?.address?.country_code || "IN";
    const cleaned = phone.replace(/\D/g, "");

    const phoneWithoutCode = cleaned.replace(/^91/, "")

    const formatters: Record<string, (p: string) => string> = {
      US: (p) =>
        p.length == 10
          ? `+1 (${p.slice(-10, -7)}) ${p.slice(-7, -4)}-${p.slice(-4)}`
          : `+1 ${p}`,
      IN: (p) =>
        p.length == 10 ? `+91 ${p.slice(-10, -5)} ${p.slice(-5)}` : `+91 ${(p.slice(0,10))}`,
      GB: (p) => `+44 ${p}`,
      CA: (p) =>
        p.length >= 10
          ? `+1 (${p.slice(-10, -7)}) ${p.slice(-7, -4)}-${p.slice(-4)}`
          : `+1 ${p}`,
      AU: (p) => `+61 ${p}`,
      AE: (p) => `+971 ${p}`,
      SG: (p) => `+65 ${p}`,
      DEFAULT: (p) => `+${p}`,
    };

    if (phoneWithoutCode.length == 0) {
      return ""
    }

    return (formatters[code] || formatters["DEFAULT"])(phoneWithoutCode);
  };

  const validateStep1 = () => {
    if (!selectedPlan) {
      toast.error("Please select a plan");
      return false;
    }
    return true;
  };

  const validateStep2 = () => {
    if (!organizationData.name?.trim()) {
      toast.error("Organization name is required");
      return false;
    }
    if (!/\S+@\S+\.\S+/.test(organizationData.email)) {
      toast.error("Invalid organization email");
      return false;
    }
    if (!otpState.orgEmail.verified) {
      toast.error("Please verify your organization email");
      return false;
    }
    if (!organizationData.phone?.trim()) {
      toast.error("Organization phone is required");
      return false;
    }
    if (!organizationData.address.street?.trim()) {
      toast.error("Street address is required");
      return false;
    }
    if (!organizationData.address.zipCode?.trim()) {
      toast.error("ZIP code is required");
      return false;
    }
    return true;
  };

  const validateStep3 = () => {
    if (!userData.firstName?.trim()) {
      toast.error("First name is required");
      return false;
    }
    if (!userData.lastName?.trim()) {
      toast.error("Last name is required");
      return false;
    }
    if (!/\S+@\S+\.\S+/.test(userData.email)) {
      toast.error("Invalid email");
      return false;
    }
    if (!otpState.userEmail.verified) {
      toast.error("Please verify your email");
      return false;
    }
    if (!userData.phone?.trim()) {
      toast.error("Phone number is required");
      return false;
    }
    return true;
  };

  const validateStep4 = () => {
    return true; // Payment validation handled in payment component
  };

  const validateStep5 = () => {
    return true; // Success step, no validation needed
  };

  const resetOnboarding = () => {
    setCurrentStep(1);
    setSelectedPlan(null);
    setBillingPeriod("monthly");
    setSignupResult(null);
    setLeadId(null);
    setLeadCreated(false);
  };

  const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000";

  const apiFetch = async (path: string, options: RequestInit = {}) => {
    const res = await fetch(`${API_BASE}${path}`, {
      ...options,
      headers: {
        "Content-Type": "application/json",
        ...(options.headers || {}),
      },
      credentials: "include",
    });
    const data = await res.json();
    if (!res.ok)
      throw new Error(data?.message || `Request failed: ${res.status}`);
    return data;
  };

  const detectLocation = async () => {
    setDetectingLocation(true);
    try {
      const data = await apiFetch("/detect-location");
      if (data.success && data.data) {
        const loc = data.data;
        console.log(loc)
        setLocationData({
          ...loc,
          country: loc.country_name,
          state: loc.region,
        });
        setOrganizationDataState((prev) => ({
          ...prev,
          address: {
            ...prev.address,
            city: loc.city || "",
            state: loc.region || "",
            country: loc.country_name || "",
            country_code: loc.country_code || "",
          },
          settings: {
            ...prev.settings,
            timezone: loc.timezone || "UTC",
            currency: "USD",
          },
        }));
        setUserDataState((prev) => ({
          ...prev,
          country: loc.country_code || "",
        }));
      }
    } catch {
      setLocationData({
        country: "United States",
        country_code: "US",
        timezone: "America/New_York",
        currency: "USD",
        city: "",
        state: "",
        ip: "",
      });
    } finally {
      setDetectingLocation(false);
    }
  };

  const createLead = async (): Promise<boolean> => {
    try {
      setLoading(true);
      const response = await apiFetch("/leads/create-lead", {
        method: "POST",
        body: JSON.stringify({
          planId: selectedPlan,
          billingPeriod,
          organizationData,
          locationData,
        }),
      });

      if (response.success && response.data?.leadId) {
        setLeadId(response.data.leadId);
        setLeadCreated(true);
        toast.success("Organization details saved");
        return true;
      } else {
        throw new Error(response.message || "Failed to create lead");
      }
    } catch (error: any) {
      toast.error(error.message || "Failed to save organization");
      return false;
    } finally {
      setLoading(false);
    }
  };

  const updateLead = async (data: any): Promise<boolean> => {
    if (!leadId) {
      toast.error("No lead found. Please start over.");
      return false;
    }

    try {
      setLoading(true);
      const response = await apiFetch(`/leads/${leadId}`, {
        method: "PUT",
        body: JSON.stringify(data),
      });

      if (response.success) {
        return true;
      } else {
        throw new Error(response.message || "Failed to update lead");
      }
    } catch (error: any) {
      toast.error(error.message || "Failed to update");
      return false;
    } finally {
      setLoading(false);
    }
  };

  const deleteLead = async () => {
    if (!leadId) return;

    try {
      await apiFetch(`/leads/${leadId}`, {
        method: "DELETE",
      });
      setLeadId(null);
      setLeadCreated(false);
    } catch (error: any) {
      console.error("Failed to delete lead:", error);
    }
  };

  const fetchPlans = async () => {
    try {
      setLoading(true);
      const data = await apiFetch("/client/subscription-plans");
      setPlans(data.data || []);
    } catch {
      toast.error("Failed to load subscription plans");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    detectLocation();
    fetchPlans();
  }, []);

  const value: OnboardingContextType = {
    currentStep,
    totalSteps,
    selectedPlan,
    billingPeriod,
    organizationData,
    userData,
    paymentData,
    otpState,
    signupResult,
    loading,
    detectingLocation,
    locationData,
    plans,
    leadId,
    leadCreated,
    setSelectedPlan,
    setBillingPeriod,
    setOrganizationData,
    setUserData,
    setPaymentData,
    setOtpState,
    setSignupResult,
    setLoading,
    nextStep,
    prevStep,
    goToStep,
    validateStep1,
    validateStep2,
    validateStep3,
    validateStep4,
    validateStep5,
    resetOnboarding,
    formatPhoneNumber,
    isValidPhoneNumber,
    detectLocation,
    createLead,
    updateLead,
    deleteLead,
  };

  return (
    <OnboardingContext.Provider value={value}>
      {children}
    </OnboardingContext.Provider>
  );
};
