import * as icon from '@mdi/js'
import Head from 'next/head'
import Link from 'next/link'
import axios from 'axios'
import React from 'react'
import { useRouter } from 'next/router'
import type { ReactElement } from 'react'
import LayoutAuthenticated from '../layouts/Authenticated'
import SectionMain from '../components/SectionMain'
import CardBox from '../components/CardBox'
import BaseButton from '../components/BaseButton'
import BaseButtons from '../components/BaseButtons'
import BaseIcon from '../components/BaseIcon'
import NotificationBar from '../components/NotificationBar'
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton'
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator'
import { SmartWidget } from '../components/SmartWidget/SmartWidget'
import { getPageTitle } from '../config'
import { hasPermission } from '../helpers/userPermissions'
import { getWorkspaceRoute, isDashboardRole } from '../helpers/workspace'
import { useAppDispatch, useAppSelector } from '../stores/hooks'
import { fetchWidgets } from '../stores/roles/rolesSlice'

type DashboardEntityCard = {
  entity: string
  label: string
  description: string
  href: string
  permission: string
  iconPath: string
}

type DashboardSection = {
  title: string
  eyebrow: string
  description: string
  cards: DashboardEntityCard[]
}

type DashboardRoleConfig = {
  pageTitle: string
  eyebrow: string
  description: string
  primaryAction: {
    href: string
    label: string
  }
  secondaryAction: {
    href: string
    label: string
  }
  sections: DashboardSection[]
}

