import { useState, useEffect, useCallback, useRef } from 'react'
import { X, Save, Clock, Plus, Trash2, Copy, AlertTriangle, LogOut } from 'lucide-react'
import { Button } from '@/components/common/Button'
import { t, sprintf } from '@/lib/i18n'

/** A single time range within a day */
interface TimeRange {
    start: string
    end: string
}

/** The structured availability data stored as JSON in meeting_availability */
export interface MeetingAvailability {
    meeting_duration: number
    days: Record<string, TimeRange[]>
}

/**
 * Safely parse meeting_availability data from the database.
 * Handles both the current format ({ meeting_duration, days }) and the
 * legacy bare-array format ([[{start,end}], ...]) that pre-migration
 * sites may still store.
 */
export function parseMeetingAvailabilitySafely(value: unknown): MeetingAvailability | null {
    if (!value) return null

    if (typeof value === 'string') {
        try {
            value = JSON.parse(value)
        } catch {
            return null
        }
    }

    if (typeof value !== 'object') return null

    if (!Array.isArray(value) && (value as any).days) {
        return value as MeetingAvailability
    }

    if (Array.isArray(value)) {
        const days: Record<string, TimeRange[]> = {}
        for (let i = 0; i < 7; i++) {
            days[String(i)] = Array.isArray(value[i]) ? value[i] : []
        }
        return { meeting_duration: 30, days }
    }

    return null
}

interface AvailabilityScheduleEditorProps {
    isOpen: boolean
    contactName: string
    initialData: MeetingAvailability | null
    onSave: (data: MeetingAvailability) => void | Promise<void>
    onClose: () => void
    isSaving?: boolean
}

const DAY_LABELS: Record<string, string> = {
    '0': t('Sunday'),
    '1': t('Monday'),
    '2': t('Tuesday'),
    '3': t('Wednesday'),
    '4': t('Thursday'),
    '5': t('Friday'),
    '6': t('Saturday'),
}

// In RTL grid, first item renders on the right.
// Sunday (0) on the right → Saturday (6) on the left.
const DAY_ORDER = ['0', '1', '2', '3', '4', '5', '6']

const DURATION_OPTIONS = [15, 30, 45, 60, 90, 120]

const DEFAULT_RANGE: TimeRange = { start: '09:00', end: '17:00' }

function getDefaultSchedule(): MeetingAvailability {
    return {
        meeting_duration: 30,
        days: {
            '0': [{ ...DEFAULT_RANGE }],
            '1': [{ ...DEFAULT_RANGE }],
            '2': [{ ...DEFAULT_RANGE }],
            '3': [{ ...DEFAULT_RANGE }],
            '4': [{ ...DEFAULT_RANGE }],
            '5': [],
            '6': [],
        },
    }
}

/** Generate time options for select dropdowns (00:00 to 23:45 in 15-min steps) */
function generateTimeOptions(): string[] {
    const options: string[] = []
    for (let h = 0; h < 24; h++) {
        for (let m = 0; m < 60; m += 15) {
            options.push(`${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`)
        }
    }
    return options
}

const TIME_OPTIONS = generateTimeOptions()

/** Serialize schedule for deep comparison */
function serializeSchedule(s: MeetingAvailability): string {
    return JSON.stringify(s)
}

/** Convert "HH:MM" to total minutes */
function timeToMinutes(t: string): number {
    const [h, m] = t.split(':').map(Number)
    return h * 60 + m
}

/** Convert total minutes to "HH:MM" */
function minutesToTime(m: number): string {
    return `${String(Math.floor(m / 60)).padStart(2, '0')}:${String(m % 60).padStart(2, '0')}`
}

/**
 * Fix #7 — Normalize a schedule by:
 * 1. Removing ranges where start >= end (invalid)
 * 2. Merging overlapping/adjacent ranges
 */
