import { VillageActivityLineChart, VillageComparisonBarChart } from '@/frontend/components/DashboardCharts'
import { ErrorDataTable, type ErrorDataTableHandle } from '@/frontend/components/ErrorDataTable'
import { SummaryCard } from '@/frontend/components/SummaryCard'
import { useSession } from '@/frontend/hooks/useAuth'
import {
  ActionIcon,
  Badge,
  Button,
  Group,
  Modal,
  SimpleGrid,
  Stack,
  Switch,
  Text,
  Textarea,
  TextInput,
  Title,
  Tooltip,
} from '@mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { notifications } from '@mantine/notifications'
import { createFileRoute, useNavigate, useParams } from '@tanstack/react-router'
import { useEffect, useRef, useState } from 'react'
import {
  TbActivity,
  TbAlertTriangle,
  TbBuildingCommunity,
  TbRefresh,
  TbVersions,
} from 'react-icons/tb'
import useSWR from 'swr'
import { API_URLS } from '../config/api'

export const Route = createFileRoute('/apps/$appId/')({
  component: AppOverviewPage,
})

const fetcher = (url: string) => fetch(url).then((res) => res.json())

function AppOverviewPage() {
  const { appId } = useParams({ from: '/apps/$appId/' })
  const navigate = useNavigate()
  const isDesaPlus = appId === 'desa-plus'
  const [versionModalOpened, { open: openVersionModal, close: closeVersionModal }] = useDisclosure(false)
  const { data: session } = useSession()
  const isDeveloper = session?.user?.role === 'DEVELOPER'
  const errorTableRef = useRef<ErrorDataTableHandle>(null)

  const [latestVersion, setLatestVersion] = useState('')
  const [minVersion, setMinVersion] = useState('')
  const [messageUpdate, setMessageUpdate] = useState('')
  const [maintenance, setMaintenance] = useState(false)
  const [isSaving, setIsSaving] = useState(false)

  const [dailyRange, setDailyRange] = useState<7 | 30 | 90>(7)
  const [comparisonRange, setComparisonRange] = useState<7 | 30 | 90>(7)

  const { data: gridRes, isLoading: gridLoading, mutate: mutateGrid } = useSWR(isDesaPlus ? API_URLS.getGridOverview() : null, fetcher)
  const { data: dailyRes, isLoading: dailyLoading, mutate: mutateDaily } = useSWR(isDesaPlus ? API_URLS.getDailyActivity(dailyRange) : null, fetcher)
  const { data: comparisonRes, isLoading: comparisonLoading, mutate: mutateComparison } = useSWR(isDesaPlus ? API_URLS.getComparisonActivity(comparisonRange) : null, fetcher)

  const { data: appData, isLoading: appLoading } = useSWR(`/api/apps/${appId}`, fetcher)

  const grid = gridRes?.data
  const dailyData = dailyRes?.data || []
  const comparisonData = comparisonRes?.data || []

  // Ref so the modal-sync effect always reads current grid without re-running on every background refetch
  const gridRef = useRef(grid)
  gridRef.current = grid

  useEffect(() => {
    if (versionModalOpened && gridRef.current?.version) {
      const v = gridRef.current.version
      setLatestVersion(v.mobile_latest_version || '')
      setMinVersion(v.mobile_minimum_version || '')
      setMessageUpdate(v.mobile_message_update || '')
      setMaintenance(v.mobile_maintenance === 'true')
    }
  }, [versionModalOpened])

  const handleRefresh = () => {
    mutateGrid()
    mutateDaily()
    mutateComparison()
    errorTableRef.current?.refresh()
  }

  const handleSaveVersion = async () => {
    setIsSaving(true)
    try {
      const response = await fetch(API_URLS.postVersionUpdate(), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          mobile_latest_version: latestVersion,
          mobile_minimum_version: minVersion,
          mobile_maintenance: maintenance,
          mobile_message_update: messageUpdate,
        }),
      })

      if (response.ok) {
        await fetch(API_URLS.createLog(), {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: 'UPDATE', message: `Updated version info: latest=${latestVersion}, min=${minVersion}, maintenance=${maintenance}` }),
        }).catch(console.error)

        notifications.show({ title: 'Updated', message: 'Application version information has been saved.', color: 'teal' })
        mutateGrid()
        closeVersionModal()
      } else {
        notifications.show({ title: 'Failed', message: 'Could not update version info. Please try again.', color: 'red' })
      }
    } catch {
      notifications.show({ title: 'Network Error', message: 'Could not connect to the server.', color: 'red' })
    } finally {
      setIsSaving(false)
    }
  }

  const maintenanceOn = grid?.version?.mobile_maintenance === 'true'

  return (
    <>
      <Modal
        opened={versionModalOpened}
        onClose={closeVersionModal}
        title={<Text fw={700} size="lg">Update Version Info</Text>}
        radius="xl"
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="md">
          <TextInput
            label="Active Version"
            placeholder="e.g. 2.0.5"
            value={latestVersion}
            onChange={(e) => setLatestVersion(e.currentTarget.value)}
          />
          <TextInput
            label="Minimum Version"
            placeholder="e.g. 2.0.0"
            value={minVersion}
            onChange={(e) => setMinVersion(e.currentTarget.value)}
          />
          <Textarea
            label="Update Message"
            placeholder="Enter release notes or update message..."
            value={messageUpdate}
            onChange={(e) => setMessageUpdate(e.currentTarget.value)}
            minRows={3}
            autosize
          />
          <Switch
            label="Maintenance Mode"
            description="Enable to put the app in maintenance mode for users."
            checked={maintenance}
            onChange={(e) => setMaintenance(e.currentTarget.checked)}
          />
          <Button
            fullWidth
            mt="md"
            variant="gradient"
            gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
            onClick={handleSaveVersion}
            loading={isSaving}
          >
            Save Changes
          </Button>
        </Stack>
      </Modal>

      <Stack gap="xl">
        <Group justify="space-between" align="flex-start">
          <Stack gap={4}>
            <Title order={3}>Overview</Title>
            <Text size="sm" c="dimmed">
              Real-time metrics and activity for {isDesaPlus ? 'Desa+' : appId}.
            </Text>
          </Stack>
          <Tooltip label="Refresh data" withArrow>
            <ActionIcon
              variant="light"
              color="brand-blue"
              size="lg"
              radius="md"
              onClick={handleRefresh}
              loading={gridLoading || dailyLoading || comparisonLoading}
            >
              <TbRefresh size={18} />
            </ActionIcon>
          </Tooltip>
        </Group>

        <SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg">
          <SummaryCard
            title="Active Version"
            value={gridLoading ? '...' : (grid?.version?.mobile_latest_version || 'N/A')}
            icon={TbVersions}
            color="brand-blue"
            onClick={isDeveloper ? openVersionModal : undefined}
          >
            <Group justify="space-between" mt="md">
              <Stack gap={0}>
                <Text size="xs" c="dimmed">Min. Version</Text>
                <Text size="sm" fw={600}>{grid?.version?.mobile_minimum_version || '—'}</Text>
              </Stack>
              <Stack gap={0} align="flex-end">
                <Text size="xs" c="dimmed">Maintenance</Text>
                <Badge size="sm" color={maintenanceOn ? 'orange' : 'teal'} variant="light">
                  {maintenanceOn ? 'On' : 'Off'}
                </Badge>
              </Stack>
            </Group>
          </SummaryCard>

          <SummaryCard
            title="Total Activity Today"
            value={gridLoading ? '...' : (grid?.activity?.today?.toLocaleString() ?? '0')}
            icon={TbActivity}
            color="teal"
            trend={grid?.activity?.increase != null && Number(grid.activity.increase) !== 0
              ? { value: `${grid.activity.increase}%`, positive: Number(grid.activity.increase) > 0 }
              : undefined}
          />

          <SummaryCard
            title="Active Villages"
            value={gridLoading ? '...' : (grid?.village?.active ?? '0')}
            icon={TbBuildingCommunity}
            color="indigo"
            onClick={() => navigate({ to: `/apps/${appId}/villages` })}
          >
            <Group justify="space-between" mt="md">
              <Text size="xs" c="dimmed">Inactive</Text>
              <Badge size="sm" color="red" variant="light">{grid?.village?.inactive ?? 0}</Badge>
            </Group>
          </SummaryCard>

          <SummaryCard
            title="Open Errors"
            value={appLoading ? '...' : (appData?.errors ?? 0)}
            icon={TbAlertTriangle}
            color="red"
            isError
            onClick={() => navigate({ to: `/apps/${appId}/errors` })}
          />
        </SimpleGrid>

        <Group justify="space-between" align="flex-end">
          <Stack gap={2}>
            <Title order={4}>Analytics</Title>
            <Text size="sm" c="dimmed">Activity trends and village comparisons.</Text>
          </Stack>
        </Group>

        <SimpleGrid cols={{ base: 1, lg: 2 }} spacing="lg">
          <VillageActivityLineChart data={dailyData} isLoading={dailyLoading} range={dailyRange} onRangeChange={setDailyRange} />
          <VillageComparisonBarChart data={comparisonData} isLoading={comparisonLoading} range={comparisonRange} onRangeChange={setComparisonRange} />
        </SimpleGrid>

        <ErrorDataTable ref={errorTableRef} appId={appId} />
      </Stack>
    </>
  )
}