const DASHBOARD_CONFIG_BY_ROLE: Record<string, DashboardRoleConfig> = {
  'Super Administrator': {
    pageTitle: 'Platform Widgets',
    eyebrow: 'Super Administrator widget surface',
    description:
      'Review the platform through a governance lens: tenants, users, roles, permissions, workflow configuration, and audit visibility.',
    primaryAction: {
      href: '/organizations/organizations-list',
      label: 'Review organizations',
    },
    secondaryAction: {
      href: '/executive-summary',
      label: 'Open workspace',
    },
    sections: [
      {
        title: 'Platform governance',
        eyebrow: 'Control surface',
        description: 'The structural entities that shape tenants, users, and role design across the platform.',
        cards: [
          {
            entity: 'organizations',
            label: 'Organizations',
            description: 'Track tenant coverage and ownership.',
            href: '/organizations/organizations-list',
            permission: 'READ_ORGANIZATIONS',
            iconPath: icon.mdiDomain,
          },
          {
            entity: 'users',
            label: 'Users',
            description: 'Inspect who can access the platform.',
            href: '/users/users-list',
            permission: 'READ_USERS',
            iconPath: icon.mdiAccountGroup,
          },
          {
            entity: 'roles',
            label: 'Roles',
            description: 'Review responsibility boundaries.',
            href: '/roles/roles-list',
            permission: 'READ_ROLES',
            iconPath: icon.mdiShieldAccountVariantOutline,
          },
          {
            entity: 'permissions',
            label: 'Permissions',
            description: 'Validate the permission catalogue.',
            href: '/permissions/permissions-list',
            permission: 'READ_PERMISSIONS',
            iconPath: icon.mdiShieldAccountOutline,
          },
          {
            entity: 'role_permissions',
            label: 'Role permissions',
            description: 'Inspect how permissions map to roles.',
            href: '/role_permissions/role_permissions-list',
            permission: 'READ_ROLE_PERMISSIONS',
            iconPath: icon.mdiLinkVariant,
          },
        ],
      },
      {
        title: 'Workflow and observability',
        eyebrow: 'Readiness and traceability',
        description: 'Templates, notices, and audit trails that help supervise tenant readiness without owning operational workflows.',
        cards: [
          {
            entity: 'approval_workflows',
            label: 'Approval workflows',
            description: 'Monitor routing templates and approvals design.',
            href: '/approval_workflows/approval_workflows-list',
            permission: 'READ_APPROVAL_WORKFLOWS',
            iconPath: icon.mdiSitemap,
          },
          {
            entity: 'approval_steps',
            label: 'Approval steps',
            description: 'Check stage definitions and progression rules.',
            href: '/approval_steps/approval_steps-list',
            permission: 'READ_APPROVAL_STEPS',
            iconPath: icon.mdiStairs,
          },
          {
            entity: 'notifications',
            label: 'Notifications',
            description: 'Review platform-wide message flow.',
            href: '/notifications/notifications-list',
            permission: 'READ_NOTIFICATIONS',
            iconPath: icon.mdiBellOutline,
          },
          {
            entity: 'audit_logs',
            label: 'Audit logs',
            description: 'Investigate system activity and changes.',
            href: '/audit_logs/audit_logs-list',
            permission: 'READ_AUDIT_LOGS',
            iconPath: icon.mdiClipboardTextClock,
          },
        ],
      },
    ],
  },
  Administrator: {
    pageTitle: 'Operations Widgets',
    eyebrow: 'Administrator operations surface',
    description:
      'Keep the organization ready to operate by focusing on users, master data, approval routing, administrative notices, and records assurance.',
    primaryAction: {
      href: '/approval_workflows/approval_workflows-list',
      label: 'Review workflow setup',
    },
    secondaryAction: {
      href: '/executive-summary',
      label: 'Open workspace',
    },
    sections: [
      {
        title: 'Organization setup',
        eyebrow: 'People and reference records',
        description: 'The administrative entities that keep the organization usable, searchable, and ready for day-to-day work.',
        cards: [
          {
            entity: 'users',
            label: 'Users',
            description: 'Support staff access and account readiness.',
            href: '/users/users-list',
            permission: 'READ_USERS',
            iconPath: icon.mdiAccountGroup,
          },
          {
            entity: 'provinces',
            label: 'Provinces',
            description: 'Maintain the delivery geography master list.',
            href: '/provinces/provinces-list',
            permission: 'READ_PROVINCES',
            iconPath: icon.mdiMapMarker,
          },
          {
            entity: 'departments',
            label: 'Departments',
            description: 'Keep internal organization structure aligned.',
            href: '/departments/departments-list',
            permission: 'READ_DEPARTMENTS',
            iconPath: icon.mdiOfficeBuilding,
          },
          {
            entity: 'documents',
            label: 'Documents',
            description: 'Review supporting records and shared files.',
            href: '/documents/documents-list',
            permission: 'READ_DOCUMENTS',
            iconPath: icon.mdiFolderFile,
          },
        ],
      },
      {
        title: 'Workflow control',
        eyebrow: 'Routing and follow-through',
        description: 'The operating controls that help the Administrator keep approvals, notifications, and control exceptions from drifting.',
        cards: [
          {
            entity: 'approval_workflows',
            label: 'Approval workflows',
            description: 'Inspect routing patterns and gaps.',
            href: '/approval_workflows/approval_workflows-list',
            permission: 'READ_APPROVAL_WORKFLOWS',
            iconPath: icon.mdiSitemap,
          },
          {
            entity: 'approval_steps',
            label: 'Approval steps',
            description: 'Maintain stage definitions and owners.',
            href: '/approval_steps/approval_steps-list',
            permission: 'READ_APPROVAL_STEPS',
            iconPath: icon.mdiStairs,
          },
          {
            entity: 'approvals',
            label: 'Approvals',
            description: 'Review the active approval queue.',
            href: '/approvals/approvals-list',
            permission: 'READ_APPROVALS',
            iconPath: icon.mdiChecklist,
          },
          {
            entity: 'role_permissions',
            label: 'Role access',
            description: 'Check whether access design matches responsibility.',
            href: '/role_permissions/role_permissions-list',
            permission: 'READ_ROLE_PERMISSIONS',
            iconPath: icon.mdiLinkVariant,
          },
          {
            entity: 'notifications',
            label: 'Notifications',
            description: 'Track operational signals requiring follow-up.',
            href: '/notifications/notifications-list',
            permission: 'READ_NOTIFICATIONS',
            iconPath: icon.mdiBellOutline,
          },
          {
            entity: 'audit_logs',
            label: 'Audit logs',
            description: 'Investigate who changed what and when.',
            href: '/audit_logs/audit_logs-list',
            permission: 'READ_AUDIT_LOGS',
            iconPath: icon.mdiClipboardTextClock,
          },
          {
            entity: 'compliance_alerts',
            label: 'Compliance alerts',
            description: 'Spot records that need administrative intervention.',
            href: '/compliance_alerts/compliance_alerts-list',
            permission: 'READ_COMPLIANCE_ALERTS',
            iconPath: icon.mdiShieldAlertOutline,
          },
        ],
      },
    ],
  },
}

