import {
  Accordion,
  Avatar,
  Badge,
  Box,
  Button,
  Code,
  Collapse,
  FileInput,
  Group,
  Image,
  Loader,
  Modal,
  Pagination,
  Paper,
  Select,
  SimpleGrid,
  Stack,
  Text,
  Textarea,
  TextInput,
  ThemeIcon,
  Timeline,
  Title,
  Tooltip,
} from '@mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { notifications } from '@mantine/notifications'
import { useQuery } from '@tanstack/react-query'
import { createFileRoute, useParams } from '@tanstack/react-router'
import dayjs from 'dayjs'
import { useState } from 'react'
import {
  TbAlertTriangle,
  TbBug,
  TbCircleCheck,
  TbCircleX,
  TbDeviceDesktop,
  TbDeviceMobile,
  TbFilter,
  TbHistory,
  TbPhoto,
  TbPlus,
  TbSearch,
} from 'react-icons/tb'
import { API_URLS } from '../config/api'

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

const STATUS_COLOR: Record<string, string> = {
  OPEN: 'red',
  IN_PROGRESS: 'blue',
  ON_HOLD: 'orange',
  RESOLVED: 'teal',
  RELEASED: 'green',
  CLOSED: 'gray',
}
const STATUS_LABEL: Record<string, string> = {
  OPEN: 'Open',
  ON_HOLD: 'On Hold',
  IN_PROGRESS: 'In Progress',
  RESOLVED: 'Resolved',
  RELEASED: 'Released',
  CLOSED: 'Closed',
}

