import * as icon from '@mdi/js';
import Head from 'next/head';
import React from 'react';
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 { hasPermission } from '../helpers/userPermissions';
import { fetchWidgets } from '../stores/roles/rolesSlice';
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator';
import { SmartWidget } from '../components/SmartWidget/SmartWidget';
import {
  useDashboardCounts,
  EntityCountValue,
} from '../hooks/useDashboardCounts';

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

/**
 * Dashboard card component for entity counts
 */
interface DashboardCardProps {
  href: string;
  label: string;
  count: EntityCountValue;
  iconKey: string;
  corners: string;
  cardsStyle: string;
  iconsColor: string;
}

const DashboardCard = ({
  href,
  label,
  count,
  iconKey,
  corners,
  cardsStyle,
  iconsColor,
}: DashboardCardProps) => {
  const iconPath =
    (icon as Record<string, string>)[iconKey] ??
    (icon as Record<string, string>)['mdiFormatListBulleted'];

  return (
    <Link href={href}>
      <div
        className={`${corners !== 'rounded-full' ? corners : 'rounded-3xl'} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
      >
        <div className='flex justify-between align-center'>
          <div>
            <div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
              {label}
            </div>
            <div className='text-3xl leading-tight font-semibold'>{count}</div>
          </div>
          <div>
            <BaseIcon
              className={`${iconsColor}`}
              w='w-16'
              h='h-16'
              size={48}
              path={iconPath}
            />
          </div>
        </div>
      </div>
    </Link>
  );
};

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 { currentUser } = useAppSelector((state) => state.auth);
  const { isFetchingQuery } = useAppSelector((state) => state.openAi);

  // Use the centralized dashboard counts hook
  const { getCount, getVisibleEntities } = useDashboardCounts(currentUser);

  const [widgetsRole, setWidgetsRole] = React.useState({
    role: { value: '', label: '' },
  });

  const { rolesWidgets, loading } = useAppSelector((state) => state.roles) as {
    rolesWidgets: Array<{ id: string; [key: string]: unknown }>;
    loading: boolean;
  };

  async function getWidgets(roleId: string) {
    await dispatch(fetchWidgets(roleId));
  }

  React.useEffect(() => {
    if (!currentUser) return;
    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]);

  // Get entities visible to current user
  const visibleEntities = getVisibleEntities();

  return (
    <>
      <Head>
        <title>{getPageTitle('Overview')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={icon.mdiChartTimelineVariant}
          title='Overview'
          main
        >
          {''}
        </SectionTitleLineWithButton>

        {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'
        >
          {visibleEntities.map((entity) => (
            <DashboardCard
              key={entity.key}
              href={entity.href}
              label={entity.label}
              count={getCount(entity.key)}
              iconKey={entity.icon}
              corners={corners}
              cardsStyle={cardsStyle}
              iconsColor={iconsColor}
            />
          ))}
        </div>
      </SectionMain>
    </>
  );
};

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

export default Dashboard;
