"use client"
import { useEffect, useMemo, useState, useCallback, Suspense, lazy } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import { api, TelemetryDto, PowerOutageSummaryDto } from '@/lib/api'
import { persianToGregorian, getCurrentPersianDay, getCurrentPersianYear, getCurrentPersianMonth, getPreviousPersianDay, getNextPersianDay } from '@/lib/date/persian-date'
import { formatPersianDate, ensureDateFormat } from '@/lib/format/persian-date'
import { TABS, TabType } from '@/features/daily-report'
import { detectDataGaps } from '@/features/daily-report/utils'
import { BarChart3, CalendarIcon, ChevronRight } from 'lucide-react'
import Loading from '@/components/Loading'
import { SummaryTab } from '@/components/daily-report'
import { fetchForecastWeather, isToday as checkIsToday, WeatherData } from '@/features/weather'
import { Tabs, Button } from '@/components/common'
import { DateNavigation } from '@/components/navigation'
import { usePullToRefresh } from '@/hooks/usePullToRefresh'
import { AppShell } from '@/components/layout'

// Lazy load heavy components
const ChartsTab = lazy(() => import('@/components/daily-report/ChartsTab').then(m => ({ default: m.ChartsTab })))
const WeatherTab = lazy(() => import('@/components/daily-report/WeatherTab').then(m => ({ default: m.WeatherTab })))
const AnalysisTab = lazy(() => import('@/components/daily-report/AnalysisTab').then(m => ({ default: m.AnalysisTab })))

