import { useRef, useState } from 'react'
import {
  Alert,
  Box,
  Button,
  CircularProgress,
  Divider,
  Typography,
} from '@mui/material'
import { ArrowRight, Bookmark, Save, Search } from 'lucide-react'
import { useNavigate } from 'react-router'
import { useQueryClient } from '@tanstack/react-query'
import {
  NeedBuilderProgress,
  NeedInput,
  VoiceNeedInput,
  WeightingEditor,
  NeedCardPreview,
  NeedBuilderErrorState,
} from '../../components/demand'
import { aiService } from '../../services/aiService'
import { needService } from '../../services/needService'
import { weightingService } from '../../services/weightingService'
import { NeedBuilderStep } from '../../domain/needBuilder'
import type { ParseNeedResult, ParsedNeedCriteria, WeightingKey } from '../../domain/needBuilder'
import { AssetType } from '../../domain/enums'
import type { CreateNeedInput } from '../../domain/need'

// ── Helpers ───────────────────────────────────────────────────────────────────

const ASSET_LABELS_TEXT: Record<string, string> = {
  OFFICE: 'Bürofläche', RETAIL: 'Retail-Fläche', LOGISTICS: 'Logistikfläche',
  PRODUCTION: 'Produktionsfläche', LIGHT_INDUSTRIAL: 'Gewerbefläche', MIXED: 'gemischte Fläche',
}

function generateSummary(c: ParsedNeedCriteria): string {
  const parts: string[] = []
  if (c.assetType) parts.push(`Suche ${ASSET_LABELS_TEXT[c.assetType] ?? c.assetType}`)
  if (c.areaRange && (c.areaRange.min > 0 || c.areaRange.max > 0))
    parts.push(`${c.areaRange.min}–${c.areaRange.max} m²`)
  if (c.preferredLocations?.length) parts.push(`in ${c.preferredLocations.join(', ')}`)
  if (c.budgetRange?.maxPerSqm) parts.push(`Budget max. CHF ${c.budgetRange.maxPerSqm}/m²`)
  if (c.timing?.earliestMoveIn) parts.push(`ab ${c.timing.earliestMoveIn}`)
  if (c.mustHaveCriteria?.length) parts.push(`Must-haves: ${c.mustHaveCriteria.join(', ')}`)
  return parts.join(', ')
}

function buildNeedInput(
  criteria: ParsedNeedCriteria,
  weights: Record<WeightingKey, number>,
  needTitle: string,
  overallConfidence: number,
  status: 'DRAFT' | 'ACTIVE',
): CreateNeedInput {
  return {
    companyName: needTitle || criteria.companyName || 'Neue Suche',
    assetType: criteria.assetType ?? AssetType.UNKNOWN,
    requiredArea: criteria.areaRange ?? { min: 0, max: 0 },
    preferredLocations: criteria.preferredLocations ?? [],
    budgetRange: criteria.budgetRange ?? { maxPerSqm: 0, currency: 'CHF' },
    timing: {
      earliestMoveIn: criteria.timing?.earliestMoveIn ?? '',
      latestMoveIn: criteria.timing?.latestMoveIn ?? criteria.timing?.earliestMoveIn ?? '',
      contractDurationMonths: criteria.timing?.contractDurationMonths,
      flexibleTiming: criteria.timing?.flexibleTiming ?? true,
    },
    weightingProfile: weights,
    confidenceInCriteria: overallConfidence,
    status,
    mustCriteriaText: criteria.mustHaveCriteria ?? [],
    notes: criteria.notes,
    extractedFromText: undefined,
  }
}

// ── Action intent ─────────────────────────────────────────────────────────────

type ActionIntent = 'search' | 'save-profile'

// ── Page ──────────────────────────────────────────────────────────────────────

