import * as icon from '@mdi/js';
import Head from 'next/head'
import React from 'react'
import axios from 'axios';
import type { ReactElement } from 'react'
import LayoutAuthenticated from '../layouts/Authenticated'
import SectionMain from '../components/SectionMain'
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton'
import BaseIcon from "../components/BaseIcon";
import { getPageTitle } from '../config'
import Link from "next/link";
import CardBox from '../components/CardBox';
import BaseButton from '../components/BaseButton';

import { hasPermission } from "../helpers/userPermissions";
import { fetchWidgets } from '../stores/roles/rolesSlice';
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator';
import { SmartWidget } from '../components/SmartWidget/SmartWidget';

import { useAppDispatch, useAppSelector } from '../stores/hooks';

const Dashboard = () => {
    const dispatch = useAppDispatch();
    const iconsColor = useAppSelector((state) => state.style.iconsColor);
    const corners = useAppSelector((state) => state.style.corners);
    const cardsStyle = useAppSelector((state) => state.style.cardsStyle);

    const loadingMessage = 'Loading...';

    const [users, setUsers] = React.useState(loadingMessage);
    const [roles, setRoles] = React.useState(loadingMessage);
    const [permissions, setPermissions] = React.useState(loadingMessage);
    const [organizations, setOrganizations] = React.useState(loadingMessage);
    const [projects, setProjects] = React.useState(loadingMessage);
    const [pages, setPages] = React.useState(loadingMessage);
    const [components, setComponents] = React.useState(loadingMessage);
    const [layers, setLayers] = React.useState(loadingMessage);
    const [assets, setAssets] = React.useState(loadingMessage);
    const [versions, setVersions] = React.useState(loadingMessage);
    const [builds, setBuilds] = React.useState(loadingMessage);
    const [styles, setStyles] = React.useState(loadingMessage);
    const [teams, setTeams] = React.useState(loadingMessage);

    const [widgetsRole, setWidgetsRole] = React.useState({
        role: { value: '', label: '' },
    });
    const { currentUser } = useAppSelector((state) => state.auth);
    const { isFetchingQuery } = useAppSelector((state) => state.openAi);
    const { rolesWidgets, loading } = useAppSelector((state) => state.roles);
    
    async function loadData() {
        const entities = ['users','roles','permissions','organizations','projects','pages','components','layers','assets','versions','builds','styles','teams'];
        const fns = [setUsers,setRoles,setPermissions,setOrganizations,setProjects,setPages,setComponents,setLayers,setAssets,setVersions,setBuilds,setStyles,setTeams];

        const requests = entities.map((entity, index) => {
          if(hasPermission(currentUser, `READ_${entity.toUpperCase()}`)) {
            return axios.get(`/${entity.toLowerCase()}/count`);
          } else {
            fns[index](null);
            return Promise.resolve({data: {count: null}});
          }
        });

        Promise.allSettled(requests).then((results) => {
            results.forEach((result, i) => {
                if (result.status === 'fulfilled') {
                    fns[i](result.value.data.count);
                } else {
                    fns[i](result.reason.message);
                }
            });
        });
    }
  
    async function getWidgets(roleId: string) {
        await dispatch(fetchWidgets(roleId));
    }

    React.useEffect(() => {
        if (!currentUser) return;
        loadData().then();
        setWidgetsRole({ role: { value: currentUser?.app_role?.id, label: currentUser?.app_role?.name } });
    }, [currentUser]);

    React.useEffect(() => {
        if (!currentUser || !widgetsRole?.role?.value) return;
        getWidgets(widgetsRole?.role?.value || '').then();
    }, [widgetsRole?.role?.value]);
  
  return (
    <>
      <Head>
        <title>{getPageTitle('Overview')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={icon.mdiChartTimelineVariant} title='Overview' main>
          {''}
        </SectionTitleLineWithButton>

        {/* Welcome Banner */}
        <CardBox className="mb-6 bg-gradient-to-r from-blue-600 to-indigo-700 text-white border-none shadow-xl">
           <div className="flex flex-col md:flex-row items-center justify-between p-4">
              <div className="space-y-2 mb-4 md:mb-0">
                 <h2 className="text-2xl font-bold">Welcome back, {currentUser?.firstName || 'Builder'}!</h2>
                 <p className="text-blue-100 opacity-80">Ready to design your next masterpiece? Jump back into your projects.</p>
              </div>
              <BaseButton 
                href="/projects/projects-new" 
                label="Create New Project" 
                color="white" 
                className="font-bold text-blue-600 rounded-full px-6"
              />
           </div>
        </CardBox>
        
        {hasPermission(currentUser, 'CREATE_ROLES') && <WidgetCreator
            currentUser={currentUser}
            isFetchingQuery={isFetchingQuery}
            setWidgetsRole={setWidgetsRole}
            widgetsRole={widgetsRole}
        />}
        
        {!!rolesWidgets.length && hasPermission(currentUser, 'CREATE_ROLES') && (
            <p className='text-gray-500 dark:text-gray-400 mb-4'>
                {`${widgetsRole?.role?.label || 'Users'}'s widgets`}
            </p>
        )}

        <div className='grid grid-cols-1 gap-6 lg:grid-cols-4 mb-6 grid-flow-dense'>
            {(isFetchingQuery || loading) && (
                <div className={` ${corners !== 'rounded-full'? corners : 'rounded-3xl'} dark:bg-dark-900 text-lg leading-tight text-gray-500 flex items-center ${cardsStyle} dark:border-dark-700 p-6`}>
                    <BaseIcon className={`${iconsColor} animate-spin mr-5`} w='w-16' h='h-16' size={48} path={icon.mdiLoading} />{' '}
                    Loading widgets...
                </div>
            )}

            {rolesWidgets && rolesWidgets.map((widget) => (
                <SmartWidget
                    key={widget.id}
                    userId={currentUser?.id}
                    widget={widget}
                    roleId={widgetsRole?.role?.value || ''}
                    admin={hasPermission(currentUser, 'CREATE_ROLES')}
                />
            ))}
        </div>

        {!!rolesWidgets.length && <hr className='my-6' />}
        
        <div id="dashboard" className='grid grid-cols-1 gap-6 lg:grid-cols-3 mb-6'>
            {hasPermission(currentUser, 'READ_PROJECTS') && <Link href={'/projects/projects-list'}>
                <div className={`${corners !== 'rounded-full'? corners : 'rounded-3xl'} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6 hover:shadow-lg transition-shadow cursor-pointer`}>
                    <div className="flex justify-between align-center">
                        <div>
                            <div className="text-lg leading-tight text-gray-500 dark:text-gray-400">Projects</div>
                            <div className="text-3xl leading-tight font-semibold">{projects}</div>
                        </div>
                        <div>
                            <BaseIcon className={`${iconsColor}`} w="w-16" h="h-16" size={48} path={icon.mdiFolder} />
                        </div>
                    </div>
                </div>
            </Link>}

            {hasPermission(currentUser, 'READ_PAGES') && <Link href={'/pages/pages-list'}>
                <div className={`${corners !== 'rounded-full'? corners : 'rounded-3xl'} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6 hover:shadow-lg transition-shadow cursor-pointer`}>
                    <div className="flex justify-between align-center">
                        <div>
                            <div className="text-lg leading-tight text-gray-500 dark:text-gray-400">Pages</div>
                            <div className="text-3xl leading-tight font-semibold">{pages}</div>
                        </div>
                        <div>
                            <BaseIcon className={`${iconsColor}`} w="w-16" h="h-16" size={48} path={icon.mdiWeb} />
                        </div>
                    </div>
                </div>
            </Link>}

            {hasPermission(currentUser, 'READ_COMPONENTS') && <Link href={'/components/components-list'}>
                <div className={`${corners !== 'rounded-full'? corners : 'rounded-3xl'} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6 hover:shadow-lg transition-shadow cursor-pointer`}>
                    <div className="flex justify-between align-center">
                        <div>
                            <div className="text-lg leading-tight text-gray-500 dark:text-gray-400">Components</div>
                            <div className="text-3xl leading-tight font-semibold">{components}</div>
                        </div>
                        <div>
                            <BaseIcon className={`${iconsColor}`} w="w-16" h="h-16" size={48} path={icon.mdiPuzzle} />
                        </div>
                    </div>
                </div>
            </Link>}
        </div>
      </SectionMain>
    </>
  )
}

Dashboard.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated>{page}</LayoutAuthenticated>
}

export default Dashboard