function DailyReportContent() {
    const router = useRouter()
    const searchParams = useSearchParams()
    const [telemetry, setTelemetry] = useState<TelemetryDto[]>([])
    const [loading, setLoading] = useState(true)
    const [activeTab, setActiveTab] = useState<TabType>('summary')
    const [forecastWeather, setForecastWeather] = useState<WeatherData | null>(null)
    const [forecastWeatherLoading, setForecastWeatherLoading] = useState(false)
    const [visibleParams, setVisibleParams] = useState<string[] | null>(null)
    const [powerOutageSummary, setPowerOutageSummary] = useState<PowerOutageSummaryDto | null>(null)
    const [powerOutageLoading, setPowerOutageLoading] = useState(false)
    
    // Map summary param to chart key
    const paramToChartKey = useCallback((param: string): string => {
        const mapping: Record<string, string> = {
            temperature: 'temp',
            humidity: 'hum',
            gas: 'gas',
            soil: 'soil',
            lux: 'lux',
        }
        return mapping[param] || param
    }, [])

    // Handle card click: switch to charts tab and scroll to chart
    const handleCardClick = useCallback((param: string) => {
        const chartKey = paramToChartKey(param)
        setActiveTab('charts')
        
        // Wait for tab to switch and chart to render, then scroll
        setTimeout(() => {
            const chartElement = document.getElementById(`chart-${chartKey}`)
            if (chartElement) {
                chartElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
            }
        }, 100)
    }, [paramToChartKey])
    
    const deviceId = Number(searchParams.get('deviceId') ?? '1')
    const dateParam = searchParams.get('date') ?? formatPersianDate(getCurrentPersianYear(), getCurrentPersianMonth(), getCurrentPersianDay())

    const selectedDate = useMemo(() => {
        if (!dateParam) return null
        try {
            const decodedDate = decodeURIComponent(dateParam)
            // Ensure date is in yyyy/MM/dd format
            return ensureDateFormat(decodedDate)
        } catch (error) {
            console.error('Error decoding date parameter:', error)
            return null
        }
    }, [dateParam])

    // Navigate to previous day
    const goToPreviousDay = useCallback(() => {
        if (!selectedDate) return
        const prevDay = getPreviousPersianDay(selectedDate)
        if (prevDay) {
            router.push(`/daily-report?deviceId=${deviceId}&date=${encodeURIComponent(prevDay)}`)
        }
    }, [selectedDate, deviceId, router])

    // Navigate to next day
    const goToNextDay = useCallback(() => {
        if (!selectedDate) return
        const nextDay = getNextPersianDay(selectedDate)
        if (nextDay) {
            router.push(`/daily-report?deviceId=${deviceId}&date=${encodeURIComponent(nextDay)}`)
        }
    }, [selectedDate, deviceId, router])

    // Navigate to calendar to select a date
    const goToCalendar = useCallback(() => {
        router.push(`/calendar?deviceId=${deviceId}`)
    }, [deviceId, router])

    const loadData = useCallback(async () => {
        if (!selectedDate) {
            setLoading(false)
            return
        }

        setLoading(true)

        try {
            const [year, month, day] = selectedDate.split('/').map(Number)
            const startDate = persianToGregorian(year, month, day)
            startDate.setHours(0, 0, 0, 0)
            const endDate = new Date(startDate)
            endDate.setHours(23, 59, 59, 999)
            
            const startUtc = startDate.toISOString()
            const endUtc = endDate.toISOString()

            const result = await api.listTelemetry({ deviceId, startUtc, endUtc, pageSize: 100000 })
            setTelemetry(result.items)

            console.log(result.items)
            // Load visible params from server (controls which parameters are shown)
            try {
                const params = await api.getDisplayParameters(deviceId)
                setVisibleParams(params ?? null)
            } catch (err) {
                console.error('Error loading display parameters:', err)
                setVisibleParams(['gas', 'temperature', 'humidity', 'lux'])
            }
        } catch (error) {
            console.error('Error loading telemetry:', error)
        } finally {
            setLoading(false)
        }
    }, [deviceId, selectedDate])

    // Load power outage summary
    useEffect(() => {
        if (!selectedDate) {
            setPowerOutageSummary(null)
            return
        }

        const loadPowerOutage = async () => {
            setPowerOutageLoading(true)
            try {
                const [year, month, day] = selectedDate.split('/').map(Number)
                const startDate = persianToGregorian(year, month, day)
                startDate.setHours(0, 0, 0, 0)
                const endDate = new Date(startDate)
                endDate.setHours(23, 59, 59, 999)

                const startUtc = startDate.toISOString()
                const endUtc = endDate.toISOString()

                const summary = await api.getPowerOutageSummary(deviceId, startUtc, endUtc)
                setPowerOutageSummary(summary)
            } catch (error) {
                console.error('Error loading power outage summary:', error)
                setPowerOutageSummary(null)
            } finally {
                setPowerOutageLoading(false)
            }
        }

        loadPowerOutage()
    }, [deviceId, selectedDate])

    // Pull-to-refresh for mobile
    usePullToRefresh(loadData)

    useEffect(() => {
        // Reset states when date or device changes
        loadData()
    }, [loadData, deviceId, selectedDate])

    // Load forecast weather data when selectedDate is today - lazy load after main data is loaded
    useEffect(() => {
        if (!selectedDate || loading) {
            setForecastWeather(null)
            setForecastWeatherLoading(false)
            return
        }

        const isTodayDate = checkIsToday(selectedDate)
        
        if (isTodayDate) {
            // Delay fetch to ensure page is fully loaded first
            setForecastWeatherLoading(true)
            setForecastWeather(null)
            
            // Use setTimeout to ensure page is fully rendered before fetching
            const timer = setTimeout(() => {
                fetchForecastWeather()
                    .then(setForecastWeather)
                    .catch((error) => {
                        console.error('Error loading forecast weather:', error)
                        setForecastWeather(null)
                    })
                    .finally(() => {
                        setForecastWeatherLoading(false)
                    })
            }, 100) // Small delay to ensure page is rendered
            
            return () => clearTimeout(timer)
        } else {
            setForecastWeather(null)
            setForecastWeatherLoading(false)
        }
    }, [selectedDate, loading])

    const sortedTelemetry = useMemo(() => {
        return [...telemetry].sort((a, b) => {
            const aTime = a.serverTimestampUtc || a.timestampUtc
            const bTime = b.serverTimestampUtc || b.timestampUtc
            return new Date(aTime).getTime() - new Date(bTime).getTime()
        })
    }, [telemetry])

    // Data arrays
    const soil = useMemo(() => sortedTelemetry.map(t => Number(t.soilPercent ?? 0)), [sortedTelemetry])
    const temp = useMemo(() => sortedTelemetry.map(t => Number(t.temperatureC ?? 0)), [sortedTelemetry])
    const hum = useMemo(() => sortedTelemetry.map(t => Number(t.humidityPercent ?? 0)), [sortedTelemetry])
    const gas = useMemo(() => sortedTelemetry.map(t => Number(t.gasPPM ?? 0)), [sortedTelemetry])
    const lux = useMemo(() => sortedTelemetry.map(t => Number(t.lux ?? 0)), [sortedTelemetry])

    // Latest values for live summary
    const latestValues = useMemo(() => ({
        temperature: temp.length > 0 ? temp.at(-1) ?? 0 : 0,
        humidity: hum.length > 0 ? hum.at(-1) ?? 0 : 0,
        soil: soil.length > 0 ? soil.at(-1) ?? 0 : 0,
        gas: gas.length > 0 ? gas.at(-1) ?? 0 : 0,
        lux: lux.length > 0 ? lux.at(-1) ?? 0 : 0,
    }), [temp, hum, soil, gas, lux])

    // Last updated time from the most recent telemetry entry
    const lastUpdated = useMemo(() => {
        if (sortedTelemetry.length === 0) return undefined
        const lastTimestamp = sortedTelemetry.at(-1)?.serverTimestampUtc || sortedTelemetry.at(-1)?.timestampUtc
        if (!lastTimestamp) return undefined
        const date = new Date(lastTimestamp)
        const hours = String(date.getHours()).padStart(2, '0')
        const minutes = String(date.getMinutes()).padStart(2, '0')
        const seconds = String(date.getSeconds()).padStart(2, '0')
        return `${hours}:${minutes}:${seconds}`
    }, [sortedTelemetry])

    // Detect data gaps in the full day data
    const dataGaps = useMemo(() => {
        const timestamps = sortedTelemetry.map(t => t.serverTimestampUtc || t.timestampUtc)
        return detectDataGaps(timestamps, 30) // 30 minutes threshold
    }, [sortedTelemetry])

    if (loading) {
        return <Loading message="در حال بارگذاری داده‌ها..." />
    }

    if (!selectedDate) {
        return (
            <AppShell
                pageTitle="گزارش روزانه"
                pageIcon={BarChart3}
                iconGradient="from-indigo-500 to-purple-600"
            >
                <div className="flex items-center justify-center p-4">
                    <div className="text-center">
                        <CalendarIcon className="w-12 h-12 text-red-500 mx-auto mb-4" />
                        <div className="text-lg text-red-600 mb-4">تاریخ انتخاب نشده است</div>
                        <Button
                            onClick={goToCalendar}
                            variant="outline"
                            icon={ChevronRight}
                        >
                            بازگشت به تقویم
                        </Button>
                    </div>
                </div>
            </AppShell>
        )
    }

    return (
        <AppShell
            pageTitle="گزارش روزانه"
            pageIcon={BarChart3}
            pageInfo={selectedDate}
            iconGradient="from-indigo-500 to-purple-600"
        >
            <div className="space-y-6">
                {/* Date Navigation Buttons */}
                <DateNavigation
                    selectedDate={selectedDate}
                    onPrevious={goToPreviousDay}
                    onNext={goToNextDay}
                    onCalendar={goToCalendar}
                />

                {/* Tabs */}
                <Tabs
                    tabs={TABS}
                    activeTab={activeTab}
                    setActiveTab={setActiveTab}
                    className="md:mx-0 mx-[-1rem] md:rounded-xl rounded-none"
                >
                    {{
                        summary: <SummaryTab temperature={temp} humidity={hum} soil={soil} gas={gas} lux={lux} forecastWeather={forecastWeather} forecastWeatherLoading={forecastWeatherLoading} onCardClick={handleCardClick} visibleParams={visibleParams} powerOutageSummary={powerOutageSummary} powerOutageLoading={powerOutageLoading} />,
                        charts: (
                            <Suspense fallback={<Loading message="در حال بارگذاری نمودارها..." />}>
                                <ChartsTab sortedTelemetry={sortedTelemetry} dataGaps={dataGaps} visibleParams={visibleParams} />
                            </Suspense>
                        ),
            weather: selectedDate ? (
                            <Suspense fallback={<Loading message="در حال بارگذاری اطلاعات آب و هوا..." />}>
                <WeatherTab selectedDate={selectedDate} />
                            </Suspense>
                        ) : null,
                        analysis: selectedDate ? (
                            <Suspense fallback={<Loading message="در حال بارگذاری تحلیل..." />}>
                <AnalysisTab deviceId={deviceId} selectedDate={selectedDate} />
                            </Suspense>
                        ) : null,
                    }}
                </Tabs>
            </div>
        </AppShell>
    )
}

export default function DailyReportPage() {
    return (
        <Suspense fallback={
            <div className="min-h-screen flex items-center justify-center p-4">
                <div className="text-center">
                    <div className="w-16 h-16 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin mx-auto mb-4"></div>
                    <p className="text-gray-600">در حال بارگذاری گزارش...</p>
                </div>
            </div>
        }>
            <DailyReportContent />
        </Suspense>
    )
}