function normalizeSchedule(s: MeetingAvailability): MeetingAvailability {
    const newDays: Record<string, TimeRange[]> = {}
    for (const [dayKey, ranges] of Object.entries(s.days)) {
        if (!ranges || ranges.length === 0) {
            newDays[dayKey] = []
            continue
        }
        // Filter out invalid ranges (start >= end)
        const valid = ranges.filter(r => timeToMinutes(r.start) < timeToMinutes(r.end))
        if (valid.length === 0) {
            newDays[dayKey] = []
            continue
        }
        // Sort by start
        valid.sort((a, b) => timeToMinutes(a.start) - timeToMinutes(b.start))
        // Merge overlapping
        const merged: { start: number; end: number }[] = [
            { start: timeToMinutes(valid[0].start), end: timeToMinutes(valid[0].end) },
        ]
        for (let i = 1; i < valid.length; i++) {
            const cur = { start: timeToMinutes(valid[i].start), end: timeToMinutes(valid[i].end) }
            const last = merged[merged.length - 1]
            if (cur.start <= last.end) {
                last.end = Math.max(last.end, cur.end)
            } else {
                merged.push(cur)
            }
        }
        newDays[dayKey] = merged.map(m => ({ start: minutesToTime(m.start), end: minutesToTime(m.end) }))
    }
    return { ...s, days: newDays }
}