export default function AISearch() {
  const navigate = useNavigate()
  const queryClient = useQueryClient()

  const [step, setStep] = useState<typeof NeedBuilderStep[keyof typeof NeedBuilderStep]>(NeedBuilderStep.IDLE)
  const [intent, setIntent] = useState<ActionIntent>('search')
  const [inputText, setInputText] = useState('')
  const [isAutoGen, setIsAutoGen] = useState(false)
  const [criteria, setCriteria] = useState<ParsedNeedCriteria>({})
  const [parseResult, setParseResult] = useState<ParseNeedResult | null>(null)
  const [editedCriteria, setEditedCriteria] = useState<ParsedNeedCriteria | null>(null)
  const [weights, setWeights] = useState<Record<WeightingKey, number>>(weightingService.getDefaultWeights())
  const [weightingKey, setWeightingKey] = useState(0)
  const [needTitle, setNeedTitle] = useState('')
  const [error, setError] = useState<string | null>(null)

  const isManualTextRef = useRef(false)

  function handleCriteriaChange(next: ParsedNeedCriteria) {
    setCriteria(next)
    if (!isManualTextRef.current) {
      const summary = generateSummary(next)
      setInputText(summary)
      setIsAutoGen(!!summary)
    }
  }

  function handleTextChange(text: string) {
    isManualTextRef.current = text !== ''
    setIsAutoGen(false)
    setInputText(text)
  }

  async function handleAiAutofill() {
    setStep(NeedBuilderStep.PARSING)
    setError(null)
    try {
      const resp = await aiService.parseNeed(inputText)
      const result = resp.data
      setParseResult(result)
      setCriteria({ ...result.extractedCriteria })
      setWeights(result.suggestedWeights as Record<WeightingKey, number>)
      setWeightingKey(k => k + 1)
      isManualTextRef.current = false
      setInputText('')
      setIsAutoGen(false)
      setStep(NeedBuilderStep.IDLE)
    } catch {
      setError('Die KI-Analyse ist fehlgeschlagen.')
      setStep(NeedBuilderStep.ERROR)
    }
  }

  // Resolve criteria (parse text if needed), then either search or show save preview
  async function handleAction(chosenIntent: ActionIntent) {
    setIntent(chosenIntent)
    setError(null)

    let resolved: ParsedNeedCriteria = criteria
    let resolvedResult: ParseNeedResult | null = parseResult

    if (!hasStructuredData && inputText.trim()) {
      setStep(NeedBuilderStep.PARSING)
      try {
        const resp = await aiService.parseNeed(inputText)
        resolved = resp.data.extractedCriteria
        resolvedResult = resp.data
        setCriteria(resolved)
        setWeights(resp.data.suggestedWeights as Record<WeightingKey, number>)
        setWeightingKey(k => k + 1)
        isManualTextRef.current = false
        setInputText('')
        setIsAutoGen(false)
        setParseResult(resp.data)
      } catch {
        setError('Die KI-Analyse ist fehlgeschlagen.')
        setStep(NeedBuilderStep.ERROR)
        return
      }
    }

    if (chosenIntent === 'search') {
      // Save as DRAFT and navigate immediately
      setStep(NeedBuilderStep.SAVING)
      try {
        const conf = resolvedResult
          ? Object.values(resolvedResult.confidenceByField).reduce((s, v) => s + v, 0) /
            Math.max(Object.values(resolvedResult.confidenceByField).length, 1)
          : 0.5
        const input = buildNeedInput(resolved, weights, needTitle, conf, 'DRAFT')
        const created = await needService.create(input)
        await queryClient.invalidateQueries({ queryKey: ['needs'] })
        await queryClient.invalidateQueries({ queryKey: ['matches'] })
        navigate('/demand/results', { state: { fromNeedBuilder: true, activeNeedId: created.data.id } })
      } catch {
        setError('Suche fehlgeschlagen.')
        setStep(NeedBuilderStep.ERROR)
      }
      return
    }

    // save-profile: show preview step
    const confidenceByField: Record<string, number> = resolvedResult?.confidenceByField ?? {}
    if (!resolvedResult) {
      if (resolved.assetType) confidenceByField.assetType = 1.0
      if (resolved.areaRange?.min) confidenceByField.areaRange = 1.0
      if (resolved.preferredLocations?.length) confidenceByField.preferredLocations = 1.0
      if (resolved.budgetRange?.maxPerSqm) confidenceByField.budgetRange = 1.0
      if (resolved.timing?.earliestMoveIn) confidenceByField.timing = 1.0
    }
    setEditedCriteria({ ...resolved })
    setParseResult(resolvedResult ?? {
      extractedCriteria: resolved,
      confidenceByField,
      missingFields: [],
      assumptions: [],
      suggestedWeights: weights,
      followUpQuestionCandidates: [],
      rawSummary: 'Manuell eingegeben',
      promptVersion: 'manual',
      schemaVersion: '1.0',
    })
    setStep(NeedBuilderStep.READY_TO_SAVE)
  }

  async function handleSaveProfile() {
    if (!editedCriteria || !parseResult) return
    setStep(NeedBuilderStep.SAVING)
    const entries = Object.entries(parseResult.confidenceByField)
    const conf = entries.length > 0 ? entries.reduce((s, [, v]) => s + v, 0) / entries.length : 0
    try {
      const input = buildNeedInput(editedCriteria, weights, needTitle, conf, 'ACTIVE')
      const created = await needService.create(input)
      await queryClient.invalidateQueries({ queryKey: ['needs'] })
      await queryClient.invalidateQueries({ queryKey: ['matches'] })
      navigate('/demand/results', { state: { fromNeedBuilder: true, activeNeedId: created.data.id } })
    } catch {
      setError('Speichern fehlgeschlagen.')
      setStep(NeedBuilderStep.ERROR)
    }
  }

  function handleRetry() {
    setStep(NeedBuilderStep.IDLE)
    setError(null)
    setParseResult(null)
    setEditedCriteria(null)
  }

  const hasStructuredData = !!(
    criteria.assetType ||
    (criteria.areaRange?.min ?? 0) > 0 ||
    (criteria.preferredLocations?.length ?? 0) > 0
  )
  const canProceed = hasStructuredData || inputText.trim().length > 0
  const isProcessing = step === NeedBuilderStep.PARSING || step === NeedBuilderStep.SAVING
  const isSaveStep = step === NeedBuilderStep.READY_TO_SAVE || step === NeedBuilderStep.SAVING

  const overallConfidence = parseResult
    ? (() => {
        const entries = Object.entries(parseResult.confidenceByField)
        return entries.length > 0 ? entries.reduce((s, [, v]) => s + v, 0) / entries.length : 0
      })()
    : 0

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}>
      {/* Header */}
      <Box sx={{ bgcolor: 'white', borderBottom: '1px solid #e2e8f0', px: 3, py: 2, flexShrink: 0 }}>
        <Typography variant="h5" sx={{ fontWeight: 700 }}>Flächensuche</Typography>
        <Typography variant="body2" color="text.secondary">
          Sprechen, schreiben oder Felder ausfüllen — dann sofort suchen oder als Suchprofil speichern
        </Typography>
      </Box>

      <NeedBuilderProgress step={step} />

      <Box sx={{ flex: 1, overflowY: 'auto', px: 3, py: 3 }}>

        {/* ── IDLE: full form ── */}
        {(step === NeedBuilderStep.IDLE || step === NeedBuilderStep.PARSING) && (
          <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, maxWidth: 1200, mx: 'auto' }}>

            <VoiceNeedInput
              text={inputText}
              onTextChange={handleTextChange}
              isAutoGen={isAutoGen}
              onAiSubmit={handleAiAutofill}
              isAnalyzing={step === NeedBuilderStep.PARSING}
            />

            <Box className="grid grid-cols-2 gap-4" sx={{ alignItems: 'start' }}>
              <NeedInput criteria={criteria} onCriteriaChange={handleCriteriaChange} />
              <WeightingEditor
                key={weightingKey}
                weights={weights}
                onChange={setWeights}
                assetType={criteria.assetType}
              />
            </Box>

            {/* Action bar */}
            <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
              <Button
                variant="contained"
                size="large"
                disabled={!canProceed || isProcessing}
                onClick={() => handleAction('search')}
                endIcon={
                  isProcessing && intent === 'search'
                    ? <CircularProgress size={18} color="inherit" />
                    : <Search size={18} />
                }
                sx={{
                  flex: 1,
                  py: 1.5,
                  bgcolor: '#1e3a5f',
                  '&:hover': { bgcolor: '#162d4a' },
                  fontSize: 15,
                  fontWeight: 600,
                  textTransform: 'none',
                }}
              >
                {isProcessing && intent === 'search' ? 'Sucht…' : 'Jetzt suchen'}
              </Button>

              <Divider orientation="vertical" flexItem sx={{ mx: 0.5 }} />

              <Button
                variant="outlined"
                size="large"
                disabled={!canProceed || isProcessing}
                onClick={() => handleAction('save-profile')}
                startIcon={<Bookmark size={16} />}
                endIcon={
                  isProcessing && intent === 'save-profile'
                    ? <CircularProgress size={18} color="inherit" />
                    : <ArrowRight size={18} />
                }
                sx={{
                  py: 1.5,
                  fontSize: 15,
                  fontWeight: 500,
                  textTransform: 'none',
                  whiteSpace: 'nowrap',
                }}
              >
                {isProcessing && intent === 'save-profile' ? 'Analysiert…' : 'Als Suchprofil speichern'}
              </Button>
            </Box>

            <Alert severity="info" sx={{ mt: -1 }}>
              <strong>Jetzt suchen</strong> liefert sofortige Ergebnisse.{' '}
              <strong>Als Suchprofil speichern</strong> legt einen dauerhaften Bedarf an, der automatisch mit neuen Angeboten abgeglichen wird — auch in Zukunft.
            </Alert>
          </Box>
        )}

        {/* ── Preview + Save as Profile ── */}
        {isSaveStep && parseResult && editedCriteria && (
          <Box sx={{ maxWidth: 1200, mx: 'auto' }}>
            <Alert severity="success" sx={{ mb: 3 }}>
              Dieses Suchprofil wird als aktiver Bedarf gespeichert und erscheint automatisch im Match Center der Verwaltung.
            </Alert>
            <NeedCardPreview
              criteria={editedCriteria}
              weights={weights}
              confidenceByField={parseResult.confidenceByField}
              missingFields={parseResult.missingFields}
              needTitle={needTitle}
              onNeedTitleChange={setNeedTitle}
            />
            <Box sx={{ maxWidth: 720, mx: 'auto', display: 'flex', justifyContent: 'space-between', mt: 3 }}>
              <Button
                variant="outlined"
                onClick={() => setStep(NeedBuilderStep.IDLE)}
                disabled={step === NeedBuilderStep.SAVING}
              >
                ← Zurück
              </Button>
              <Button
                variant="contained"
                onClick={handleSaveProfile}
                disabled={step === NeedBuilderStep.SAVING}
                endIcon={
                  step === NeedBuilderStep.SAVING
                    ? <CircularProgress size={16} color="inherit" />
                    : <Save size={16} />
                }
                sx={{ bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#162d4a' }, textTransform: 'none' }}
              >
                {step === NeedBuilderStep.SAVING
                  ? 'Wird gespeichert…'
                  : overallConfidence < 0.6
                    ? 'Als Entwurf speichern'
                    : 'Suchprofil speichern & Matching starten'}
              </Button>
            </Box>
          </Box>
        )}

        {/* ── Error ── */}
        {step === NeedBuilderStep.ERROR && (
          <NeedBuilderErrorState message={error ?? 'Unbekannter Fehler'} onRetry={handleRetry} />
        )}
      </Box>
    </Box>
  )
}