function AppErrorsPage() {
  const { appId } = useParams({ from: '/apps/$appId/errors' })

  const [page, setPage] = useState(1)
  const [search, setSearch] = useState('')
  const [status, setStatus] = useState('all')

  const [showLogs, setShowLogs] = useState<Record<string, boolean>>({})
  const [showStackTrace, setShowStackTrace] = useState<Record<string, boolean>>({})

  const toggleLogs = (bugId: string) => setShowLogs((prev) => ({ ...prev, [bugId]: !prev[bugId] }))
  const toggleStackTrace = (bugId: string) => setShowStackTrace((prev) => ({ ...prev, [bugId]: !prev[bugId] }))

  const { data, isLoading, refetch } = useQuery({
    queryKey: ['bugs', { page, search, app: appId, status }],
    queryFn: () => fetch(API_URLS.getBugs(page, search, appId, status)).then((r) => r.json()),
  })

  const { data: appsList } = useQuery({
    queryKey: ['apps-list'],
    queryFn: () => fetch('/api/apps').then((r) => r.json()),
  })

  const [previewImage, setPreviewImage] = useState<string | null>(null)

  const [opened, { open, close }] = useDisclosure(false)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [imageFiles, setImageFiles] = useState<File[]>([])
  const [createForm, setCreateForm] = useState({
    description: '',
    app: appId,
    source: 'USER',
    affectedVersion: '',
    device: '',
    os: '',
    stackTrace: '',
  })

  const [updateModalOpened, { open: openUpdateModal, close: closeUpdateModal }] = useDisclosure(false)
  const [isUpdating, setIsUpdating] = useState(false)
  const [selectedBugId, setSelectedBugId] = useState<string | null>(null)
  const [updateForm, setUpdateForm] = useState({ status: '', description: '' })

  const [feedbackModalOpened, { open: openFeedbackModal, close: closeFeedbackModal }] = useDisclosure(false)
  const [isUpdatingFeedback, setIsUpdatingFeedback] = useState(false)
  const [feedbackForm, setFeedbackForm] = useState({ feedBack: '' })

  const handleUpdateFeedback = async () => {
    if (!selectedBugId || !feedbackForm.feedBack) return
    setIsUpdatingFeedback(true)
    try {
      const res = await fetch(API_URLS.updateBugFeedback(selectedBugId), {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(feedbackForm),
      })
      if (res.ok) {
        notifications.show({ title: 'Success', message: 'Feedback has been updated.', color: 'teal', icon: <TbCircleCheck size={18} /> })
        refetch()
        closeFeedbackModal()
        setFeedbackForm({ feedBack: '' })
      } else {
        throw new Error()
      }
    } catch {
      notifications.show({ title: 'Error', message: 'Something went wrong.', color: 'red', icon: <TbCircleX size={18} /> })
    } finally {
      setIsUpdatingFeedback(false)
    }
  }

  const handleUpdateStatus = async () => {
    if (!selectedBugId || !updateForm.status) return
    setIsUpdating(true)
    try {
      const res = await fetch(API_URLS.updateBugStatus(selectedBugId), {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(updateForm),
      })
      if (res.ok) {
        notifications.show({ title: 'Success', message: 'Status has been updated.', color: 'teal', icon: <TbCircleCheck size={18} /> })
        refetch()
        closeUpdateModal()
        setUpdateForm({ status: '', description: '' })
      } else {
        throw new Error()
      }
    } catch {
      notifications.show({ title: 'Error', message: 'Something went wrong.', color: 'red', icon: <TbCircleX size={18} /> })
    } finally {
      setIsUpdating(false)
    }
  }

  const handleCreateBug = async () => {
    if (!createForm.description || !createForm.affectedVersion || !createForm.device || !createForm.os) {
      notifications.show({ title: 'Validation Error', message: 'Please fill in all required fields.', color: 'red' })
      return
    }
    setIsSubmitting(true)
    try {
      const imageUrls: string[] = []
      for (const file of imageFiles) {
        const formData = new FormData()
        formData.append('file', file)
        const uploadRes = await fetch(API_URLS.uploadImage(), { method: 'POST', body: formData })
        if (!uploadRes.ok) throw new Error('Failed to upload image')
        const { url } = await uploadRes.json()
        imageUrls.push(url)
      }
      const res = await fetch(API_URLS.createBug(), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...createForm, imageUrls: imageUrls.length ? imageUrls : undefined }),
      })
      if (res.ok) {
        await fetch(API_URLS.createLog(), {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ type: 'CREATE', message: `New error report added: ${createForm.description.substring(0, 50)}${createForm.description.length > 50 ? '...' : ''}` }),
        }).catch(console.error)
        notifications.show({ title: 'Success', message: 'Error report has been created.', color: 'teal', icon: <TbCircleCheck size={18} /> })
        refetch()
        close()
        setImageFiles([])
        setCreateForm({ description: '', app: appId, source: 'USER', affectedVersion: '', device: '', os: '', stackTrace: '' })
      } else {
        throw new Error()
      }
    } catch {
      notifications.show({ title: 'Error', message: 'Something went wrong.', color: 'red', icon: <TbCircleX size={18} /> })
    } finally {
      setIsSubmitting(false)
    }
  }

  const bugs = data?.data || []
  const totalPages = data?.totalPages || 1

  return (
    <Stack gap="xl" py="md">
      <Group justify="space-between" align="flex-start">
        <Stack gap={4}>
          <Title order={3}>Error Reports</Title>
          <Text size="sm" c="dimmed">
            Bug reports and crash tracking for this application.
          </Text>
        </Stack>
        <Button
          variant="gradient"
          gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
          leftSection={<TbPlus size={18} />}
          size="sm"
          onClick={open}
        >
          Report Error
        </Button>
      </Group>

      {/* Image Preview Modal */}
      <Modal
        opened={!!previewImage}
        onClose={() => setPreviewImage(null)}
        size="xl"
        radius="md"
        padding={0}
        withCloseButton={false}
        overlayProps={{ backgroundOpacity: 0.75, blur: 6 }}
        styles={{ content: { background: 'transparent', boxShadow: 'none' } }}
        onClick={() => setPreviewImage(null)}
      >
        {previewImage && (
          <Image src={previewImage} alt="Preview" fit="contain" style={{ maxHeight: '85vh', width: '100%' }} />
        )}
      </Modal>

      <Modal
        opened={updateModalOpened}
        onClose={closeUpdateModal}
        title={<Text fw={700} size="lg">Update Bug Status</Text>}
        radius="md"
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="md">
          <Select
            label="New Status"
            placeholder="Select a status"
            required
            data={Object.entries(STATUS_LABEL).map(([value, label]) => ({ value, label }))}
            value={updateForm.status}
            onChange={(val) => setUpdateForm({ ...updateForm, status: val || '' })}
          />
          <Textarea
            label="Update Note (Optional)"
            placeholder="e.g. Fixed in commit abc123 / Assigned to team"
            minRows={3}
            value={updateForm.description}
            onChange={(e) => setUpdateForm({ ...updateForm, description: e.target.value })}
          />
          <Button
            fullWidth
            mt="md"
            variant="gradient"
            gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
            loading={isUpdating}
            onClick={handleUpdateStatus}
          >
            Save Changes
          </Button>
        </Stack>
      </Modal>

      <Modal
        opened={feedbackModalOpened}
        onClose={closeFeedbackModal}
        title={<Text fw={700} size="lg">Developer Feedback</Text>}
        radius="md"
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="md">
          <Textarea
            data-autofocus
            label="Feedback / Note"
            placeholder="Explain the issue, root cause, or resolution..."
            required
            minRows={4}
            value={feedbackForm.feedBack}
            onChange={(e) => setFeedbackForm({ feedBack: e.target.value })}
          />
          <Button
            fullWidth
            mt="md"
            variant="gradient"
            gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
            loading={isUpdatingFeedback}
            onClick={handleUpdateFeedback}
          >
            Save Feedback
          </Button>
        </Stack>
      </Modal>

      <Modal
        opened={opened}
        onClose={() => { close(); setImageFiles([]) }}
        title={<Text fw={700} size="lg">Report New Error</Text>}
        radius="md"
        size="lg"
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="md">
          <Textarea
            label="Description"
            placeholder="What happened? Describe the error in detail..."
            required
            minRows={3}
            value={createForm.description}
            onChange={(e) => setCreateForm({ ...createForm, description: e.target.value })}
          />
          <SimpleGrid cols={2}>
            <Select
              label="Application"
              data={appsList?.map((a: any) => ({ value: a.id, label: a.name })) || []}
              value={createForm.app}
              onChange={(val) => setCreateForm({ ...createForm, app: val as any })}
              placeholder="Select application"
              disabled={!appsList}
            />
            <Select
              label="Source"
              data={[
                { value: 'USER', label: 'User' },
                { value: 'QC', label: 'QC' },
                { value: 'SYSTEM', label: 'System' },
              ]}
              value={createForm.source}
              onChange={(val) => setCreateForm({ ...createForm, source: val as any })}
            />
          </SimpleGrid>
          <TextInput
            label="Affected Version"
            placeholder="e.g. 2.4.1"
            required
            value={createForm.affectedVersion}
            onChange={(e) => setCreateForm({ ...createForm, affectedVersion: e.target.value })}
          />
          <SimpleGrid cols={2}>
            <TextInput
              label="Device"
              placeholder="e.g. iPhone 13, Windows PC"
              required
              value={createForm.device}
              onChange={(e) => setCreateForm({ ...createForm, device: e.target.value })}
            />
            <TextInput
              label="OS"
              placeholder="e.g. iOS 15.4, Windows 11"
              required
              value={createForm.os}
              onChange={(e) => setCreateForm({ ...createForm, os: e.target.value })}
            />
          </SimpleGrid>
          <FileInput
            label="Screenshots (Optional)"
            placeholder="Click to upload images..."
            accept="image/*"
            leftSection={<TbPhoto size={16} />}
            description="Max 3 images · 5 MB each · JPG, PNG, WEBP"
            value={imageFiles}
            onChange={(files) => {
              if (files.length > 3) {
                notifications.show({ title: 'Error', message: 'Maximum 3 images allowed.', color: 'red' })
                return
              }
              setImageFiles(files)
            }}
            clearable
            multiple
          />
          <Textarea
            label="Stack Trace (Optional)"
            placeholder="Paste error logs or stack trace here..."
            style={{ fontFamily: 'monospace' }}
            minRows={2}
            value={createForm.stackTrace}
            onChange={(e) => setCreateForm({ ...createForm, stackTrace: e.target.value })}
          />
          <Button
            fullWidth
            mt="md"
            variant="gradient"
            gradient={{ from: '#2563EB', to: '#7C3AED', deg: 135 }}
            loading={isSubmitting}
            onClick={handleCreateBug}
          >
            Submit Error Report
          </Button>
        </Stack>
      </Modal>

      <Paper withBorder radius="2xl" className="glass" p="md">
        <SimpleGrid cols={{ base: 1, sm: 3 }} mb="lg">
          <TextInput
            label="Search"
            placeholder="Description, device, OS..."
            leftSection={<TbSearch size={16} />}
            value={search}
            onChange={(e) => setSearch(e.currentTarget.value)}
            radius="md"
            size="sm"
          />
          <Select
            label="Status"
            size="sm"
            data={[
              { value: 'all', label: 'All Status' },
              ...Object.entries(STATUS_LABEL).map(([value, label]) => ({ value, label })),
            ]}
            value={status}
            onChange={(val) => setStatus(val || 'all')}
            radius="md"
          />
          <Stack justify="flex-end">
            <Button
              variant="subtle"
              color="gray"
              size="sm"
              leftSection={<TbFilter size={16} />}
              onClick={() => { setSearch(''); setStatus('all') }}
            >
              Reset Filters
            </Button>
          </Stack>
        </SimpleGrid>

        {isLoading ? (
          <Stack align="center" py="xl">
            <Loader size="md" type="dots" />
          </Stack>
        ) : bugs.length === 0 ? (
          <Stack align="center" py="xl" gap="xs">
            <TbBug size={40} style={{ opacity: 0.25 }} />
            <Text fw={600} size="sm">No error reports found</Text>
            <Text size="sm" c="dimmed">Try adjusting your filters or search terms.</Text>
          </Stack>
        ) : (
          <Accordion variant="separated" radius="xl">
            {bugs.map((bug: any) => (
              <Accordion.Item
                key={bug.id}
                value={bug.id}
                style={{
                  border: '1px solid var(--mantine-color-default-border)',
                  background: 'var(--mantine-color-default)',
                  marginBottom: 12,
                }}
              >
                <Accordion.Control>
                  <Group wrap="nowrap">
                    <ThemeIcon
                      color={STATUS_COLOR[bug.status] ?? 'gray'}
                      variant="light"
                      size="lg"
                      radius="md"
                    >
                      <TbAlertTriangle size={20} />
                    </ThemeIcon>
                    <Box style={{ flex: 1 }}>
                      <Group justify="space-between">
                        <Text size="sm" fw={600} lineClamp={1}>{bug.description}</Text>
                        <Badge
                          color={STATUS_COLOR[bug.status] ?? 'gray'}
                          variant="dot"
                          size="sm"
                        >
                          {STATUS_LABEL[bug.status] ?? bug.status}
                        </Badge>
                      </Group>
                      <Text size="xs" c="dimmed">
                        {dayjs(bug.createdAt).format('D MMM YYYY, HH:mm')} · {bug.appId?.toUpperCase()} · v{bug.affectedVersion}
                      </Text>
                    </Box>
                  </Group>
                </Accordion.Control>

                <Accordion.Panel>
                  <Stack gap="lg" py="xs">
                    <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg">
                      <Box>
                        <Text size="xs" fw={700} c="dimmed" mb={4} tt="uppercase">Device Metadata</Text>
                        <Group gap="xs">
                          {bug.device.toLowerCase().includes('windows') || bug.device.toLowerCase().includes('mac') || bug.device.toLowerCase().includes('pc') ? (
                            <TbDeviceDesktop size={14} color="gray" />
                          ) : (
                            <TbDeviceMobile size={14} color="gray" />
                          )}
                          <Text size="xs" fw={500}>{bug.device} ({bug.os})</Text>
                        </Group>
                      </Box>
                      <Box>
                        <Text size="xs" fw={700} c="dimmed" mb={4} tt="uppercase">Source</Text>
                        <Badge variant="light" color="gray" size="sm">{bug.source}</Badge>
                      </Box>
                    </SimpleGrid>

                    {(bug.user || bug.feedBack) && (
                      <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg">
                        {bug.user && (
                          <Box>
                            <Text size="xs" fw={700} c="dimmed" mb={4} tt="uppercase">Reported By</Text>
                            <Group gap="xs">
                              <Avatar src={bug.user.image} radius="xl" size="sm" color="blue">
                                {bug.user.name?.charAt(0).toUpperCase()}
                              </Avatar>
                              <Text size="sm">{bug.user.name}</Text>
                            </Group>
                          </Box>
                        )}
                        {bug.feedBack && (
                          <Box>
                            <Text size="xs" fw={700} c="dimmed" mb={4} tt="uppercase">Developer Feedback</Text>
                            <Text size="sm" style={{ whiteSpace: 'pre-wrap' }}>{bug.feedBack}</Text>
                          </Box>
                        )}
                      </SimpleGrid>
                    )}

                    {bug.stackTrace && (
                      <Box>
                        <Group justify="space-between" mb={showStackTrace[bug.id] ? 8 : 0}>
                          <Text size="xs" fw={700} c="dimmed" tt="uppercase">Stack Trace</Text>
                          <Button variant="subtle" size="compact-xs" color="gray" onClick={() => toggleStackTrace(bug.id)}>
                            {showStackTrace[bug.id] ? 'Hide' : 'Show'}
                          </Button>
                        </Group>
                        <Collapse in={!!showStackTrace[bug.id]}>
                          <Code
                            block
                            color="red"
                            style={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap', fontSize: 11, border: '1px solid var(--mantine-color-default-border)' }}
                          >
                            {bug.stackTrace}
                          </Code>
                        </Collapse>
                      </Box>
                    )}

                    {bug.images && bug.images.length > 0 && (
                      <Box>
                        <Group gap="xs" mb={8}>
                          <TbPhoto size={14} color="gray" />
                          <Text size="xs" fw={700} c="dimmed" tt="uppercase">
                            Attached Images ({bug.images.length})
                          </Text>
                        </Group>
                        <SimpleGrid cols={{ base: 2, sm: 4 }} spacing="xs">
                          {bug.images.map((img: any) => (
                            <Tooltip key={img.id} label="Click to preview" withArrow>
                              <Paper
                                withBorder
                                radius="md"
                                style={{ overflow: 'hidden', cursor: 'zoom-in' }}
                                onClick={() => setPreviewImage(img.imageUrl)}
                              >
                                <Image src={img.imageUrl} alt="Error screenshot" height={100} fit="cover" />
                              </Paper>
                            </Tooltip>
                          ))}
                        </SimpleGrid>
                      </Box>
                    )}

                    {bug.logs && bug.logs.length > 0 && (
                      <Box>
                        <Group justify="space-between" mb={showLogs[bug.id] ? 12 : 0}>
                          <Group gap="xs">
                            <TbHistory size={14} color="gray" />
                            <Text size="xs" fw={700} c="dimmed" tt="uppercase">
                              Activity Log ({bug.logs.length})
                            </Text>
                          </Group>
                          <Button variant="subtle" size="compact-xs" color="gray" onClick={() => toggleLogs(bug.id)}>
                            {showLogs[bug.id] ? 'Hide' : 'Show'}
                          </Button>
                        </Group>
                        <Collapse in={showLogs[bug.id]}>
                          <Timeline active={bug.logs.length - 1} bulletSize={24} lineWidth={2} mt="md">
                            {bug.logs.map((log: any) => (
                              <Timeline.Item
                                key={log.id}
                                bullet={
                                  <Badge size="xs" circle color={STATUS_COLOR[log.status] ?? 'blue'}> </Badge>
                                }
                                title={
                                  <Text size="sm" fw={600}>
                                    {STATUS_LABEL[log.status] ?? log.status}
                                  </Text>
                                }
                              >
                                <Text size="xs" c="dimmed" mb={4}>
                                  {dayjs(log.createdAt).format('D MMM YYYY, HH:mm')} · {log.user?.name ?? 'Unknown'}
                                </Text>
                                <Text size="sm">{log.description}</Text>
                              </Timeline.Item>
                            ))}
                          </Timeline>
                        </Collapse>
                      </Box>
                    )}

                    <Group justify="flex-end" pt="sm">
                      <Button
                        variant="light"
                        size="compact-sm"
                        color="blue"
                        onClick={() => {
                          setSelectedBugId(bug.id)
                          setFeedbackForm({ feedBack: bug.feedBack || '' })
                          openFeedbackModal()
                        }}
                      >
                        Developer Feedback
                      </Button>
                      <Button
                        variant="light"
                        size="compact-sm"
                        color="teal"
                        onClick={() => {
                          setSelectedBugId(bug.id)
                          setUpdateForm({ status: bug.status, description: '' })
                          openUpdateModal()
                        }}
                      >
                        Update Status
                      </Button>
                    </Group>
                  </Stack>
                </Accordion.Panel>
              </Accordion.Item>
            ))}
          </Accordion>
        )}

        {totalPages > 1 && (
          <Group justify="center" mt="xl">
            <Pagination total={totalPages} value={page} onChange={setPage} size="sm" radius="xl" />
          </Group>
        )}
      </Paper>
    </Stack>
  )
}
