"use client";

import { createContext, useContext, useEffect, useRef, useState, type ReactNode } from "react";
import { demoPassword, normalizeEmail, restoreAccounts, validEmail, type AccountState, type SavedAddress, type DemoProfile } from "@/lib/account";
import { normalizePhone, validateCheckout } from "@/lib/commerce";

type AccountStore = { profile: DemoProfile | null; ready: boolean; signIn: (email: string, password: string) => string; register: (name: string, email: string, password: string) => string; signOut: () => void; updateProfile: (name: string, phone: string) => string; saveAddress: (address: SavedAddress) => string; removeAddress: (id: string) => void; setDefault: (id: string) => void };
const Context = createContext<AccountStore | null>(null);
export function AccountProvider({ children }: { children: ReactNode }) {
  const [state, setState] = useState<AccountState>({ profiles: [], activeEmail: "" });
  const snapshot = useRef(state);
  const [ready, setReady] = useState(false);
  const profile = state.profiles.find((item) => item.email === state.activeEmail) ?? null;
  function change(next: AccountState) { snapshot.current = next; setState(next); }
  useEffect(() => { try { change(restoreAccounts(JSON.parse(localStorage.getItem("fashion-mart:accounts:demo:v1") ?? "null"))); } catch {} setReady(true); }, []);
  useEffect(() => { if (ready) try { localStorage.setItem("fashion-mart:accounts:demo:v1", JSON.stringify(state)); } catch {} }, [state, ready]);
  function update(action: (profile: DemoProfile) => DemoProfile) { const current = snapshot.current; change({ ...current, profiles: current.profiles.map((item) => item.email === current.activeEmail ? action(item) : item) }); }
  function signIn(email: string, password: string) {
    if (!ready) return "Please wait for your demo account to load.";
    const normalized = normalizeEmail(email);
    if (password !== demoPassword || !snapshot.current.profiles.some((item) => item.email === normalized)) return "Use a demo account created in this browser and password DEMO2026.";
    change({ ...snapshot.current, activeEmail: normalized }); return "";
  }
  function register(name: string, email: string, password: string) {
    if (!ready) return "Please wait for your demo account to load.";
    const normalized = normalizeEmail(email);
    if (name.trim().length < 2 || name.length > 80 || !validEmail(normalized)) return "Enter a name (2–80 characters) and valid email.";
    if (password !== demoPassword) return "Use DEMO2026 as the demo password. Do not enter a personal password.";
    if (snapshot.current.profiles.some((item) => item.email === normalized)) return "This demo email is already registered. Please sign in.";
    if (snapshot.current.profiles.length >= 10) return "This browser has reached the 10-account demo limit.";
    change({ profiles: [...snapshot.current.profiles, { name: name.trim(), email: normalized, phone: "", addresses: [], defaultAddressId: "" }], activeEmail: normalized }); return "";
  }
  function updateProfile(name: string, phone: string) {
    const normalized = normalizePhone(phone);
    if (name.trim().length < 2 || name.length > 80 || normalized && !/^01[3-9]\d{8}$/.test(normalized)) return "Enter a name (2–80 characters) and valid Bangladesh mobile number, or leave the number blank.";
    update((item) => ({ ...item, name: name.trim(), phone: normalized })); return "";
  }
  function saveAddress(address: SavedAddress) {
    const validation = validateCheckout(address);
    if (!validation.valid) return Object.values(validation.errors)[0] ?? "Check your address.";
    if (!address.label.trim() || address.label.length > 40) return "Enter an address label (1–40 characters).";
    const current = snapshot.current.profiles.find((item) => item.email === snapshot.current.activeEmail);
    if (!current) return "Sign in to save an address.";
    if (current.addresses.length >= 10 && !current.addresses.some((item) => item.id === address.id)) return "You can save up to 10 demo addresses.";
    update((item) => ({ ...item, addresses: [...item.addresses.filter((entry) => entry.id !== address.id), { ...validation.details, email: item.email, label: address.label.trim(), id: address.id }], defaultAddressId: item.defaultAddressId || address.id })); return "";
  }
  return <Context.Provider value={{ profile, ready, signIn, register, signOut: () => change({ ...snapshot.current, activeEmail: "" }), updateProfile, saveAddress, removeAddress: (id) => update((item) => { const addresses = item.addresses.filter((entry) => entry.id !== id); return { ...item, addresses, defaultAddressId: item.defaultAddressId === id ? addresses[0]?.id ?? "" : item.defaultAddressId }; }), setDefault: (id) => update((item) => item.addresses.some((entry) => entry.id === id) ? { ...item, defaultAddressId: id } : item) }}>{children}</Context.Provider>;
}
export function useAccount() { const context = useContext(Context); if (!context) throw new Error("Account provider missing"); return context; }
