"use client";

import React, { createContext, useContext, useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import {
  apiCustomerLogin,
  apiCustomerRegister,
  apiGetCustomerMe,
  CustomerUser
} from "@/services/customerAuthService";
import {
  getSavedPropertyIds,
  toggleSavedProperty
} from "@/services/savedPropertyService";

export interface UserProfile {
  id?: number;
  name: string;
  email: string;
  phone?: string;
  initials: string;
  role?: string;
  status?: string;
  avatar?: string;
}

interface AuthResult {
  success: boolean;
  error?: string;
}

interface AuthContextType {
  user: UserProfile | null;
  isLoggedIn: boolean;
  login: (emailOrPhone: string, password?: string) => Promise<AuthResult>;
  signup: (name: string, email: string, phone: string, password?: string) => Promise<AuthResult>;
  logout: () => void;
  authModalOpen: boolean;
  openAuthModal: (message?: string, redirectUrl?: string) => void;
  closeAuthModal: () => void;
  authModalMessage: string;
  
  // Saved Properties State & Helpers
  savedPropertyIds: number[];
  savedCount: number;
  isPropertySaved: (id: number | string) => boolean;
  toggleSaveProperty: (id: number | string, title?: string) => Promise<boolean>;
  refreshSavedProperties: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const router = useRouter();
  const [user, setUser] = useState<UserProfile | null>(null);
  const [authModalOpen, setAuthModalOpen] = useState(false);
  const [authModalMessage, setAuthModalMessage] = useState("");
  const [redirectTarget, setRedirectTarget] = useState<string | null>(null);
  const [savedPropertyIds, setSavedPropertyIds] = useState<number[]>([]);

  const getInitials = (name: string) => {
    if (!name) return "DH";
    const parts = name.trim().split(" ");
    if (parts.length === 1) return parts[0].substring(0, 2).toUpperCase();
    return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
  };

  const refreshSavedProperties = useCallback(async () => {
    const token = typeof window !== "undefined" ? localStorage.getItem("dreamhomes_customer_token") : null;
    if (!token) {
      setSavedPropertyIds([]);
      return;
    }
    try {
      const ids = await getSavedPropertyIds();
      setSavedPropertyIds(ids);
    } catch {
      // Ignore
    }
  }, []);

  // Initialize from localStorage and verify session with backend on mount
  useEffect(() => {
    try {
      const stored = localStorage.getItem("dreamhomes_customer_user");
      const token = localStorage.getItem("dreamhomes_customer_token");

      if (stored) {
        setUser(JSON.parse(stored));
      }

      if (token) {
        apiGetCustomerMe(token).then((me) => {
          if (me) {
            const updatedUser: UserProfile = {
              id: me.id,
              name: me.name,
              email: me.email,
              phone: me.phone,
              role: me.role,
              status: me.status,
              avatar: me.avatar,
              initials: getInitials(me.name)
            };
            setUser(updatedUser);
            localStorage.setItem("dreamhomes_customer_user", JSON.stringify(updatedUser));
          }
        }).catch(() => {});

        // Fetch user's saved property IDs
        getSavedPropertyIds().then((ids) => {
          setSavedPropertyIds(ids);
        }).catch(() => {});
      }
    } catch (e) {
      // Ignore storage errors
    }
  }, []);

  const isPropertySaved = useCallback(
    (id: number | string) => {
      const numId = Number(id);
      return savedPropertyIds.includes(numId);
    },
    [savedPropertyIds]
  );

  const toggleSaveProperty = async (id: number | string, title?: string): Promise<boolean> => {
    const token = typeof window !== "undefined" ? localStorage.getItem("dreamhomes_customer_token") : null;
    
    // If not logged in, prompt Auth Modal!
    if (!user || !token) {
      openAuthModal(
        title 
          ? `Please sign in or create an account to save "${title}" to your wishlist.` 
          : "Please sign in or create an account to save properties."
      );
      return false;
    }

    const numId = Number(id);
    const currentlySaved = savedPropertyIds.includes(numId);

    // Optimistic UI update
    if (currentlySaved) {
      setSavedPropertyIds((prev) => prev.filter((x) => x !== numId));
    } else {
      setSavedPropertyIds((prev) => [...prev, numId]);
    }

    try {
      const res = await toggleSavedProperty(id);
      if (!res.success) {
        // Revert on failure
        refreshSavedProperties();
        return false;
      }
      if (res.saved) {
        setSavedPropertyIds((prev) => Array.from(new Set([...prev, numId])));
      } else {
        setSavedPropertyIds((prev) => prev.filter((x) => x !== numId));
      }
      return res.saved;
    } catch {
      refreshSavedProperties();
      return false;
    }
  };

  const login = async (emailOrPhone: string, password?: string): Promise<AuthResult> => {
    const cleanId = emailOrPhone.trim();
    const cleanPass = password?.trim() || "";

    const res = await apiCustomerLogin(cleanId, cleanPass);

    if (!res.success) {
      return {
        success: false,
        error: res.error || "Invalid credentials. Please verify your email and password."
      };
    }

    const userData = res.data?.user;
    const token = res.data?.token;

    if (userData) {
      const newUser: UserProfile = {
        id: userData.id,
        name: userData.name,
        email: userData.email,
        phone: userData.phone,
        role: userData.role || "Customer",
        status: userData.status || "Active",
        avatar: userData.avatar,
        initials: getInitials(userData.name)
      };

      setUser(newUser);
      try {
        localStorage.setItem("dreamhomes_customer_user", JSON.stringify(newUser));
        if (token) {
          localStorage.setItem("dreamhomes_customer_token", token);
        }
      } catch (e) {}

      // Refresh saved properties
      getSavedPropertyIds().then((ids) => setSavedPropertyIds(ids)).catch(() => {});
    }

    if (redirectTarget) {
      router.push(redirectTarget);
      setRedirectTarget(null);
    }

    return { success: true };
  };

  const signup = async (name: string, email: string, phone: string, password?: string): Promise<AuthResult> => {
    const cleanName = name.trim();
    const cleanEmail = email.trim();
    const cleanPhone = phone.trim();
    const cleanPass = password?.trim() || "password123";

    const res = await apiCustomerRegister({
      name: cleanName,
      email: cleanEmail,
      phone: cleanPhone,
      password: cleanPass,
    });

    if (!res.success) {
      return {
        success: false,
        error: res.error || "Account creation failed. Please check your details."
      };
    }

    const userData = res.data?.user;
    const token = res.data?.token;

    if (userData) {
      const newUser: UserProfile = {
        id: userData.id,
        name: userData.name,
        email: userData.email,
        phone: userData.phone,
        role: userData.role || "Customer",
        status: userData.status || "Active",
        avatar: userData.avatar,
        initials: getInitials(userData.name)
      };

      setUser(newUser);
      try {
        localStorage.setItem("dreamhomes_customer_user", JSON.stringify(newUser));
        if (token) {
          localStorage.setItem("dreamhomes_customer_token", token);
        }
      } catch (e) {}

      setSavedPropertyIds([]);
    }

    if (redirectTarget) {
      router.push(redirectTarget);
      setRedirectTarget(null);
    }

    return { success: true };
  };

  const logout = () => {
    setUser(null);
    setSavedPropertyIds([]);
    try {
      localStorage.removeItem("dreamhomes_customer_user");
      localStorage.removeItem("dreamhomes_customer_token");
    } catch (e) {}
  };

  const openAuthModal = (message?: string, redirectUrl?: string) => {
    setAuthModalMessage(message || "Please sign in or create an account to continue.");
    if (redirectUrl) setRedirectTarget(redirectUrl);
    setAuthModalOpen(true);
  };

  const closeAuthModal = () => {
    setAuthModalOpen(false);
  };

  return (
    <AuthContext.Provider
      value={{
        user,
        isLoggedIn: !!user,
        login,
        signup,
        logout,
        authModalOpen,
        openAuthModal,
        closeAuthModal,
        authModalMessage,
        savedPropertyIds,
        savedCount: savedPropertyIds.length,
        isPropertySaved,
        toggleSaveProperty,
        refreshSavedProperties
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
}
