// import { PrimeReactProvider } from "primereact/api";
// import { Tree } from 'primereact/tree';
// import { type TreeNode } from 'primereact/treenode'

import { TriangleRightIcon, TriangleDownIcon, MagnifyingGlassIcon } from '@radix-ui/react-icons'
import { useEffect, useState } from 'react'

import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'

import { getClientInfo } from '@/lib/location';

import { type FormData, type TreeNode, type SelectedItem, type IncidenciasIndexProps, type Area, type DropdownItem } from './types'

const getDefaultDateTime = (): string => {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  const day = String(now.getDate()).padStart(2, '0');
  const hours = String(now.getHours()).padStart(2, '0');
  const minutes = String(now.getMinutes()).padStart(2, '0');

  return `${year}-${month}-${day}T${hours}:${minutes}`;
};

const Index = (props: IncidenciasIndexProps) => {
  const initial_data: FormData = {
    colaborador: '',
    descripcion: '',
    causa: '',
    efecto: '',
    frecuencia: '',
    proceso_id: '',
    area_reporte: '',
    area_origen: '',
    oficina_id: '',
    fuente_id: '',
    impacto_mon: '',
    navegador: getClientInfo().browser,
    ip_address: props.ip,
    ubicacion_lat: '',
    ubicacion_lon: '',
    fecha_incidencia: getDefaultDateTime(),
    codigo_colaborador: '',
    files: []
  }

  const [formErrors, setFormErrors] = useState<FormData>([])

  const [formData, setFormData] = useState<FormData>(initial_data)

  // Set browser info on mount
  useEffect(() => {
    // Set IP address (fetch from public API)
    // fetch('https://api.ipify.org?format=json')
    //   .then(res => res.json())
    //   .then(data => {
    //     setFormData(prev => ({ ...prev, ip_address: data.ip || '' }));
    //   });

    // Set geolocation
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (pos) => {
          setFormData(prev => ({
            ...prev,
            ubicacion_lat: String(pos.coords.latitude),
            ubicacion_lon: String(pos.coords.longitude)
          }));
        },
        () => {
          // User denied or error
        }
      );
    }
  }, []);

  const [documento, setDocumento] = useState<string>('')
  const [areasEmployee, setAreasEmployee] = useState<Area[]>([])

  // State for procesos dropdown
  const [selectedProceso, setSelectedProceso] = useState<SelectedItem>({})
  const [openProcesosNodes, setOpenProcesosNodes] = useState<Record<string, boolean>>({});
  const [searchProceso, setSearchProceso] = useState<string>("")

  // State for fuentes dropdown
  const [selectedFuente, setSelectedFuente] = useState<SelectedItem>({})
  const [openFuentesNodes, setOpenFuentesNodes] = useState<Record<string, boolean>>({});
  const [searchFuente, setSearchFuente] = useState<string>("")

  // Submission dialog state
  const [submissionStatus, setSubmissionStatus] = useState<'idle' | 'sending' | 'success' | 'error'>('idle')
  const [dialogOpen, setDialogOpen] = useState<boolean>(false)
  const [dialogMsg, setDialogMsg] = useState<string>('')

  const toggleNode = (node: string | number, opcion = 'procesos') => {
    if (opcion === 'procesos') setOpenProcesosNodes(prev => ({
      ...prev,
      [node]: !prev[node]
    }));
    else setOpenFuentesNodes(prev => ({
      ...prev,
      [node]: !prev[node]
    }))
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value } = e.target
    setFormData(prev => ({
      ...prev,
      [name]: value
    }))
  }

  const handleSelectChange = (name: string, value: string|number|undefined) => {
    setFormData(prev => ({
      ...prev,
      [name]: value
    }))
  }

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles = Array.from(e.target.files || [])
    setFormData(prev => ({
      ...prev,
      files: [...prev.files, ...selectedFiles]
    }))
  }

  const removeFile = (index: number) => {
    setFormData(prev => ({
      ...prev,
      files: prev.files.filter((_, i) => i !== index)
    }))
  }

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setSubmissionStatus('sending')
    setDialogMsg('')
    try {
      const csrfMeta = document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null
      const csrf = csrfMeta ? csrfMeta.content : ''

      let body: BodyInit
      let headers: Record<string, string> = {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        ...(csrf ? { 'X-CSRF-TOKEN': csrf } : {}),
      }

      if (formData.files.length > 0) {
        // Use FormData for file uploads
        const formDataObj = new FormData()
        Object.entries(formData).forEach(([key, value]) => {
          if (key === 'files') {
            formData.files.forEach((file, index) => {
              formDataObj.append(`files[${index}]`, file)
            })
          } else {
            formDataObj.append(key, String(value))
          }
        })
        body = formDataObj
      } else {
        // Use JSON for non-file data
        headers['Content-Type'] = 'application/json'
        body = JSON.stringify(formData)
      }

      const response = await fetch('incidencia', {
        method: 'POST',
        credentials: 'include',
        headers,
        body,
      })

      const contentType = response.headers.get('content-type') || ''
      let data: any = null
      if (contentType.includes('application/json')) {
        data = await response.json()
      } else {
        // non-JSON (HTML) response - capture for debugging
        const text = await response.text()
        console.error('Expected JSON but received:', text)
      }

      if (response.ok) {
        cleanForm()
        setSubmissionStatus('success')
        setDialogOpen(true)
      } else {
        console.error('Error creating incidencia', data)
        setSubmissionStatus('error')
        setDialogMsg('Rellene todos los campos')
        setDialogOpen(true)
      }
    } catch (err) {
      console.error('Network error', err)
      setSubmissionStatus('error')
      setDialogOpen(true)
    }
  }

  const handleDropdownChange = (item: DropdownItem, form_name: string) => {
    const { id, name } = item
    if (form_name === 'proceso_id') setSelectedProceso({ id, name })
      else setSelectedFuente({ id, name })
    handleSelectChange(form_name, id);
  }

  const renderTreeItems = (data: Array<TreeNode>, opcion = 'procesos') => {
    return data.map((e) => {
      const name = `${e.nombre || e.proceso || e.fuente || e.descripcion || String(e.id)}`
      const id = e.id
      const uniqueKey = opcion === 'procesos' ? 'p' + id : 'f' + id

      if (Array.isArray(e.children) && e.children.length === 0) {
        return (
          <DropdownMenuItem
            key={uniqueKey}
            onClick={() => opcion === 'procesos' ? handleDropdownChange({id, name}, 'proceso_id') : handleDropdownChange({id, name}, 'fuente_id')}
          >
            {name}
          </DropdownMenuItem>
        )
      }
      return (
        <div key={uniqueKey}>
          <div
            className="flex items-center justify-between hover:bg-accent hover:color-accent-foreground rounded-sm"
          >
            <DropdownMenuItem
              onClick={() => opcion === 'procesos' ? handleDropdownChange({id, name}, 'proceso_id') : handleDropdownChange({id, name}, 'fuente_id')}
              className='w-full'
            >
              {name}
            </DropdownMenuItem>

            {/* expandir */}
            <button
              onClick={() => toggleNode(id, opcion)}
              className="px-2"
            >
              {((opcion === 'fuentes' && openFuentesNodes[id]) || (opcion === 'procesos' && openProcesosNodes[id])) ? <TriangleDownIcon /> : <TriangleRightIcon />}
            </button>
          </div>
          {((opcion === 'fuentes' && openFuentesNodes[id]) || (opcion === 'procesos' && openProcesosNodes[id])) && (
            <div className='ml-4'>
              {renderTreeItems(e.children ?? [], opcion)}
            </div>
          )}
        </div>
      )
    })
  }

  const filterXSearch = (items: Array<TreeNode>, opcion = 'procesos') => {
    const search = opcion === 'procesos' ? searchProceso.toLowerCase() : searchFuente.toLowerCase()

    return items.reduce((acc: TreeNode[], item) => {
      const name = `${item.nombre || item.proceso || item.fuente || item.descripcion || String(item.id)}`.toLowerCase()

      let children: TreeNode[] = []
      if (Array.isArray(item.children)) {
        children = filterXSearch(item.children, opcion)
      }

      if (name.includes(search) || children.length > 0) {
        acc.push({
          ...item,
          children,
        })
      }

      return acc
    }, [])
  };

  const findEmployee = async () => {
    if (!documento) {
      return;
    }

    setFormErrors([])

    try {
      const response = await fetch(`incidencias/employee/${documento}`);
      const data = await response.json();

      if (data.success && data.codigo) {
        setFormData(prev => ({
          ...prev,
          colaborador: data.nombre || '',
          codigo_colaborador: data.codigo,
          oficina_id: String(data.oficina_id || ''),
        }));
        setAreasEmployee(data.areas)
      } else {
        setFormErrors(prev => ({
          ...prev,
          codigo_colaborador: 'Empleado no encontrado'
        }))
        setFormData(prev => ({
          ...prev,
          area_reporte: '',
          colaborador: '',
          codigo_colaborador: '',
        }));
        setAreasEmployee([])
      }
    } catch (error) {
      setFormErrors(prev => ({
        ...prev,
        codigo_colaborador: 'Error interno'
      }))
      setFormData(prev => ({
        ...prev,
        area_reporte: '',
        colaborador: '',
        codigo_colaborador: '',
      }));
      setAreasEmployee([])
    }
  }

  const cleanForm = () => {
    setFormData(initial_data)
    setDocumento('')
    setAreasEmployee([])
    setSelectedProceso({})
    setSelectedFuente({})
    setSearchProceso('')
    setSearchFuente('')
    setOpenProcesosNodes({})
    setOpenFuentesNodes({})
    setFormErrors([])
  }

  return (
    <div className="min-h-screen py-8 px-4">
      <div className="max-w-4xl mx-auto">
        <Card>
          <CardHeader>
            <CardTitle>Reporte de Incidencia</CardTitle>
            <CardDescription>Completa el formulario para registrar una nueva incidencia</CardDescription>
          </CardHeader>
          <CardContent>
            <form onSubmit={handleSubmit} className="space-y-8">
              {/* Información Básica */}
              <div>
                <h3 className="text-lg font-semibold mb-4">Información Básica</h3>
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label htmlFor="fecha_incidencia">Fecha y Hora del Evento</Label>
                    <Input
                      id="fecha_incidencia"
                      name="fecha_incidencia"
                      type="datetime-local"
                      value={formData.fecha_incidencia}
                      onChange={handleChange}
                      required
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="documento">Documento del Colaborador</Label>
                    <div className="flex">
                      <Input
                        aria-invalid={formErrors.codigo_colaborador? true : false}
                        error={formErrors.codigo_colaborador}
                        id="documento"
                        name="documento"
                        value={documento}
                        onChange={(e) => setDocumento(e.target.value)}
                        placeholder="Documento del colaborador"
                        required
                      />
                      <Button type='button' onClick={findEmployee}><MagnifyingGlassIcon /></Button>
                    </div>
                  </div>
                  <div className="col-span-2">
                    <Label htmlFor="colaborador">Colaborador</Label>
                    <Input
                      id="colaborador"
                      name="colaborador"
                      type="text"
                      value={formData.colaborador}
                      onChange={handleChange}
                      placeholder="Colaborador"
                      disabled
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="area_reporte">Área que Reporta (Ingrese su documento primero)</Label>
                    <Select value={formData.area_reporte} onValueChange={(value) => handleSelectChange('area_reporte', value)} required>
                      <SelectTrigger id="area_reporte">
                        <SelectValue placeholder="Área responsable" />
                      </SelectTrigger>
                      <SelectContent>
                        {areasEmployee && areasEmployee.map(area => (
                          <SelectItem key={area.id} value={area.id !== undefined ? String(area.id) : ''}>
                            {area.nombre}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="area_origen">Área de Origen de la Incidencia</Label>
                    <Select value={formData.area_origen} onValueChange={(value) => handleSelectChange('area_origen', value)} required>
                      <SelectTrigger id="area_origen">
                        <SelectValue placeholder="Área donde se originó" />
                      </SelectTrigger>
                      <SelectContent>
                        {props.oficinas && props.oficinas.map(oficina => (              
                          <SelectGroup key={oficina.id}>
                            <SelectLabel className='font-extrabold'>{oficina.nombre}</SelectLabel>
                            {props.areas && props.areas
                              .filter(area => area.oficina_id === oficina.id)
                              .map(area => (
                                <SelectItem key={area.id} value={area.id !== undefined ? String(area.id) : ''}>
                                  &nbsp;&nbsp;- {area.nombre}
                                </SelectItem>
                              ))}
                            <hr />
                          </SelectGroup>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
              </div>

              {/* Detalles de la Incidencia */}
              <div>
                <h3 className="text-lg font-semibold mb-4">Detalles de la Incidencia</h3>
                <div className="space-y-4">
                  <div className="card flex md:flex-row flex-col justify-between w-full gap-4">
                    <div className="card flex flex-col justify-content-center w-full gap-2">
                      <Label>¿En que Proceso se dió?</Label>
                      <DropdownMenu>
                        <DropdownMenuTrigger className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 h-9 px-4 py-2 has-[>svg]:px-3">
                          {selectedProceso.name || "Seleccionar proceso"}
                        </DropdownMenuTrigger>
                        <DropdownMenuContent className='relative overflow-hidden overflow-y-auto max-h-60 max-w-lvw'>
                          <Input
                            className='fixed z-10 bg-accent top-0 -right-3 left-0 w-[97%]'
                            key={'input_p'}
                            type="text"
                            placeholder="Buscar proceso..."
                            value={searchProceso}
                            onChange={(e) => setSearchProceso(e.target.value)}
                            onKeyDown={(e) => e.stopPropagation()}
                          />
                          <div className="mb-10"></div>
                          {props.procesos && props.procesos.length > 0 && renderTreeItems(searchProceso == "" ? props.procesos : filterXSearch(props.procesos))}
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </div>
                    <div className="card flex flex-col justify-content-center w-full gap-2">
                      <Label>Fuente de Riesgo</Label>
                      <DropdownMenu>
                        <DropdownMenuTrigger className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 h-9 px-4 py-2 has-[>svg]:px-3">
                          {selectedFuente.name || "Seleccionar fuente"}
                        </DropdownMenuTrigger>
                        <DropdownMenuContent className='overflow-y-auto max-h-60'>
                          <Input
                            type="text"
                            placeholder="Buscar fuente..."
                            value={searchFuente}
                            onChange={(e) => setSearchFuente(e.target.value)}
                            onKeyDown={(e) => e.stopPropagation()}
                          />
                          {props.fuentes && props.fuentes.length > 0 && renderTreeItems(searchFuente == "" ? props.fuentes : filterXSearch(props.fuentes, 'fuentes'), 'fuentes')}
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </div>
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="descripcion">Descripción</Label>
                    <Textarea
                      id="descripcion"
                      name="descripcion"
                      value={formData.descripcion}
                      onChange={handleChange}
                      placeholder="Describe la incidencia en detalle"
                      rows={4}
                      required
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="causa">Causa</Label>
                    <Textarea
                      id="causa"
                      name="causa"
                      value={formData.causa}
                      onChange={handleChange}
                      placeholder="¿Cuál fue la causa principal?"
                      rows={3}
                      required
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="efecto">Efecto</Label>
                    <Textarea
                      id="efecto"
                      name="efecto"
                      value={formData.efecto}
                      onChange={handleChange}
                      placeholder="¿Cuál fue el efecto o consecuencia?"
                      rows={3}
                      required
                    />
                  </div>
                </div>
              </div>

              {/* Archivos Adjuntos */}
              <div>
                <h3 className="text-lg font-semibold mb-4">Archivos Adjuntos</h3>
                <div className="space-y-4">
                  <div className="space-y-2">
                    <Label htmlFor="files">Seleccionar archivos</Label>
                    <Input
                      id="files"
                      name="files"
                      type="file"
                      multiple
                      onChange={handleFileChange}
                      accept=".pdf,.doc,.docx,.jpg,.jpeg,.png,.gif,.txt"
                    />
                    <p className="text-sm text-muted-foreground">
                      Tipos de archivo permitidos: PDF, DOC, DOCX, JPG, JPEG, PNG, GIF, TXT
                    </p>
                  </div>
                  {formData.files.length > 0 && (
                    <div className="space-y-2">
                      <Label>Archivos seleccionados:</Label>
                      <div className="space-y-1">
                        {formData.files.map((file, index) => (
                          <div key={index} className="flex items-center justify-between p-2 bg-muted rounded">
                            <span className="text-sm">{file.name} ({(file.size / 1024).toFixed(1)} KB)</span>
                            <Button
                              type="button"
                              variant="ghost"
                              size="sm"
                              onClick={() => removeFile(index)}
                              className="text-destructive hover:text-destructive"
                            >
                              ✕
                            </Button>
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                </div>
              </div>

              {/* Clasificación */}
              <div>
                <h3 className="text-lg font-semibold mb-4">Clasificación</h3>
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label htmlFor="frecuencia">Frecuencia</Label>
                    <Select value={formData.frecuencia} onValueChange={(value) => handleSelectChange('frecuencia', value)} required>
                      <SelectTrigger id="frecuencia">
                        <SelectValue placeholder="Selecciona la frecuencia" />
                      </SelectTrigger>
                      <SelectContent>
                        {props.frecuencias && props.frecuencias.map(frecuencia => (
                          <SelectItem key={frecuencia.id} value={frecuencia.id !== undefined ? String(frecuencia.id) : ''}>
                            {frecuencia.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="impacto_mon">Impacto (Monetario)</Label>
                    <Input
                      id="impacto_mon"
                      name="impacto_mon"
                      type="number"
                      value={formData.impacto_mon}
                      onChange={handleChange}
                      placeholder="Monto del impacto"
                      step="0.01"
                    />
                  </div>
                </div>
              </div>

              {/* Botones de acción */}
              <div className="flex gap-4 pt-6">
                <Button type="submit" className="flex-1">
                  Enviar reporte
                </Button>
                <Button type="button" onClick={() => cleanForm()} variant="outline" className="flex-1">
                  Limpiar
                </Button>
              </div>
            </form>
          </CardContent>
        </Card>
      </div>
      {/* Submission status dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>
              {submissionStatus === 'success' ? 'Reporte enviado' : submissionStatus === 'sending' ? 'Enviando...' : 'Error al enviar'}
            </DialogTitle>
            <DialogDescription>
              {submissionStatus === 'success' && 'El reporte se ha enviado correctamente.'}
              {submissionStatus === 'sending' && 'Enviando el reporte, por favor espere.'}
              {submissionStatus === 'error' && 'Ocurrió un error al enviar el reporte. Intente nuevamente.'}
              <p className='text-red-500'>
                {dialogMsg}
              </p>
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button onClick={() => setDialogOpen(false)}>
              OK
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}

export default Index