import * as React from 'react';
import { useEffect } from 'react';
import CssBaseline from '@mui/material/CssBaseline';
import Container from '@mui/material/Container';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import AppTheme from '../shared-theme/AppTheme';
import MainContent from './components/MainContent';
import ArticleView from './components/Article/ArticleView';
import ArticleEditor from './components/Article/ArticleEditor';
import Latest from './components/Latest';
import Footer from './components/Footer';
import Profile from './components/Profile';
import { useArticles } from './providers/Article';
import { useAuth as useAuthor } from './providers/Author';
import { View, useViewRouter } from "./types/views";
import { ArticleModel, ArticlesModel } from "./types/models";
import { ArticleViewProps, ArticleEditorProps } from "./types/props";

import { useAuth, AuthPage, AuthMode } from '../../auth/src';

function HomeView({
  currentUser,
  open_auth,
  open_profile,
  open_create,
  articles,
  openArticle,
}: any) {
  return (
    <>
      <Box sx={{ display: 'flex', justifyContent: 'flex-end', mb: 2, gap: 1 }}>
        {!currentUser ? (
          <Button variant='outlined' onClick={() => open_auth('login')}>
            Login
          </Button>
        ) : (
          <>
            <Button variant='outlined' onClick={open_profile}>
              {currentUser.username}
            </Button>
            <Button variant='contained' onClick={open_create}>
              New Article
            </Button>
          </>
        )}
      </Box>

      <MainContent articles={articles} onSelectArticle={openArticle} />
      <Latest articles={articles} onSelectArticle={openArticle} />
    </>
  );
}

export default function Blog(props: { disableCustomTheme?: boolean }) {
  const { articles, loading, error } = useArticles();
  const auth = useAuth();
  const { currentUser } = useAuthor();

  const [ui, setUI] = React.useState({
    selectedArticle: null as ArticleModel | null,
    view: 'home' as View,
    authMode: 'login' as AuthMode,
  });

  useEffect(() => {
    if (loading) return;

    const path = window.location.pathname;
    const parts = path.split('/').filter(Boolean);

    if (parts[0] === 'articles' && parts[1]) {
      const id = parts[1];
      const article = articles.readById(id);

      if (article) {
        setUI({
          selectedArticle: article,
          view: 'article',
          authMode: 'login'
        });
      }
    }
  }, [loading]);

  const {
    goBack,
    navigateToChildren,
    openArticle,
  } = useViewRouter(setUI);

  type RouterContext = {
    ui: typeof ui;
    articles: ArticlesModel;
    currentUser: any;
    openArticle: (article: ArticleModel) => void;
  };

  type ViewComponentEntry<P> = {
    component: React.ComponentType<P>;
    extraProps?: (ctx: RouterContext) => Partial<P>;
    navigationMap?: Record<string, string>;
  };

  // @ts-ignore
  const VIEW_COMPONENTS: Record<View, ViewComponentEntry<any>> = {
    home: {
      component: HomeView,
    },

    auth: {
      component: AuthPage,
      extraProps: ({ ui }) => ({
        mode: ui.authMode,
        onSwitchMode: () =>
          setUI((prev) => ({
            ...prev,
            authMode: prev.authMode === 'login' ? 'register' : 'login',
          })),
        login: auth.login,
        register: auth.register,
        loading: auth.loading,
        error: auth.error,
        currentUser: currentUser,
      }),
    },

    profile: {
      component: Profile,
    },

    article: {
      component: ArticleView,
      navigationMap: {
        open_editor: 'onEdit',
      },
      extraProps: ({ ui, articles }) => ({
        // @ts-ignore
        article: articles.readById(ui.selectedArticle._id),
      }) satisfies Partial<ArticleViewProps>,
    },

    editor: {
      component: ArticleEditor,
      extraProps: ({ ui, articles }) => ({
        article: ui.selectedArticle !== null ? articles.readById(ui.selectedArticle._id as string) : null,
      }) satisfies Partial<ArticleEditorProps>,
    },

    create: {
      component: ArticleEditor,
      extraProps: () => ({
        article: null,
      }) satisfies Partial<ArticleEditorProps>,
    },
  };

  const renderView = () => {
    const entry = VIEW_COMPONENTS[ui.view];
    const navigationMap= entry['navigationMap'] || {}
    const ViewComponent = entry.component;

    const childNav = {
      ...navigateToChildren(ui.view, navigationMap),
      open_auth: (mode: AuthMode = 'login') =>
        setUI((prev) => ({
          ...prev,
          view: 'auth',
          authMode: mode,
        })),
    };

    const ctx: RouterContext = {
      ui,
      articles,
      currentUser,

      openArticle,
    };

    const extraProps = entry.extraProps ? entry.extraProps(ctx) : {};

    return (
      <ViewComponent
        {...ctx}
        {...childNav}
        onBack={() => goBack(ui.view)}
        {...extraProps}
      />
    );
  };

  if (loading) {
    return (
      <AppTheme {...props}>
        <CssBaseline enableColorScheme />
        <Container
          maxWidth="lg"
          component="main"
          sx={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            height: '100vh',
          }}
        >
          Loading articles...
        </Container>
      </AppTheme>
    );
  }

  if (error) {
    return (
      <AppTheme {...props}>
        <CssBaseline enableColorScheme />
        <Container
          maxWidth="lg"
          component="main"
          sx={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            height: '100vh',
          }}
        >
          Failed to load articles: {error}
        </Container>
      </AppTheme>
    );
  }

  return (
    <AppTheme {...props}>
      <CssBaseline enableColorScheme />

      <Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>
        <Container
          maxWidth="lg"
          component="main"
          sx={{
            flex: '1 0 auto',
            display: 'flex',
            flexDirection: 'column',
            my: 4,
            gap: 4,
            pb: ui.view === 'home' ? 24 : 0,
          }}
        >
          {renderView()}
        </Container>

        {ui.view === 'home' && (
          <Box
            component='footer'
            sx={{
              position: 'fixed',
              bottom: 0,
              left: 0,
              right: 0,
              zIndex: 1000,
              bgcolor: 'background.paper',
              boxShadow: '0 -2px 10px rgba(0,0,0,0.08)',
            }}
          >
            <Footer />
          </Box>
        )}
      </Box>
    </AppTheme>
  );
}
