import { useState, useEffect, useCallback, useMemo } from 'react'
import { databases, DATABASE_ID, COLLECTIONS, Query, ID, isDemoMode } from '../lib/appwrite'

const DEMO_MODE = isDemoMode

function buildFiltersKey(filters = {}) {
  return JSON.stringify({
    limit: filters.limit ?? null,
    customerId: filters.customerId ?? null,
    assignedTo: filters.assignedTo ?? null,
    status: filters.status ?? null,
    type: filters.type ?? null,
    priority: filters.priority ?? null,
    woid: filters.woid ?? null,
  })
}

// Demo data for testing without Appwrite
const lastWeek = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)

const DEMO_WORKORDERS = [
  { 
    $id: 'dummy-10001', 
    woid: '10001', 
    topic: 'Kompletter Systemausfall - Server & Netzwerk',
    status: 'Assigned', 
    priority: 4, 
    type: 'Emergency Call', 
    systemType: 'Server',
    responseLevel: 'Backoffice',
    serviceType: 'On Site',
    customerName: 'Kunde A', 
    customerLocation: 'Hauptstraße 123, 12345 Musterstadt',
    assignedTo: 'user-max-id',
    assignedName: 'Max Mustermann', 
    requestedBy: 'Dr. Anna Schmidt',
    requestedFor: 'IT-Abteilung Kunde A',
    startDate: '30.12.2025',
    startTime: '0800',
    deadline: '31.12.2025',
    endTime: '1800',
    estimate: '480',
    mailCopyTo: 'admin@kunde-a.de, it@kunde-a.de',
    sendNotification: true,
    details: `KRITISCHER SYSTEMAUSFALL - SOFORTIGE BEARBEITUNG ERFORDERLICH

Problembeschreibung:
- Kompletter Serverausfall im Rechenzentrum
- Alle Server sind offline (keine Verbindung möglich)
- Netzwerk-Infrastruktur betroffen
- Keine Backup-Systeme verfügbar

Betroffene Systeme:
- Hauptserver (Windows Server 2022)
- Datenbankserver (SQL Server 2019)
- Fileserver
- Exchange Server
- Netzwerk-Switches

Auswirkungen:
- Keine E-Mail-Kommunikation möglich
- Alle Anwendungen offline
- Kein Zugriff auf Datenbanken
- Produktion steht still

Dringlichkeit: KRITISCH - Produktionsausfall

Erwartete Bearbeitungszeit: 8 Stunden
Benötigte Ressourcen: 2 Techniker, Hardware-Ersatzteile`,
    approvalStatus: 'approved',
    $createdAt: lastWeek.toISOString(),
    createdAt: lastWeek.toISOString()
  },
  { $id: '2', woid: '10002', title: 'Netzwerk Problem', description: 'WLAN funktioniert nicht', status: 'Occupied', priority: 3, type: 'Support', customerName: 'Kunde B', assignedName: 'Lisa S.', response: 'Remote', $createdAt: new Date().toISOString() },
  { $id: '3', woid: '10003', title: 'Software Installation', description: 'Office 365 Setup', status: 'Assigned', priority: 1, type: 'Installation', customerName: 'Kunde C', assignedName: 'Tom K.', response: 'Onsite', $createdAt: new Date().toISOString() },
  { $id: '4', woid: '10004', title: 'Drucker defekt', description: 'Papierstau', status: 'Awaiting', priority: 2, type: 'Hardware', customerName: 'Kunde D', assignedName: '', response: 'Pickup', $createdAt: new Date().toISOString() },
  { $id: '5', woid: '10005', title: 'Kritischer Serverausfall', description: 'Produktionsserver down', status: 'Open', priority: 4, type: 'Emergency', customerName: 'Kunde E', assignedName: 'Max M.', response: 'Onsite', $createdAt: new Date().toISOString() },
]

