import { useCallback, useEffect, useRef, useState } from 'react'
import './App.css'
import { useUserAPI } from '../providers/pond/userAPI'
import { useAuth0 } from '@auth0/auth0-react'
import { or } from '../utils/types'
import LoadingScreen from './LoadingScreen'
import NavigationContainer from '../navigation/NavigationContainer'
import { GlobalState, GlobalStateAction, StateProvider } from '../providers/StateContainer'
import { User } from '../models/user'
import { Team } from '../models/team'
import { makeStyles } from '@mui/styles'
import { CssBaseline, Theme } from '@mui/material'
import { AppThemeProvider } from 'theme/AppThemeProvider'
import HTTPProvider from 'providers/http'
import { Crisp } from "crisp-sdk-web";
import { useMobile, useSnackbar } from 'hooks'
// import FirmwareLoader from './FirmwareLoader'

const reducer = (state: GlobalState, action: GlobalStateAction): GlobalState => {
  return {
    ...state,
    [action.key]: action.value
  };
};

const useStyles = makeStyles((theme: Theme) => ({
  appContent: {
    paddingTop: 56,
    paddingBottom: 56,
    paddingLeft: "0px",
    [theme.breakpoints.up("sm")]: {
      paddingTop: 64,
      paddingBottom: 0,
    },
    [theme.breakpoints.up("md")]: {
      paddingLeft: theme.spacing(9)
    },
  },
  container: {
    backgroundColor: theme.palette.background.default,
  },
  helloMessage: {
    marginTop: theme.spacing(2),
  },
}))

const globalDefault = {
  user: User.create(),
  team: Team.create(),
  as: "",
  showErrors: false,
  userTeamPermissions: [],
  backgroundTasksComplete: false,
  firmware: new Map(),
}

interface Props {
  token: string;
}

export default function UserWrapper(props: Props) {
  const { token } = props;
  const [loading, setLoading] = useState(false)
  const userAPI = useUserAPI();
  const classes = useStyles();
  const useAuth = useAuth0();
  const hasFetched = useRef(false);
  const [global, setGlobal] = useState<undefined | GlobalState>(undefined)
  const snackbar = useSnackbar()
  const isMobile = useMobile()

  const user_id = or(useAuth.user?.sub, "")

  const crispInitialized = useRef(false);
  Crisp.configure(import.meta.env.VITE_CRISP_WEBSITE_ID);

  const loadUser = useCallback(() => {
    if (!userAPI.getUserWithTeam) return;
    if (hasFetched.current) return;
    setLoading(true)
    userAPI.getUserWithTeam(user_id).then(resp => {
      setGlobal({
        user: resp.data.user ? User.create(resp.data.user) : User.create(),
        team: resp.data.team ? Team.create(resp.data.team) : Team.create(),
        as: resp.data.user?.settings?.useTeam === true ? resp.data.user.settings.defaultTeam : "",
        showErrors: false,
        userTeamPermissions: [],
        backgroundTasksComplete: false,
        firmware: new Map()
      })
    }).catch((err) => {
      snackbar.error("get user and team: "+err)
      userAPI.getUser(user_id).then(user => {
        setGlobal({
          user: user ? user : User.create(),
          team: globalDefault.team,
          as: "",
          showErrors: false,
          userTeamPermissions: [],
          backgroundTasksComplete: false,
          firmware: new Map()
        })
      }).catch((err) => {
        snackbar.error("get user: "+err)
        setGlobal(globalDefault)
      })
      
    })
    .finally(() => {
      setLoading(false)
      hasFetched.current = true;
    })
  }, [setGlobal])

  useEffect(() => {
    if (!crispInitialized.current && global?.user) {
      Crisp.configure(import.meta.env.VITE_CRISP_WEBSITE_ID);
      crispInitialized.current = true;
      Crisp.session.reset();
      Crisp.user.setEmail(global?.user.settings.email);
      // Optional: Set nickname or other info
      Crisp.user.setNickname(global?.user.settings.name || global?.user.settings.email);
      Crisp.user.setPhone(global?.user.settings.phoneNumber);

      // For extra security (marks email as verified, prevents spoofing):
      // Crisp.user.setEmail(user.email, "your-hmac-signature-here"); // See Crisp docs for signing

      // Optional: For session continuity across devices/browsers
      Crisp.setTokenId(global?.user.id()); // e.g., your DB user ID
    }
  }, [global]);

  // useEffect(() => {
  //   if (window.$crisp) {
  //     if (isMobile) {
  //       $crisp.push(["config", "position:offset", [20, 120]]);
  //     } else {
  //       $crisp.push(["config", "position:offset", [20, 20]]);
  //     }
  //   }
  // }, [isMobile]);

  // useEffect(() => {
  //   console.log("crisb")
  //   const crispEl = document.getElementById("crisp-chatbox");
  //   console.log(crispEl)
  //   if (crispEl) {
  //     if (isMobile) {
  //       console.log("setting margin")
  //       crispEl.style.setProperty("margin-bottom", "180px", "important");
  //     } else {
  //       crispEl.style.setProperty("margin-bottom", "0px", "important");
  //     }
  //   }
  // }, [isMobile]);

  useEffect(() => {
    let style = document.getElementById("crisp-offset-override");
    if (!style) {
      style = document.createElement("style");
      style.id = "crisp-offset-override";
      document.head.appendChild(style);
    }

    if (isMobile) {
      style.textContent = `
        #crisp-chatbox [aria-label="Open chat"] {
          bottom: 6em !important;
        }
        // #crisp-chatbox [data-visible][style*="width: 360px"] {
        //   bottom: 180px !important;
        // }
      `;
    } else {
      style.textContent = "";
    }

    return () => style?.remove();
  }, [isMobile]);
  
  useEffect(() => {
    if (loading) return;
    loadUser()
  }, [loading])
  
  if (loading || !global) return (
    <LoadingScreen />
  )

  return (
    <StateProvider state={global} reducer={reducer}>
      <AppThemeProvider >
        <CssBaseline/>
        <main className={classes.appContent}>
          <HTTPProvider token={token}>
            <NavigationContainer />
          </HTTPProvider>
        </main>
      </AppThemeProvider>
    </StateProvider>
  )
}