export function AvailabilityScheduleEditor({
    isOpen,
    contactName,
    initialData,
    onSave,
    onClose,
    isSaving = false,
}: AvailabilityScheduleEditorProps) {
    const [schedule, setSchedule] = useState<MeetingAvailability>(getDefaultSchedule)
    const [showUnsavedModal, setShowUnsavedModal] = useState(false)
    const [saveError, setSaveError] = useState<string | null>(null)
    const originalRef = useRef<string>('')

    // Track whether the contact has any saved availability at all
    const hasExistingData = initialData !== null

    useEffect(() => {
        if (isOpen) {
            const data = (initialData?.days) ? initialData : getDefaultSchedule()
            setSchedule(data)
            originalRef.current = initialData ? serializeSchedule(initialData) : ''
            setShowUnsavedModal(false)
            setSaveError(null)
        }
    }, [isOpen, initialData])

    const isDirty = isOpen && serializeSchedule(schedule) !== originalRef.current

    const setDuration = useCallback((dur: number) => {
        setSchedule(prev => ({ ...prev, meeting_duration: dur }))
    }, [])

    const toggleDay = useCallback((dayKey: string) => {
        setSchedule(prev => {
            const currentRanges = prev.days[dayKey] || []
            return {
                ...prev,
                days: {
                    ...prev.days,
                    [dayKey]: currentRanges.length > 0 ? [] : [{ ...DEFAULT_RANGE }],
                },
            }
        })
    }, [])

    const addRange = useCallback((dayKey: string) => {
        setSchedule(prev => {
            const existing = prev.days[dayKey] || []
            const lastEnd = existing.length > 0 ? existing[existing.length - 1].end : '09:00'
            // Start 1 hour after last end, or at 09:00
            const startParts = lastEnd.split(':')
            const startH = Math.min(23, parseInt(startParts[0]) + 1)
            const newStart = `${String(startH).padStart(2, '0')}:${startParts[1]}`
            const endH = Math.min(23, startH + 2)
            const newEnd = `${String(endH).padStart(2, '0')}:${startParts[1]}`
            return {
                ...prev,
                days: {
                    ...prev.days,
                    [dayKey]: [...existing, { start: newStart, end: newEnd }],
                },
            }
        })
    }, [])

    const removeRange = useCallback((dayKey: string, rangeIndex: number) => {
        setSchedule(prev => {
            const existing = [...(prev.days[dayKey] || [])]
            existing.splice(rangeIndex, 1)
            return {
                ...prev,
                days: {
                    ...prev.days,
                    [dayKey]: existing,
                },
            }
        })
    }, [])

    const updateRange = useCallback((dayKey: string, rangeIndex: number, field: 'start' | 'end', value: string) => {
        setSchedule(prev => {
            const existing = [...(prev.days[dayKey] || [])]
            existing[rangeIndex] = { ...existing[rangeIndex], [field]: value }
            return {
                ...prev,
                days: {
                    ...prev.days,
                    [dayKey]: existing,
                },
            }
        })
    }, [])

    const copyToAll = useCallback((sourceDayKey: string) => {
        setSchedule(prev => {
            const sourceRanges = prev.days[sourceDayKey] || []
            const newDays: Record<string, TimeRange[]> = {}
            for (let d = 0; d <= 6; d++) {
                const key = String(d)
                newDays[key] = sourceRanges.map(r => ({ ...r }))
            }
            return { ...prev, days: newDays }
        })
    }, [])

    const handleSave = useCallback(async () => {
        setSaveError(null)
        const normalized = normalizeSchedule(schedule)
        setSchedule(normalized) // update UI to show merged result
        try {
            await onSave(normalized)
            onClose()
        } catch {
            setSaveError(t('Save failed. Please try again.'))
        }
    }, [schedule, onSave, onClose])

    /** Attempt to close — if dirty, show unsaved changes modal instead */
    const handleRequestClose = useCallback(() => {
        if (isDirty) {
            setShowUnsavedModal(true)
        } else {
            onClose()
        }
    }, [isDirty, onClose])

    /** Discard changes and close */
    const handleDiscard = useCallback(() => {
        setShowUnsavedModal(false)
        onClose()
    }, [onClose])

    /** Save changes from the unsaved modal, then close */
    const handleSaveAndClose = useCallback(async () => {
        setShowUnsavedModal(false)
        setSaveError(null)
        const normalized = normalizeSchedule(schedule)
        try {
            await onSave(normalized)
            onClose()
        } catch {
            setSaveError(t('Save failed. Please try again.'))
        }
    }, [schedule, onSave, onClose])

    if (!isOpen) return null

    return (
        <>
            <div
                className="fixed inset-0 bg-black/50 flex items-center justify-center"
                style={{ zIndex: 100000 }}
                dir="rtl"
                onClick={handleRequestClose}
            >
                <div
                    className="bg-white rounded-xl shadow-xl w-full max-w-4xl mx-4 max-h-[90vh] flex flex-col overflow-hidden"
                    onClick={(e) => e.stopPropagation()}
                >
                    {/* Header */}
                    <div className={`px-6 py-4 flex items-center justify-between border-b shrink-0 ${
                        !hasExistingData ? 'bg-amber-50 border-amber-100' : 'bg-primary-50 border-primary-100'
                    }`}>
                        <div className="flex items-center gap-3">
                            <Clock className={`w-5 h-5 ${!hasExistingData ? 'text-amber-600' : 'text-primary-600'}`} />
                            <h3 className={`font-semibold ${!hasExistingData ? 'text-amber-900' : 'text-primary-900'}`}>
                                {sprintf(t('Meeting Availability Settings - %s'), contactName)}
                            </h3>
                            {!hasExistingData && (
                                <span className="text-xs bg-amber-200 text-amber-800 px-2 py-0.5 rounded-full">
                                    {t('Not yet configured')}
                                </span>
                            )}
                        </div>
                        <button
                            onClick={handleRequestClose}
                            className="text-gray-400 hover:text-gray-600 transition-colors"
                        >
                            <X className="w-5 h-5" />
                        </button>
                    </div>

                    {/* Content - scrollable */}
                    <div className="px-6 py-5 overflow-y-auto flex-1">
                        {/* Duration selector */}
                        <div className="mb-6">
                            <label className="block text-sm font-medium text-gray-700 mb-2">
                                {t('Meeting Duration (minutes)')}
                            </label>
                            <div className="flex flex-wrap gap-2">
                                {DURATION_OPTIONS.map((dur) => (
                                    <label
                                        key={dur}
                                        className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm cursor-pointer transition-colors ${
                                            schedule.meeting_duration === dur
                                                ? 'bg-primary-100 text-primary-700 border-primary-300 border'
                                                : 'bg-gray-100 hover:bg-gray-200 border border-transparent'
                                        }`}
                                    >
                                        <input
                                            type="radio"
                                            name="meeting_duration"
                                            checked={schedule.meeting_duration === dur}
                                            onChange={() => setDuration(dur)}
                                            className="w-3.5 h-3.5 text-primary-600 focus:ring-primary-500"
                                        />
                                        {sprintf(t('%s min'), dur)}
                                    </label>
                                ))}
                            </div>
                        </div>

                        {/* Weekly schedule grid */}
                        <div className="mb-4">
                            <label className="block text-sm font-medium text-gray-700 mb-3">
                                {t('Available Days and Hours')}
                            </label>
                            <div className="grid grid-cols-7 gap-2">
                                {DAY_ORDER.map((dayKey) => {
                                    const ranges = schedule.days?.[dayKey] || []
                                    const isActive = ranges.length > 0

                                    return (
                                        <div
                                            key={dayKey}
                                            className={`rounded-lg border transition-colors ${
                                                isActive
                                                    ? 'border-primary-200 bg-primary-50/50'
                                                    : 'border-gray-200 bg-gray-50'
                                            }`}
                                        >
                                            {/* Day header with toggle */}
                                            <div className="p-2 text-center border-b border-inherit">
                                                <button
                                                    onClick={() => toggleDay(dayKey)}
                                                    className={`w-full text-xs font-semibold py-1 px-2 rounded transition-colors ${
                                                        isActive
                                                            ? 'bg-primary-500 text-white'
                                                            : 'bg-gray-200 text-gray-500 hover:bg-gray-300'
                                                    }`}
                                                >
                                                    {DAY_LABELS[dayKey]}
                                                </button>
                                            </div>

                                            {/* Time ranges */}
                                            <div className="p-2 min-h-[120px]">
                                                {isActive ? (
                                                    <>
                                                        {ranges.map((range, idx) => {
                                                            const isInvalid = timeToMinutes(range.start) >= timeToMinutes(range.end)
                                                            return (
                                                            <div key={idx} className="mb-2 last:mb-0">
                                                                <div className="flex items-center gap-1 mb-1">
                                                                    <select
                                                                        value={range.start}
                                                                        onChange={(e) => updateRange(dayKey, idx, 'start', e.target.value)}
                                                                        className={`text-[11px] border rounded px-1 py-0.5 w-full bg-white ${isInvalid ? 'border-red-400' : 'border-gray-300'}`}
                                                                    >
                                                                        {TIME_OPTIONS.map(t => (
                                                                            <option key={t} value={t}>{t}</option>
                                                                        ))}
                                                                    </select>
                                                                </div>
                                                                <div className="flex items-center gap-1 mb-1">
                                                                    <select
                                                                        value={range.end}
                                                                        onChange={(e) => updateRange(dayKey, idx, 'end', e.target.value)}
                                                                        className={`text-[11px] border rounded px-1 py-0.5 w-full bg-white ${isInvalid ? 'border-red-400' : 'border-gray-300'}`}
                                                                    >
                                                                        {TIME_OPTIONS.map(t => (
                                                                            <option key={t} value={t}>{t}</option>
                                                                        ))}
                                                                    </select>
                                                                </div>
                                                                {ranges.length > 1 && (
                                                                    <button
                                                                        onClick={() => removeRange(dayKey, idx)}
                                                                        className="text-red-400 hover:text-red-600 transition-colors w-full flex justify-center"
                                                                        title={t('Remove range')}
                                                                    >
                                                                        <Trash2 className="w-3 h-3" />
                                                                    </button>
                                                                )}
                                                                {isInvalid && (
                                                                    <span className="text-[9px] text-red-500 block text-center">{t('End time before start')}</span>
                                                                )}
                                                            </div>
                                                        )})}
                                                        <button
                                                            onClick={() => addRange(dayKey)}
                                                            className="w-full mt-1 text-[10px] text-primary-600 hover:text-primary-700 flex items-center justify-center gap-0.5 py-1 rounded hover:bg-primary-50 transition-colors"
                                                        >
                                                            <Plus className="w-3 h-3" />
                                                            {t('Range')}
                                                        </button>
                                                        <button
                                                            onClick={() => copyToAll(dayKey)}
                                                            className="w-full mt-0.5 text-[10px] text-gray-400 hover:text-gray-600 flex items-center justify-center gap-0.5 py-0.5 rounded hover:bg-gray-100 transition-colors"
                                                            title={t('Copy to all days')}
                                                        >
                                                            <Copy className="w-2.5 h-2.5" />
                                                            {t('Copy to all')}
                                                        </button>
                                                    </>
                                                ) : (
                                                    <div className="flex items-center justify-center h-full text-[11px] text-gray-400">
                                                        {t('Not available')}
                                                    </div>
                                                )}
                                            </div>
                                        </div>
                                    )
                                })}
                            </div>
                        </div>
                    </div>

                    {/* Footer */}
                    <div className="px-6 py-4 bg-gray-50 border-t shrink-0">
                        {saveError && (
                            <div className="mb-3 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
                                {saveError}
                            </div>
                        )}
                        <div className="flex items-center justify-between">
                        <button
                            onClick={handleRequestClose}
                            disabled={isSaving}
                            className="text-sm text-gray-500 hover:text-gray-700"
                        >
                            {t('Cancel')}
                        </button>
                        <Button
                            onClick={handleSave}
                            disabled={isSaving}
                            className={isDirty ? '!bg-amber-500 hover:!bg-amber-600' : ''}
                        >
                            <Save className="w-4 h-4 me-2" />
                            {isSaving ? t('Saving...') : isDirty ? t('Save Changes') : t('Save')}
                        </Button>
                        </div>
                    </div>
                </div>
            </div>

            {/* Unsaved changes confirmation modal */}
            {showUnsavedModal && (
                <div
                    className="fixed inset-0 bg-black/50 flex items-center justify-center"
                    style={{ zIndex: 100001 }}
                    dir="rtl"
                >
                    <div className="bg-white rounded-xl shadow-xl max-w-md w-full mx-4 overflow-hidden">
                        {/* Header */}
                        <div className="bg-amber-50 px-6 py-4 flex items-center gap-3 border-b border-amber-100">
                            <AlertTriangle className="w-6 h-6 text-amber-600" />
                            <h3 className="font-semibold text-amber-900">{t('Unsaved Changes')}</h3>
                        </div>

                        {/* Content */}
                        <div className="px-6 py-4">
                            <p className="text-gray-700 mb-4">
                                {t('You have unsaved changes. What would you like to do?')}
                            </p>
                        </div>

                        {/* Actions */}
                        <div className="px-6 py-4 bg-gray-50 flex flex-col gap-2">
                            <div className="flex gap-2">
                                <Button
                                    onClick={handleDiscard}
                                    variant="outline"
                                    className="flex-1"
                                    disabled={isSaving}
                                >
                                    <LogOut className="w-4 h-4 me-2" />
                                    {t('Exit without saving')}
                                </Button>

                                <Button
                                    onClick={handleSaveAndClose}
                                    className="flex-1"
                                    disabled={isSaving}
                                >
                                    <Save className="w-4 h-4 me-2" />
                                    {isSaving ? t('Saving...') : t('Save and exit')}
                                </Button>
                            </div>

                            <button
                                onClick={() => setShowUnsavedModal(false)}
                                disabled={isSaving}
                                className="text-sm text-gray-400 hover:text-gray-600 py-2"
                            >
                                {t('Cancel - stay in editor')}
                            </button>
                        </div>
                    </div>
                </div>
            )}
        </>
    )
}