const SectionHeader = ({
  eyebrow,
  title,
  description,
  action,
}: {
  eyebrow: string
  title: string
  description?: string
  action?: React.ReactNode
}) => (
  <div className='mb-4 flex flex-col gap-3 border-b border-slate-200 pb-4 md:flex-row md:items-end md:justify-between dark:border-slate-800'>
    <div>
      <p className='text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400'>{eyebrow}</p>
      <h2 className='mt-1 text-xl font-semibold text-slate-900 dark:text-white'>{title}</h2>
      {description ? <p className='mt-2 max-w-3xl text-sm text-slate-500 dark:text-slate-400'>{description}</p> : null}
    </div>
    {action}
  </div>
)

const DashboardCard = ({
  label,
  description,
  count,
  href,
  iconPath,
}: DashboardEntityCard & { count: number | string | null }) => {
  const numericCount = typeof count === 'number'
  const displayValue = count === null ? '—' : count

  return (
    <Link href={href} className='group block h-full'>
      <CardBox className='h-full border border-slate-200 bg-white/90 shadow-sm transition-all duration-150 group-hover:-translate-y-0.5 group-hover:border-slate-300 group-hover:shadow-md dark:border-slate-800 dark:bg-slate-900 dark:group-hover:border-slate-700'>
        <div className='flex h-full flex-col justify-between gap-6'>
          <div className='flex items-start justify-between gap-4'>
            <div>
              <p className='text-sm font-semibold text-slate-900 dark:text-white'>{label}</p>
              <p className='mt-2 text-sm leading-6 text-slate-500 dark:text-slate-400'>{description}</p>
            </div>
            <div className='flex h-11 w-11 items-center justify-center rounded-2xl border border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-200'>
              <BaseIcon path={iconPath} size={20} />
            </div>
          </div>
          <div className='flex items-end justify-between gap-4'>
            <div>
              <p className='text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400'>Current records</p>
              <p className='mt-2 text-3xl font-semibold text-slate-950 dark:text-white'>{displayValue}</p>
            </div>
            <span className={`rounded-full px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] ${numericCount ? 'bg-emerald-50 text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-300' : 'bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-300'}`}>
              {numericCount ? 'Live' : 'Unavailable'}
            </span>
          </div>
        </div>
      </CardBox>
    </Link>
  )
}

