import {useState, useEffect} from 'react'
import {Stack, Typography, Button, MenuItem, Select, FormControl, InputLabel, Grid, Box, Accordion, AccordionSummary, AccordionDetails, useTheme, TextField} from '@mui/material'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import axios from 'axios'
import {BACKEND_URL} from '../lib/constants'

type Field<T> = {
  label: string
  data: keyof T
}

type ExtraFieldConfig = {
  type: 'number'
  label: string
  minValue: number
  maxValue: (linkedItems: any[]) => number
}

type LinkedItemsProps<T> = {
  parentId: string | number
  parentResource: string
  childResource: string
  fields: Field<T>[]
  title: string
  type: 'show' | 'edit'
  extraField?: ExtraFieldConfig
}

export const LinkedItems = <T extends {id: number; [key: string]: any}>({parentId, parentResource, childResource, fields, title, type}: LinkedItemsProps<T>) => {
  const [items, setItems] = useState<T[]>([])
  const [linkedItems, setLinkedItems] = useState<T[]>([])
  const [selectedItemId, setSelectedItemId] = useState<number | null>(null)
  const [pageNum, setPageNum] = useState<number>(1)
  const [isLoading, setIsLoading] = useState<boolean>(true)
  const [mediaOrder, setMediaOrder] = useState<number>(1)
  const theme = useTheme()

  useEffect(() => {
    if (parentId) {
      axios
        .get(`${BACKEND_URL}/${parentResource}/${parentId}/${childResource}`)
        .then((response) => {
          setLinkedItems(response?.data || [])
        })
        .catch(() => {
          setLinkedItems([])
        })
    }
  }, [parentId, parentResource, childResource])

  useEffect(() => {
    if (type === 'edit') {
      axios
        .get(`${BACKEND_URL}/${childResource}/`)
        .then((response) => {
          setItems(response?.data || [])
          setIsLoading(false)
        })
        .catch(() => {
          setItems([])
          setIsLoading(false)
        })
    } else {
      setIsLoading(false)
    }
  }, [childResource, type])

  useEffect(() => {
    if (childResource === 'article' && parentResource === 'sight') {
      setPageNum(linkedItems.length + 1)
    }
  }, [linkedItems, childResource, parentResource])

  const availableItems = items.filter((item) => !linkedItems.some((linked) => linked.id === item.id))

  const linkItem = () => {
    if (selectedItemId !== null) {
      const requestData =
        childResource === 'article'
          ? {
              [`${childResource}_id`]: selectedItemId,
              page_num: pageNum,
            }
          : childResource === 'media'
          ? {
              [`${childResource}_id`]: selectedItemId,
              media_order: mediaOrder,
            }
          : {
              [`${childResource}_id`]: selectedItemId,
            }

      axios
        .post(`${BACKEND_URL}/${parentResource}/${parentId}/${childResource}`, requestData)
        .then(() => {
          axios.get(`${BACKEND_URL}/${parentResource}/${parentId}/${childResource}`).then((response) => {
            setLinkedItems(response?.data || [])
            setSelectedItemId(null)
            if (childResource === 'article') {
              setPageNum(pageNum + 1)
            }
          })
        })
        .catch((error) => {
          console.error('Error linking item:', error)
        })
    }
  }

  const deleteItem = (itemId: number) => {
    axios
      .delete(`${BACKEND_URL}/${parentResource}/${parentId}/${childResource}`, {
        data: {[`${childResource}_id`]: itemId},
      })
      .then(() => {
        setLinkedItems((prev) => prev.filter((item) => item.id !== itemId))
      })
      .catch((error) => {
        console.error('Error unlinking item:', error)
      })
  }

  return (
    <Accordion>
      <AccordionSummary
        expandIcon={<ExpandMoreIcon />}
        sx={{
          background: theme.palette.background.paper,
          borderBottom: `1px solid ${theme.palette.divider}`,
        }}
      >
        <Typography variant="subtitle1" fontWeight="bold">
          Привязанные {title}
        </Typography>
      </AccordionSummary>

      <AccordionDetails sx={{background: theme.palette.background.paper}}>
        <Stack gap={2}>
          <Grid container gap={1.25}>
            {isLoading ? (
              <Typography>Загрузка...</Typography>
            ) : linkedItems.length > 0 ? (
              linkedItems.map((item, index) => (
                <Box
                  key={index}
                  sx={{
                    marginTop: '8px',
                    padding: '14px',
                    borderRadius: 2,
                    border: `2px solid ${theme.palette.divider}`,
                  }}
                >
                  <Stack gap={0.25}>
                    {fields.map(({label, data}) => (
                      <Typography variant="body2" color="textSecondary" key={String(data)}>
                        <strong>{label}:</strong> {item[data]}
                      </Typography>
                    ))}
                    {type === 'edit' && (
                      <Button variant="outlined" color="error" size="small" onClick={() => deleteItem(item.id)} sx={{mt: 1.5}}>
                        Отвязать
                      </Button>
                    )}
                  </Stack>
                </Box>
              ))
            ) : (
              <Typography>{title} не найдены</Typography>
            )}
          </Grid>

          {type === 'edit' && (
            <Stack gap={2}>
              <Typography variant="subtitle1">Добавить {title}</Typography>
              <FormControl fullWidth>
                <InputLabel>Выберите {title}</InputLabel>
                <Select value={selectedItemId || ''} onChange={(e) => setSelectedItemId(e.target.value as number)} label={`Выберите ${title}`}>
                  {availableItems.map((item) => (
                    <MenuItem key={item.id} value={item.id}>
                      {/* {fields.map((field) => item[field.data]).join(' - ')} */}
                      {item[fields[0].data]}
                    </MenuItem>
                  ))}
                </Select>
              </FormControl>

              {childResource === 'article' && (
                <FormControl fullWidth>
                  <TextField
                    type="number"
                    label="Номер страницы"
                    name="page_num"
                    value={pageNum}
                    onChange={(e) => {
                      const newValue = Number(e.target.value)
                      const minValue = linkedItems.length + 1 // page number on articles lenght
                      setPageNum(newValue < minValue ? minValue : newValue)
                    }}
                    fullWidth
                    InputLabelProps={{shrink: true}}
                  />
                </FormControl>
              )}

              {childResource === 'media' && type === 'edit' && (
                <FormControl fullWidth>
                  <TextField
                    type="number"
                    label="Порядок отображения медиа"
                    value={mediaOrder}
                    onChange={(e) => {
                      const newValue = Number(e.target.value)
                      const maxValue = linkedItems.length + 1
                      const value = Math.max(1, Math.min(newValue, maxValue))
                      setMediaOrder(value)
                    }}
                    fullWidth
                    InputLabelProps={{shrink: true}}
                  />
                </FormControl>
              )}

              <Button variant="contained" onClick={linkItem} disabled={!selectedItemId}>
                Добавить
              </Button>
            </Stack>
          )}
        </Stack>
      </AccordionDetails>
    </Accordion>
  )
}
