import {
  ActionIcon,
  Avatar,
  Badge,
  Box,
  Button,
  Container,
  Divider,
  Group,
  Modal,
  Pagination,
  Paper,
  ScrollArea,
  Select,
  SimpleGrid,
  Stack,
  Table,
  Text,
  TextInput,
  ThemeIcon,
  Title,
  Switch,
} from '@mantine/core'
import { useDisclosure, useMediaQuery } from '@mantine/hooks'
import { notifications } from '@mantine/notifications'
import { createFileRoute, useParams } from '@tanstack/react-router'
import { useState } from 'react'
import {
  TbBriefcase,
  TbCircleCheck,
  TbCircleX,
  TbEdit,
  TbHome2,
  TbId,
  TbMail,
  TbPhone,
  TbPlus,
  TbSearch,
  TbUsers,
  TbX,
} from 'react-icons/tb'
import useSWR from 'swr'
import { API_URLS } from '../config/api'

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

interface APIUser {
  id: string
  name: string
  nik: string
  phone: string
  email: string
  gender: string
  isWithoutOTP: boolean
  isActive: boolean
  role: string
  village: string
  group: string
  position?: string
  idUserRole: string
  idVillage: string
  idGroup: string
  idPosition: string
}

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

function UsersIndexPage() {
  const { appId } = useParams({ from: '/apps/$appId/users/' })
  const [page, setPage] = useState(1)
  const [search, setSearch] = useState('')
  const [searchQuery, setSearchQuery] = useState('')

  const isDesaPlus = appId === 'desa-plus'
  const apiUrl = isDesaPlus ? API_URLS.getUsers(page, searchQuery) : null

  const { data: response, error, isLoading, mutate } = useSWR(apiUrl, fetcher)
  const users: APIUser[] = response?.data?.user || []

  const handleSearchChange = (val: string) => {
    setSearch(val)
    if (val.length >= 3 || val.length === 0) {
      setSearchQuery(val)
      setPage(1)
    }
  }

  // --- ADD USER LOGIC ---
  const [opened, { open, close }] = useDisclosure(false)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [villageSearch, setVillageSearch] = useState('')
  const [form, setForm] = useState({
    name: '',
    nik: '',
    phone: '',
    email: '',
    gender: '',
    idUserRole: '',
    idVillage: '',
    idGroup: '',
    idPosition: ''
  })

  const [editOpened, { open: openEdit, close: closeEdit }] = useDisclosure(false)
  const [editForm, setEditForm] = useState({
    id: '',
    name: '',
    nik: '',
    phone: '',
    email: '',
    gender: '',
    idUserRole: '',
    idVillage: '',
    idGroup: '',
    idPosition: '',
    isActive: true,
    isWithoutOTP: false
  })

  // Options Data (Shared for both Add and Edit modals)
  const isAnyModalOpened = opened || editOpened
  const targetVillageId = opened ? form.idVillage : editForm.idVillage
  const targetGroupId = opened ? form.idGroup : editForm.idGroup

  const { data: rolesResp } = useSWR(isAnyModalOpened ? API_URLS.listRole() : null, fetcher)
  const { data: villagesResp } = useSWR(
    isAnyModalOpened && villageSearch.length >= 1 ? API_URLS.getVillages(1, villageSearch) : null,
    fetcher
  )
  const { data: groupsResp } = useSWR(
    isAnyModalOpened && targetVillageId ? API_URLS.listGroup(targetVillageId) : null,
    fetcher
  )
  const { data: positionsResp } = useSWR(
    isAnyModalOpened && targetGroupId ? API_URLS.listPosition(targetGroupId) : null,
    fetcher
  )

  const rolesOptions = (rolesResp?.data || []).map((r: any) => ({ value: r.id, label: r.name }))
  const villagesOptions = (villagesResp?.data || []).map((v: any) => ({ value: v.id, label: v.name }))
  const groupsOptions = (groupsResp?.data || []).map((g: any) => ({ value: g.id, label: g.name }))
  const positionsOptions = (positionsResp?.data || []).map((p: any) => ({ value: p.id, label: p.name }))

  const handleCreateUser = async () => {
    const requiredFields = ['name', 'nik', 'phone', 'email', 'gender', 'idUserRole', 'idVillage', 'idGroup']
    const missing = requiredFields.filter(f => !form[f as keyof typeof form])

    if (missing.length > 0) {
      notifications.show({
        title: 'Validation Error',
        message: `Please fill in all required fields: ${missing.join(', ')}`,
        color: 'red'
      })
      return
    }

    setIsSubmitting(true)
    try {
      const res = await fetch(API_URLS.createUser(), {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(form)
      })

      const result = await res.json()

      if (result.success) {
        await fetch(API_URLS.createLog(), {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: 'CREATE', message: `Didaftarkan user (${appId}) baru: ${form.name}-${form.nik}` })
        }).catch(console.error)

        notifications.show({
          title: 'Success',
          message: 'User has been created successfully.',
          color: 'teal',
          icon: <TbCircleCheck size={18} />
        })
        mutate() // Refresh user list
        close()
        setForm({
          name: '',
          nik: '',
          phone: '',
          email: '',
          gender: '',
          idUserRole: '',
          idVillage: '',
          idGroup: '',
          idPosition: ''
        })
      } else {
        notifications.show({
          title: 'Error',
          message: result.message || 'Failed to create user.',
          color: 'red',
          icon: <TbCircleX size={18} />
        })
      }
    } catch (e) {
      notifications.show({
        title: 'Network Error',
        message: 'Unable to connect to the server.',
        color: 'red'
      })
    } finally {
      setIsSubmitting(false)
    }
  }

  const handleEditOpen = (user: APIUser) => {
    setEditForm({
      id: user.id,
      name: user.name,
      nik: user.nik,
      phone: user.phone,
      email: user.email,
      gender: user.gender,
      idUserRole: user.idUserRole,
      idVillage: user.idVillage,
      idGroup: user.idGroup,
      idPosition: user.idPosition,
      isActive: user.isActive,
      isWithoutOTP: user.isWithoutOTP
    })
    setVillageSearch(user.village)
    openEdit()
  }

  const handleUpdateUser = async () => {
    const requiredFields = ['name', 'nik', 'phone', 'email', 'gender', 'idUserRole', 'idVillage', 'idGroup']
    const missing = requiredFields.filter(f => !editForm[f as keyof typeof editForm])

    if (missing.length > 0) {
      notifications.show({
        title: 'Validation Error',
        message: `Please fill in all required fields: ${missing.join(', ')}`,
        color: 'red'
      })
      return
    }

    setIsSubmitting(true)
    try {
      const res = await fetch(API_URLS.editUser(), {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(editForm)
      })

      const result = await res.json()

      if (result.success) {
        await fetch(API_URLS.createLog(), {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: 'UPDATE', message: `Data user (${appId}) diperbarui: ${editForm.name}-${editForm.id}` })
        }).catch(console.error)

        notifications.show({
          title: 'Success',
          message: 'User has been updated successfully.',
          color: 'teal',
          icon: <TbCircleCheck size={18} />
        })
        mutate()
        closeEdit()
      } else {
        notifications.show({
          title: 'Error',
          message: result.message || 'Failed to update user.',
          color: 'red',
          icon: <TbCircleX size={18} />
        })
      }
    } catch (e) {
      notifications.show({
        title: 'Network Error',
        message: 'Unable to connect to the server.',
        color: 'red'
      })
    } finally {
      setIsSubmitting(false)
    }
  }

  const handleClearSearch = () => {
    setSearch('')
    setSearchQuery('')
    setPage(1)
  }

  const getRoleColor = (role: string) => {
    const r = role.toLowerCase()
    if (r.includes('super')) return 'red'
    if (r.includes('admin')) return 'brand-blue'
    if (r.includes('developer')) return 'violet'
    return 'gray'
  }

  const isMobile = useMediaQuery('(max-width: 768px)')

  if (!isDesaPlus) {
    return (
      <Container size="xl" py="xl">
        <Paper p="xl" radius="xl" className="glass" style={{ textAlign: 'center' }}>
          <TbUsers size={48} color="gray" opacity={0.5} />
          <Title order={3} mt="md">User Management</Title>
          <Text c="dimmed">This feature is currently customized for Desa+. Other apps coming soon.</Text>
        </Paper>
      </Container>
    )
  }

  return (
    <Stack gap="xl" py="md">
      <Paper withBorder radius="2xl" p="xl" className="glass" style={{ borderLeft: '6px solid #2563EB' }}>
        <Stack gap="lg">
          <Group justify="space-between" align="center">
            <Stack gap={4}>
              <Group gap="xs">
                <ThemeIcon variant="light" color="brand-blue" size="lg" radius="md">
                  <TbUsers size={22} />
                </ThemeIcon>
                <Title order={3}>User Management</Title>
              </Group>
              <Text size="sm" c="dimmed" ml={40}>
                {isLoading ? 'Loading users...' : `${response?.data?.total || 0} users registered in the Desa+ system`}
              </Text>
            </Stack>
            <Button
              variant="gradient"
              gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
              leftSection={<TbPlus size={18} />}
              radius="md"
              size="md"
              onClick={open}
            >
              Add User
            </Button>
          </Group>

          <Modal
            opened={opened}
            onClose={close}
            title={<Text fw={700} size="lg">Add New User</Text>}
            radius="xl"
            size="lg"
            overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
          >
            <Stack gap="md">
              <Box>
                <Text size="xs" fw={700} c="dimmed" mb={8} style={{ textTransform: 'uppercase', letterSpacing: '0.05em' }}>
                  Personal Information
                </Text>
                <SimpleGrid cols={2} spacing="md">
                  <TextInput
                    label="Full Name"
                    placeholder="Enter full name"
                    required
                    value={form.name}
                    onChange={(e) => setForm(f => ({ ...f, name: e.target.value }))}
                  />
                  <TextInput
                    label="NIK"
                    placeholder="16-digit identity number"
                    required
                    value={form.nik}
                    onChange={(e) => setForm(f => ({ ...f, nik: e.target.value }))}
                  />
                </SimpleGrid>

                <SimpleGrid cols={2} spacing="md" mt="sm">
                  <TextInput
                    label="Email Address"
                    placeholder="email@example.com"
                    required
                    value={form.email}
                    onChange={(e) => setForm(f => ({ ...f, email: e.target.value }))}
                  />
                  <TextInput
                    label="Phone Number"
                    placeholder="628xxxxxxxxxx"
                    required
                    value={form.phone}
                    onChange={(e) => setForm(f => ({ ...f, phone: e.target.value }))}
                  />
                </SimpleGrid>

                <Select
                  label="Gender"
                  placeholder="Select gender"
                  data={[
                    { value: 'M', label: 'Male' },
                    { value: 'F', label: 'Female' },
                  ]}
                  mt="sm"
                  required
                  value={form.gender}
                  onChange={(v) => setForm(f => ({ ...f, gender: v || '' }))}
                />
              </Box>

              <Divider label="Role & Organization" labelPosition="center" my="sm" />

              <Box>
                <Select
                  label="User Role"
                  placeholder="Select user role"
                  data={rolesOptions}
                  required
                  value={form.idUserRole}
                  onChange={(v) => setForm(f => ({ ...f, idUserRole: v || '' }))}
                />

                <Select
                  label="Village"
                  placeholder="Type to search village..."
                  searchable
                  onSearchChange={setVillageSearch}
                  data={villagesOptions}
                  mt="sm"
                  required
                  value={form.idVillage}
                  onChange={(v) => {
                    setForm(f => ({ ...f, idVillage: v || '', idGroup: '', idPosition: '' }))
                  }}
                />

                <SimpleGrid cols={2} spacing="md" mt="sm">
                  <Select
                    label="Group"
                    placeholder={form.idVillage ? "Select group" : "Select village first"}
                    data={groupsOptions}
                    disabled={!form.idVillage}
                    required
                    value={form.idGroup}
                    onChange={(v) => {
                      setForm(f => ({ ...f, idGroup: v || '', idPosition: '' }))
                    }}
                  />
                  <Select
                    label="Position"
                    placeholder={form.idGroup ? "Select position" : "Select group first"}
                    data={positionsOptions}
                    disabled={!form.idGroup}
                    value={form.idPosition || ''}
                    onChange={(v) => setForm(f => ({ ...f, idPosition: v || '' }))}
                  />
                </SimpleGrid>
              </Box>

              <Button
                fullWidth
                mt="lg"
                radius="md"
                size="md"
                variant="gradient"
                gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
                loading={isSubmitting}
                onClick={handleCreateUser}
              >
                Register User
              </Button>
            </Stack>
          </Modal>

          <Modal
            opened={editOpened}
            onClose={closeEdit}
            title={<Text fw={700} size="lg">Edit User</Text>}
            radius="xl"
            size="lg"
            overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
          >
            <Stack gap="md">
              <Box>
                <Text size="xs" fw={700} c="dimmed" mb={8} style={{ textTransform: 'uppercase', letterSpacing: '0.05em' }}>
                  Personal Information
                </Text>
                <SimpleGrid cols={2} spacing="md">
                  <TextInput
                    label="Full Name"
                    placeholder="Enter full name"
                    required
                    value={editForm.name}
                    onChange={(e) => setEditForm(f => ({ ...f, name: e.target.value }))}
                  />
                  <TextInput
                    label="NIK"
                    placeholder="16-digit identity number"
                    required
                    value={editForm.nik}
                    onChange={(e) => setEditForm(f => ({ ...f, nik: e.target.value }))}
                  />
                </SimpleGrid>

                <SimpleGrid cols={2} spacing="md" mt="sm">
                  <TextInput
                    label="Email Address"
                    placeholder="email@example.com"
                    required
                    value={editForm.email}
                    onChange={(e) => setEditForm(f => ({ ...f, email: e.target.value }))}
                  />
                  <TextInput
                    label="Phone Number"
                    placeholder="628xxxxxxxxxx"
                    required
                    value={editForm.phone}
                    onChange={(e) => setEditForm(f => ({ ...f, phone: e.target.value }))}
                  />
                </SimpleGrid>

                <Select
                  label="Gender"
                  placeholder="Select gender"
                  data={[
                    { value: 'M', label: 'Male' },
                    { value: 'F', label: 'Female' },
                  ]}
                  mt="sm"
                  required
                  value={editForm.gender}
                  onChange={(v) => setEditForm(f => ({ ...f, gender: v || '' }))}
                />
              </Box>

              <Divider label="Role & Organization" labelPosition="center" my="sm" />

              <Box>
                <Select
                  label="User Role"
                  placeholder="Select user role"
                  data={rolesOptions}
                  required
                  value={editForm.idUserRole}
                  onChange={(v) => setEditForm(f => ({ ...f, idUserRole: v || '' }))}
                />

                <Select
                  label="Village"
                  placeholder="Type to search village..."
                  searchable
                  onSearchChange={setVillageSearch}
                  data={villagesOptions}
                  mt="sm"
                  required
                  value={editForm.idVillage}
                  onChange={(v) => {
                    setEditForm(f => ({ ...f, idVillage: v || '', idGroup: '', idPosition: '' }))
                  }}
                />

                <SimpleGrid cols={2} spacing="md" mt="sm">
                  <Select
                    label="Group"
                    placeholder={editForm.idVillage ? "Select group" : "Select village first"}
                    data={groupsOptions}
                    disabled={!editForm.idVillage}
                    required
                    value={editForm.idGroup}
                    onChange={(v) => {
                      setEditForm(f => ({ ...f, idGroup: v || '', idPosition: '' }))
                    }}
                  />
                  <Select
                    label="Position"
                    placeholder={editForm.idGroup ? "Select position" : "Select group first"}
                    data={positionsOptions}
                    disabled={!editForm.idGroup}
                    value={editForm.idPosition || ''}
                    onChange={(v) => setEditForm(f => ({ ...f, idPosition: v || '' }))}
                  />
                </SimpleGrid>
              </Box>

              <Divider label="System Access" labelPosition="center" my="sm" />

              <SimpleGrid cols={2} spacing="xl">
                <Switch
                  label="Account Active"
                  description="Enable or disable user access"
                  checked={editForm.isActive}
                  onChange={(event) => setEditForm(f => ({ ...f, isActive: event.currentTarget.checked }))}
                />
                <Switch
                  label="Without OTP"
                  description="Bypass login OTP verification"
                  checked={editForm.isWithoutOTP}
                  onChange={(event) => setEditForm(f => ({ ...f, isWithoutOTP: event.currentTarget.checked }))}
                />
              </SimpleGrid>

              <Button
                fullWidth
                mt="lg"
                radius="md"
                size="md"
                variant="gradient"
                gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
                loading={isSubmitting}
                onClick={handleUpdateUser}
              >
                Update User
              </Button>
            </Stack>
          </Modal>

          <TextInput
            placeholder="Search name, NIK, or email..."
            leftSection={<TbSearch size={18} />}
            size="md"
            rightSection={
              search ? (
                <ActionIcon variant="transparent" color="gray" onClick={handleClearSearch} size="md">
                  <TbX size={18} />
                </ActionIcon>
              ) : null
            }
            value={search}
            onChange={(e) => handleSearchChange(e.currentTarget.value)}
            radius="md"
            style={{ maxWidth: 500 }}
            ml={40}
          />
        </Stack>
      </Paper>

      {isLoading ? (
        <Paper p="xl" radius="xl" withBorder style={{ textAlign: 'center' }}>
          <Text c="dimmed">Loading user data...</Text>
        </Paper>
      ) : error ? (
        <Paper p="xl" radius="xl" withBorder style={{ textAlign: 'center' }}>
          <Text c="red">Failed to load data from API.</Text>
        </Paper>
      ) : users.length === 0 ? (
        <Paper p="xl" radius="xl" withBorder style={{ textAlign: 'center' }}>
          <TbUsers size={40} color="gray" opacity={0.4} />
          <Text c="dimmed" mt="md">No users match your criteria.</Text>
        </Paper>
      ) : (
        <Paper withBorder radius="2xl" className="glass" style={{ overflow: 'hidden' }}>
          <ScrollArea h={isMobile ? undefined : 'auto'} offsetScrollbars>
            <Table
              verticalSpacing="md"
              horizontalSpacing="md"
              highlightOnHover
              withColumnBorders={false}
              style={{
                tableLayout: isMobile ? 'auto' : 'fixed',
                width: '100%',
                minWidth: isMobile ? 900 : 'unset'
              }}
            >
              <Table.Thead bg="rgba(0,0,0,0.05)">
                <Table.Tr>
                  <Table.Th style={{ border: 'none', width: isMobile ? undefined : '28%' }}>User & ID</Table.Th>
                  <Table.Th style={{ border: 'none', width: isMobile ? undefined : '25%' }}>Contact Detail</Table.Th>
                   <Table.Th style={{ border: 'none', width: isMobile ? undefined : '22%' }}>Organization</Table.Th>
                   <Table.Th style={{ border: 'none', width: isMobile ? undefined : '20%' }}>Role</Table.Th>
                   <Table.Th style={{ border: 'none', width: isMobile ? undefined : '10%' }}>Status</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {users.map((user) => (
                  <Table.Tr key={user.id} style={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }} onClick={()=>{handleEditOpen(user)}}>
                    <Table.Td>
                      <Group gap="md" wrap="nowrap">
                        <Avatar
                          size="lg"
                          radius="md"
                          variant="light"
                          color={getRoleColor(user.role)}
                          style={{ border: '1px solid rgba(255,255,255,0.1)', flexShrink: 0 }}
                        >
                          {user.name.charAt(0)}
                        </Avatar>
                        <Stack gap={2} style={{ overflow: 'hidden' }}>
                          <Text fw={700} size="sm" truncate="end" style={{ color: 'var(--mantine-color-white)' }}>{user.name}</Text>
                          <Group gap={4} wrap="nowrap">
                            <TbId size={12} color="var(--mantine-color-dimmed)" />
                            <Text size="xs" c="dimmed" style={{ letterSpacing: '0.5px' }} truncate="end">{user.nik}</Text>
                          </Group>
                        </Stack>
                      </Group>
                    </Table.Td>
                    <Table.Td>
                      <Stack gap={4} style={{ overflow: 'hidden' }}>
                        <Group gap={8} wrap="nowrap" align="center">
                          <ThemeIcon size={18} variant="transparent" color="gray">
                            <TbMail size={14} />
                          </ThemeIcon>
                          <Text size="xs" fw={500} truncate="end">{user.email}</Text>
                        </Group>
                        <Group gap={8} wrap="nowrap" align="center">
                          <ThemeIcon size={18} variant="transparent" color="gray">
                            <TbPhone size={14} />
                          </ThemeIcon>
                          <Text size="xs" c="dimmed" truncate="end">{user.phone}</Text>
                        </Group>
                      </Stack>
                    </Table.Td>
                    <Table.Td>
                      <Stack gap={4}>
                        <Group gap={8} wrap="nowrap" align="center">
                          <ThemeIcon size={18} variant="light" color="blue" radius="sm">
                            <TbHome2 size={12} />
                          </ThemeIcon>
                          <Text size="xs" fw={700} truncate="end">{user.village}</Text>
                        </Group>
                        <Group gap={8} wrap="nowrap" align="center">
                          <ThemeIcon size={18} variant="transparent" color="gray">
                            <TbBriefcase size={12} />
                          </ThemeIcon>
                          <Text size="xs" c="dimmed" truncate="end">{user.group} · {user.position || 'Staff'}</Text>
                        </Group>
                      </Stack>
                    </Table.Td>
                    <Table.Td>
                      <Badge
                        variant="filled"
                        color={getRoleColor(user.role)}
                        radius="md"
                        size="sm"
                        fullWidth={false}
                        styles={{ root: { textTransform: 'uppercase', fontWeight: 800, whiteSpace: 'nowrap' } }}
                      >
                        {user.role}
                      </Badge>
                    </Table.Td>
                    <Table.Td>
                      <Stack gap={4}>
                        <Group gap="xs" wrap="nowrap">
                          {user.isActive ? (
                            <Box style={{ width: 8, height: 8, borderRadius: '50%', background: '#10b981', boxShadow: '0 0 8px #10b981' }} />
                          ) : (
                            <Box style={{ width: 8, height: 8, borderRadius: '50%', background: '#ef4444' }} />
                          )}
                          <Text size="xs" fw={800} c={user.isActive ? 'teal.4' : 'red.5'}>
                            {user.isActive ? 'ACTIVE' : 'INACTIVE'}
                          </Text>
                        </Group>
                        {user.isWithoutOTP && (
                          <Badge variant="light" color="orange" size="xs" radius="sm">
                            NO OTP
                          </Badge>
                        )}
                      </Stack>
                    </Table.Td>
                  </Table.Tr>
                ))}
              </Table.Tbody>
            </Table>
          </ScrollArea>
        </Paper>
      )}

      {!isLoading && !error && response?.data?.totalPage > 0 && (
        <Group justify="center" mt="xl">
          <Pagination
            value={page}
            onChange={setPage}
            total={response.data.totalPage}
            radius="md"
            withEdges={false}
            siblings={1}
            boundaries={1}
          />
        </Group>
      )}
    </Stack>
  )
}