export function useWorkorders(filters = {}) {
  const [workorders, setWorkorders] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
  const filtersKey = useMemo(() => buildFiltersKey(filters), [
    filters.limit,
    filters.customerId,
    filters.assignedTo,
    filters.status,
    filters.type,
    filters.priority,
    filters.woid,
  ])

  const fetchWorkorders = useCallback(async () => {
    const activeFilters = JSON.parse(filtersKey)
    setLoading(true)
    
    if (DEMO_MODE) {
      // Filter demo data
      let filtered = [...DEMO_WORKORDERS]
      if (activeFilters.status?.length > 0) {
        filtered = filtered.filter(wo => activeFilters.status.includes(wo.status))
      }
      if (activeFilters.priority?.length > 0) {
        filtered = filtered.filter(wo => activeFilters.priority.includes(wo.priority))
      }
      if (activeFilters.woid) {
        filtered = filtered.filter(wo => String(wo.woid) === String(activeFilters.woid))
      }
      if (activeFilters.limit) {
        filtered = filtered.slice(0, activeFilters.limit)
      }
      setWorkorders(filtered)
      setLoading(false)
      return
    }
    
    try {
      const queries = [Query.orderDesc('$createdAt')]
      
      if (activeFilters.limit) {
        queries.push(Query.limit(activeFilters.limit))
      }
      
      // Appwrite Query.equal mit Array = OR-Match. Serverseitig filtern, damit
      // das Limit erst NACH dem Statusfilter greift (sonst wuerden archivierte
      // Tickets die neuesten Slots belegen und aktive verdraengen).
      if (activeFilters.status && activeFilters.status.length > 0) {
        queries.push(Query.equal('status', activeFilters.status))
      }

      if (activeFilters.type && activeFilters.type.length > 0) {
        queries.push(Query.equal('type', activeFilters.type))
      }

      if (activeFilters.priority && activeFilters.priority.length > 0) {
        queries.push(Query.equal('priority', activeFilters.priority))
      }
      
      if (activeFilters.customerId) {
        queries.push(Query.equal('customerId', activeFilters.customerId))
      }
      
      if (activeFilters.assignedTo) {
        queries.push(Query.equal('assignedTo', activeFilters.assignedTo))
      }

      // WOID-Direktsuche (z. B. Deep-Link aus den Leads: /tickets?woid=123)
      if (activeFilters.woid) {
        queries.push(Query.equal('woid', [String(activeFilters.woid)]))
      }

      // Debug: Zeige Collection ID
      if (import.meta.env.DEV) {
        console.log('📋 Fetching workorders:')
        console.log('  Database ID:', DATABASE_ID)
        console.log('  Collection ID:', COLLECTIONS.WORKORDERS)
        console.log('  Queries:', queries.length)
      }

      const response = await databases.listDocuments(
        DATABASE_ID,
        COLLECTIONS.WORKORDERS,
        queries
      )

      setWorkorders(response.documents)
      setError(null)
    } catch (err) {
      let errorMessage = err.message || 'Fehler beim Laden der Tickets'
      
      // Bessere Fehlermeldungen
      if (err.code === 401 || errorMessage.includes('not authorized') || errorMessage.includes('Unauthorized')) {
        errorMessage = 'Berechtigung fehlt: Bitte überprüfe die Read-Berechtigungen der Collection in Appwrite. Die Collection muss "Users" oder "Any" als Read-Berechtigung haben.'
      } else if (errorMessage.includes('Collection') && errorMessage.includes('not found')) {
        errorMessage = 'Collection nicht gefunden: Bitte überprüfe die Collection ID in der Konfiguration.'
      }
      
      setError(errorMessage)
      console.error('Error fetching workorders:', err)
    } finally {
      setLoading(false)
    }
  }, [filtersKey])

  useEffect(() => {
    fetchWorkorders()
  }, [fetchWorkorders])

  const resolveAutomaticTicketFields = async (requestedAssignee = '') => {
    const [allTicketsResponse, employeesResponse] = await Promise.all([
      databases.listDocuments(
        DATABASE_ID,
        COLLECTIONS.WORKORDERS,
        [Query.limit(5000)]
      ),
      databases.listDocuments(
        DATABASE_ID,
        COLLECTIONS.EMPLOYEES,
        [Query.orderAsc('displayName'), Query.limit(500)]
      ),
    ])

    const allTickets = allTicketsResponse.documents || []
    const employees = employeesResponse.documents || []
    const maxWoid = allTickets.reduce((highest, ticket) => {
      const numericId = Number.parseInt(ticket.woid, 10)
      return Number.isFinite(numericId) ? Math.max(highest, numericId) : highest
    }, 9999)

    let assignee = requestedAssignee
      ? employees.find((employee) => employee.userId === requestedAssignee)
      : null

    if (!assignee && employees.length > 0) {
      const finishedStatuses = new Set(['Closed', 'Completed', 'Cancelled', 'Done'])
      const activeCounts = new Map(employees.map((employee) => [employee.userId, 0]))
      for (const ticket of allTickets) {
        if (!ticket.assignedTo || finishedStatuses.has(ticket.status)) continue
        if (activeCounts.has(ticket.assignedTo)) {
          activeCounts.set(ticket.assignedTo, activeCounts.get(ticket.assignedTo) + 1)
        }
      }
      assignee = [...employees].sort((left, right) => {
        const loadDifference = activeCounts.get(left.userId) - activeCounts.get(right.userId)
        if (loadDifference !== 0) return loadDifference
        return (left.displayName || '').localeCompare(right.displayName || '', 'de')
      })[0]
    }

    return {
      woid: String(maxWoid + 1),
      assignedTo: assignee?.userId || '',
      assignedName: assignee?.displayName || '',
    }
  }

  const createWorkorder = async (data) => {
    if (DEMO_MODE) {
      // Finde höchste WOID und +1
      const maxWoid = workorders.length > 0 
        ? Math.max(...workorders.map(wo => parseInt(wo.woid)).filter(w => !isNaN(w)))
        : 9999;
      const nextWoid = maxWoid + 1;
      
      const newWo = { ...data, $id: Date.now().toString(), woid: nextWoid.toString(), status: 'Open', $createdAt: new Date().toISOString() }
      setWorkorders(prev => [newWo, ...prev])
      return { success: true, data: newWo }
    }
    
    try {
      // Validierung: Prüfe required fields
      if (!data.topic || data.topic.trim() === '') {
        return { success: false, error: 'Das Feld "Topic" ist erforderlich.' }
      }

      const automatic = await resolveAutomaticTicketFields(data.assignedTo)
      const autoStatus = automatic.assignedTo ? 'Assigned' : 'Open'
      
      // Bereite Daten für Appwrite vor
      const workorderData = {
        // Required fields
        topic: data.topic.trim(),
        status: autoStatus,
        priority: typeof data.priority === 'number' ? data.priority : parseInt(data.priority) || 1,
        woid: automatic.woid,
        
        // Optional fields - nur senden wenn vorhanden
        type: data.type || '',
        systemType: data.systemType || '',
        responseLevel: data.responseLevel || '',
        serviceType: data.serviceType || 'Remote',
        customerId: data.customerId || '',
        assignedTo: automatic.assignedTo,
        assignedName: automatic.assignedName,
        requestedBy: data.requestedBy || '',
        requestedFor: data.requestedFor || '',
        startDate: data.startDate || '',
        startTime: data.startTime || '',
        deadline: data.deadline || '',
        endTime: data.endTime || '',
        estimate: data.estimate || '',
        mailCopyTo: data.mailCopyTo || '',
        sendNotification: data.sendNotification || false,
        details: data.details || '',
        
        // Datetime field
        createdAt: new Date().toISOString()
      }

      // Entferne leere Strings (außer für required fields)
      Object.keys(workorderData).forEach(key => {
        if (workorderData[key] === '' && key !== 'topic' && key !== 'status') {
          delete workorderData[key]
        }
      })

      console.log('Creating workorder with data:', workorderData)

      const response = await databases.createDocument(
        DATABASE_ID,
        COLLECTIONS.WORKORDERS,
        ID.unique(),
        workorderData
      )
      setWorkorders(prev => [response, ...prev])
      return { success: true, data: response }
    } catch (err) {
      console.error('Error creating workorder:', err)
      let errorMessage = err.message || 'Fehler beim Erstellen des Tickets'
      
      // Bessere Fehlermeldungen
      if (err.code === 400 || errorMessage.includes('Bad Request')) {
        errorMessage = 'Ungültige Daten: Bitte überprüfe, ob alle Pflichtfelder ausgefüllt sind und die Daten korrekt sind. Details: ' + (err.message || 'Unbekannter Fehler')
      } else if (errorMessage.includes('required') || errorMessage.includes('missing')) {
        errorMessage = 'Pflichtfelder fehlen: Bitte fülle alle erforderlichen Felder aus.'
      }
      
      return { success: false, error: errorMessage }
    }
  }

  const updateWorkorder = async (id, data) => {
    if (DEMO_MODE) {
      setWorkorders(prev => prev.map(wo => wo.$id === id ? { ...wo, ...data } : wo))
      return { success: true }
    }
    
    try {
      // Status-Automatik beim Update:
      // Wenn assignedTo gesetzt wird → Status = "Assigned"
      // Wenn assignedTo entfernt wird UND Status = "Assigned" → Status = "Open"
      const updateData = { ...data }
      if ('assignedTo' in updateData) {
        if (updateData.assignedTo && updateData.assignedTo !== '') {
          // Mitarbeiter zugewiesen → Status auf "Assigned" setzen
          if (!updateData.status) {
            updateData.status = 'Assigned'
          }
        } else if (!updateData.status) {
          // Keine Zuweisung mehr → Status auf "Open" setzen (nur wenn nicht explizit anders gesetzt)
          updateData.status = 'Open'
        }
      }
      
      const response = await databases.updateDocument(
        DATABASE_ID,
        COLLECTIONS.WORKORDERS,
        id,
        updateData
      )
      setWorkorders(prev => 
        prev.map(wo => wo.$id === id ? response : wo)
      )
      return { success: true, data: response }
    } catch (err) {
      return { success: false, error: err.message }
    }
  }

  const deleteWorkorder = async (id) => {
    if (DEMO_MODE) {
      setWorkorders(prev => prev.filter(wo => wo.$id !== id))
      return { success: true }
    }
    
    try {
      await databases.deleteDocument(
        DATABASE_ID,
        COLLECTIONS.WORKORDERS,
        id
      )
      setWorkorders(prev => prev.filter(wo => wo.$id !== id))
      return { success: true }
    } catch (err) {
      return { success: false, error: err.message }
    }
  }

  return {
    workorders,
    loading,
    error,
    refresh: fetchWorkorders,
    createWorkorder,
    updateWorkorder,
    deleteWorkorder
  }
}