const Dashboard = () => {
  const dispatch = useAppDispatch()
  const router = useRouter()
  const { currentUser } = useAppSelector((state) => state.auth)
  const { isFetchingQuery } = useAppSelector((state) => state.openAi)
  const { rolesWidgets, loading } = useAppSelector((state) => state.roles)

  const roleName = currentUser?.app_role?.name || ''
  const dashboardAllowed = isDashboardRole(roleName)
  const workspaceRoute = getWorkspaceRoute(roleName)
  const dashboardConfig = DASHBOARD_CONFIG_BY_ROLE[roleName] || DASHBOARD_CONFIG_BY_ROLE.Administrator
  const availableSections = React.useMemo(
    () =>
      dashboardConfig.sections
        .map((section) => ({
          ...section,
          cards: section.cards.filter((card) => hasPermission(currentUser, card.permission)),
        }))
        .filter((section) => section.cards.length > 0),
    [currentUser, dashboardConfig],
  )

  const [entityCounts, setEntityCounts] = React.useState<Record<string, number | string | null>>({})
  const [loadError, setLoadError] = React.useState('')
  const [widgetsRole, setWidgetsRole] = React.useState({
    role: { value: '', label: '' },
  })

  const totalVisibleEntities = availableSections.reduce((sum, section) => sum + section.cards.length, 0)
  const totalLoadedRecords = Object.values(entityCounts).reduce((sum, value) => {
    if (typeof value === 'number') {
      return sum + value
    }

    return sum
  }, 0)

  React.useEffect(() => {
    if (!currentUser?.id || dashboardAllowed) return

    router.replace(workspaceRoute)
  }, [currentUser?.id, dashboardAllowed, router, workspaceRoute])

  React.useEffect(() => {
    if (!currentUser?.app_role?.id) return

    setWidgetsRole({
      role: {
        value: currentUser.app_role.id,
        label: currentUser.app_role.name,
      },
    })
  }, [currentUser?.app_role?.id, currentUser?.app_role?.name])

  React.useEffect(() => {
    if (!widgetsRole?.role?.value) return

    dispatch(fetchWidgets(widgetsRole.role.value))
  }, [dispatch, widgetsRole?.role?.value])

  React.useEffect(() => {
    if (!currentUser || !dashboardAllowed) return

    let mounted = true

    const loadCounts = async () => {
      try {
        setLoadError('')

        const cards = availableSections.flatMap((section) => section.cards)
        const requests = cards.map((card) => axios.get(`/${card.entity}/count`))
        const results = await Promise.allSettled(requests)
        const nextCounts: Record<string, number | string | null> = {}

        results.forEach((result, index) => {
          const card = cards[index]

          if (result.status === 'fulfilled') {
            nextCounts[card.entity] = result.value.data.count
            return
          }

          console.error(`Failed to load ${card.entity} count`, result.reason)
          nextCounts[card.entity] = 'Error'
        })

        if (mounted) {
          setEntityCounts(nextCounts)
        }
      } catch (error: any) {
        console.error('Failed to load dashboard counts', error)

        if (mounted) {
          setLoadError(error?.response?.data?.message || 'Unable to load dashboard counts right now.')
        }
      }
    }

    loadCounts()

    return () => {
      mounted = false
    }
  }, [availableSections, currentUser, dashboardAllowed])

  if (currentUser?.id && !dashboardAllowed) {
    return (
      <SectionMain>
        <CardBox className='border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-900'>
          <div className='flex flex-col gap-2'>
            <p className='text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400'>Role workspace redirect</p>
            <h2 className='text-xl font-semibold text-slate-900 dark:text-white'>This dashboard is reserved for Super Administrators and Administrators.</h2>
            <p className='text-sm text-slate-600 dark:text-slate-300'>Redirecting you to your role workspace now.</p>
            <div>
              <Link href={workspaceRoute} className='text-sm font-medium text-blue-700 dark:text-sky-400'>Go to workspace now</Link>
            </div>
          </div>
        </CardBox>
      </SectionMain>
    )
  }

  return (
    <>
      <Head>
        <title>{getPageTitle(dashboardConfig.pageTitle)}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={icon.mdiChartTimelineVariant} title={dashboardConfig.pageTitle} main>
          <BaseButtons>
            <BaseButton href={dashboardConfig.primaryAction.href} color='info' label={dashboardConfig.primaryAction.label} icon={icon.mdiArrowTopRight} />
            <BaseButton href={dashboardConfig.secondaryAction.href} color='whiteDark' label={dashboardConfig.secondaryAction.label} />
          </BaseButtons>
        </SectionTitleLineWithButton>

        <CardBox className='mb-6 overflow-hidden border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900'>
          <div className='grid gap-6 lg:grid-cols-[1.6fr,1fr]'>
            <div>
              <p className='text-xs font-semibold uppercase tracking-[0.24em] text-slate-500 dark:text-slate-400'>{dashboardConfig.eyebrow}</p>
              <h2 className='mt-3 text-3xl font-semibold tracking-tight text-slate-900 dark:text-white'>{dashboardConfig.pageTitle}</h2>
              <p className='mt-4 max-w-3xl text-sm leading-6 text-slate-600 dark:text-slate-300'>{dashboardConfig.description}</p>
              <div className='mt-6 grid gap-3 sm:grid-cols-3'>
                <div className='rounded-xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-800/70'>
                  <p className='text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400'>Visible entity cards</p>
                  <p className='mt-2 text-2xl font-semibold text-slate-950 dark:text-white'>{totalVisibleEntities}</p>
                  <p className='mt-2 text-xs text-slate-500 dark:text-slate-400'>Only role-approved modules are surfaced here.</p>
                </div>
                <div className='rounded-xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-800/70'>
                  <p className='text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400'>Records represented</p>
                  <p className='mt-2 text-2xl font-semibold text-slate-950 dark:text-white'>{totalLoadedRecords}</p>
                  <p className='mt-2 text-xs text-slate-500 dark:text-slate-400'>Combined count across the visible control surface.</p>
                </div>
                <div className='rounded-xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-800/70'>
                  <p className='text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400'>Saved widgets</p>
                  <p className='mt-2 text-2xl font-semibold text-slate-950 dark:text-white'>{rolesWidgets.length}</p>
                  <p className='mt-2 text-xs text-slate-500 dark:text-slate-400'>Role-specific widgets remain available below.</p>
                </div>
              </div>
            </div>

            <div className='grid gap-4'>
              <div className='rounded-xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-800/70'>
                <p className='text-xs uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400'>Current operator</p>
                <p className='mt-2 text-lg font-semibold text-slate-950 dark:text-white'>
                  {currentUser?.firstName || currentUser?.email || 'Authenticated user'}
                </p>
                <p className='mt-1 text-sm text-slate-500 dark:text-slate-400'>{roleName || 'Operational access'}</p>
              </div>
              <div className='rounded-xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-800/70'>
                <p className='text-xs uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400'>Dashboard intent</p>
                <p className='mt-2 text-sm leading-6 text-slate-600 dark:text-slate-300'>
                  This page is now a focused control surface instead of a generic entity dump. If a module does not belong to this role, it stays out of view.
                </p>
              </div>
              <div className='rounded-xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-800/70'>
                <p className='text-xs uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400'>Next best action</p>
                <Link href={dashboardConfig.primaryAction.href} className='mt-2 inline-flex items-center gap-2 text-sm font-semibold text-blue-700 transition hover:text-slate-950 dark:text-sky-400 dark:hover:text-white'>
                  {dashboardConfig.primaryAction.label}
                  <BaseIcon path={icon.mdiArrowTopRight} size={16} />
                </Link>
              </div>
            </div>
          </div>
        </CardBox>

        {loadError ? <NotificationBar color='danger'>{loadError}</NotificationBar> : null}

        <CardBox className='mb-6 border border-slate-200 bg-white/90 shadow-sm dark:border-slate-800 dark:bg-slate-900'>
          <SectionHeader
            eyebrow='Role widgets'
            title={`${widgetsRole?.role?.label || roleName || 'Current role'} widgets`}
            description='Continue using AI-configured widgets, but keep them inside a cleaner role-specific shell.'
            action={
              hasPermission(currentUser, 'CREATE_ROLES') ? (
                <span className='rounded-full bg-blue-50 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-blue-700 dark:bg-blue-950/40 dark:text-blue-300'>
                  Widget editing enabled
                </span>
              ) : null
            }
          />

          {hasPermission(currentUser, 'CREATE_ROLES') ? (
            <WidgetCreator
              currentUser={currentUser}
              isFetchingQuery={isFetchingQuery}
              setWidgetsRole={setWidgetsRole}
              widgetsRole={widgetsRole}
            />
          ) : null}

          <div className='mt-6 grid grid-cols-1 gap-6 lg:grid-cols-4'>
            {(isFetchingQuery || loading) && (
              <div className='flex items-center gap-4 rounded-2xl border border-slate-200 bg-slate-50 p-6 text-slate-600 dark:border-slate-800 dark:bg-slate-800 dark:text-slate-300'>
                <BaseIcon className='animate-spin text-blue-600 dark:text-sky-400' w='w-10' h='h-10' size={32} path={icon.mdiLoading} />
                <div>
                  <p className='font-semibold'>Loading widgets…</p>
                  <p className='text-sm'>Refreshing saved role insights.</p>
                </div>
              </div>
            )}

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

            {!rolesWidgets.length && !(isFetchingQuery || loading) ? (
              <div className='lg:col-span-4'>
                <div className='rounded-2xl border border-dashed border-slate-300 bg-slate-50/80 p-6 text-sm text-slate-600 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300'>
                  No widgets are saved for this role yet. Use the widget creator to add focused insights, or continue with the curated entity sections below.
                </div>
              </div>
            ) : null}
          </div>
        </CardBox>

        <div className='space-y-6'>
          {availableSections.map((section) => (
            <CardBox key={section.title} className='border border-slate-200 bg-white/90 shadow-sm dark:border-slate-800 dark:bg-slate-900'>
              <SectionHeader eyebrow={section.eyebrow} title={section.title} description={section.description} />
              <div className='grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3'>
                {section.cards.map((card) => (
                  <DashboardCard
                    key={card.entity}
                    {...card}
                    count={Object.prototype.hasOwnProperty.call(entityCounts, card.entity) ? entityCounts[card.entity] : 'Loading…'}
                  />
                ))}
              </div>
            </CardBox>
          ))}
        </div>
      </SectionMain>
    </>
  )
}

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

export default Dashboard
