import React, { useState, useEffect } from 'react';
import { Calendar } from './calendar';
import { Button } from './button';
import { Popover, PopoverContent, PopoverTrigger } from './popover';
import { ChevronLeftIcon, ChevronRightIcon, CalendarIcon, X } from 'lucide-react';
import { format, addDays, addMonths, addYears, isAfter } from 'date-fns';
import './DateRangePicker.css';

// Test function to verify preset calculations (can be called from browser console)
export const testPresetCalculations = () => {
  console.log('🧪 Testing Preset Calculations...');
  
  timeRangePresets.forEach(preset => {
    const range = preset.getRange();
    const today = new Date();
    const todayString = today.toDateString();
    const yesterdayString = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1).toDateString();
    
    console.log(`📅 ${preset.label}:`, {
      from: range.from.toDateString(),
      to: range.to.toDateString(),
      fromISO: range.from.toISOString(),
      toISO: range.to.toISOString(),
      isCorrect: preset.value === '2d' ? 
        (range.from.toDateString() === yesterdayString && range.to.toDateString() === todayString) :
        true
    });
  });
  
  // Test specific 2-day calculation
  const twoDayPreset = timeRangePresets.find(p => p.value === '2d');
  if (twoDayPreset) {
    const range = twoDayPreset.getRange();
    const today = new Date();
    const expectedFrom = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
    const expectedTo = new Date(today.getFullYear(), today.getMonth(), today.getDate());
    
    console.log('🔍 2-Day Preset Verification:', {
      actualFrom: range.from.toDateString(),
      actualTo: range.to.toDateString(),
      expectedFrom: expectedFrom.toDateString(),
      expectedTo: expectedTo.toDateString(),
      isCorrect: range.from.toDateString() === expectedFrom.toDateString() && 
                range.to.toDateString() === expectedTo.toDateString()
    });
  }
};

const timeRangePresets = [
  { label: 'Today', value: 'today', getRange: () => {
    const now = new Date();
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    return { from: todayStart, to: todayStart };
  }},
  { label: 'Last 2 days', value: '2d', getRange: () => {
    const now = new Date();
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const yesterdayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
    return { from: yesterdayStart, to: todayStart };
  }},
  { label: 'Last 7 days', value: '7d', getRange: () => {
    const now = new Date();
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const sevenDaysAgoStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6);
    return { from: sevenDaysAgoStart, to: todayStart };
  }},
  { label: 'Last 30 days', value: '30d', getRange: () => {
    const now = new Date();
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const thirtyDaysAgoStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 29);
    return { from: thirtyDaysAgoStart, to: todayStart };
  }},
  { label: 'Last 90 days', value: '90d', getRange: () => {
    const now = new Date();
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const ninetyDaysAgoStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 89);
    return { from: ninetyDaysAgoStart, to: todayStart };
  }},
  { label: 'Last 6 months', value: '6m', getRange: () => {
    const now = new Date();
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const sixMonthsAgoStart = new Date(now.getFullYear(), now.getMonth() - 6, now.getDate());
    return { from: sixMonthsAgoStart, to: todayStart };
  }},
  { label: 'Last 1 year', value: '1y', getRange: () => {
    const now = new Date();
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const oneYearAgoStart = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate());
    return { from: oneYearAgoStart, to: todayStart };
  }},
];

export function DateRangePicker({ 
  value, 
  onValueChange, 
  placeholder = "Select date range",
  className = "",
  forceDown = false,
  hideCalendar = false
}) {
  const [isOpen, setIsOpen] = useState(false);
  const [selectedRange, setSelectedRange] = useState(value || { from: undefined, to: undefined });
  const [selectedPreset, setSelectedPreset] = useState(null);
  const [tempRange, setTempRange] = useState({ from: undefined, to: undefined });

  // Update internal state when external value changes
  useEffect(() => {
    if (value) {
      setSelectedRange(value);
      setTempRange(value);
      // Check if the value matches any preset - compare dates without time
      const matchingPreset = timeRangePresets.find(preset => {
        const presetRange = preset.getRange();
        // Compare dates without time using toDateString()
        return presetRange.from.toDateString() === value.from?.toDateString() && 
               presetRange.to.toDateString() === value.to?.toDateString();
      });
      
      if (matchingPreset) {
        setSelectedPreset(matchingPreset.value);
      } else {
        // If no preset matches, check if it's approximately last 30 days (within 1-2 days tolerance)
        if (value.from && value.to) {
          const diffTime = Math.abs(value.to - value.from);
          const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
          
          // Check if it's close to 30 days (allow 1-2 days tolerance)
          if (diffDays >= 28 && diffDays <= 32) {
            setSelectedPreset('30d');
          } else {
            setSelectedPreset(null);
          }
        } else {
          setSelectedPreset(null);
        }
      }
    }
  }, [value]);

  // Initialize with last 30 days preset if no value is provided
  useEffect(() => {
    if (!value && !selectedPreset) {
      const today = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate());
      const thirtyDaysAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 29);
      const defaultRange = { from: thirtyDaysAgo, to: today };
      
      setSelectedRange(defaultRange);
      setTempRange(defaultRange);
      setSelectedPreset('30d');
    }
  }, []);

  const handlePresetSelect = (preset) => {
    // Force recalculation using current date
    const currentDate = new Date();
    let range;
    
    // Calculate range based on preset value using current date
    switch (preset.value) {
      case 'today':
        const todayStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
        range = { from: todayStart, to: todayStart };
        break;
      case '2d':
        const todayStart2 = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
        const yesterdayStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - 1);
        range = { from: yesterdayStart, to: todayStart2 };
        break;
      case '7d':
        const todayStart7 = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
        const sevenDaysAgoStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - 6);
        range = { from: sevenDaysAgoStart, to: todayStart7 };
        break;
      case '30d':
        const todayStart30 = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
        const thirtyDaysAgoStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - 29);
        range = { from: thirtyDaysAgoStart, to: todayStart30 };
        break;
      case '90d':
        const todayStart90 = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
        const ninetyDaysAgoStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - 89);
        range = { from: ninetyDaysAgoStart, to: todayStart90 };
        break;
      case '6m':
        const todayStart6m = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
        const sixMonthsAgoStart = new Date(currentDate.getFullYear(), currentDate.getMonth() - 6, currentDate.getDate());
        range = { from: sixMonthsAgoStart, to: todayStart6m };
        break;
      case '1y':
        const todayStart1y = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
        const oneYearAgoStart = new Date(currentDate.getFullYear() - 1, currentDate.getMonth(), currentDate.getDate());
        range = { from: oneYearAgoStart, to: todayStart1y };
        break;
      default:
        range = preset.getRange();
    }
    
    const todayString = currentDate.toDateString();
    
    // Enhanced debug with more detailed information
    console.log('🔍 Enhanced Preset Selection Debug:', {
      presetLabel: preset.label,
      presetValue: preset.value,
      calculatedRange: {
        from: range.from.toISOString(),
        to: range.to.toISOString(),
        fromDateString: range.from.toDateString(),
        toDateString: range.to.toDateString(),
        fromLocalDate: range.from.toLocaleDateString(),
        toLocalDate: range.to.toLocaleDateString()
      },
      today: todayString,
      todayISO: currentDate.toISOString(),
      todayLocal: currentDate.toLocaleDateString(),
      includesToday: range.to.toDateString() === todayString,
      dayDifference: Math.floor((range.to - range.from) / (1000 * 60 * 60 * 24)) + 1,
      expectedFrom: new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - 1).toDateString(),
      expectedTo: todayString
    });
    
    setSelectedRange(range);
    setTempRange(range);
    setSelectedPreset(preset.value);
    onValueChange(range);
    setIsOpen(false);
  };

  const handleDateSelect = (date) => {
    if (!date) return;

    // Prevent future dates
    if (isAfter(date, new Date())) return;

    // Ensure the date is in local time by creating a new Date object
    const localDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());

    if (!tempRange.from || (tempRange.from && tempRange.to)) {
      // Start new range
      setTempRange({ from: localDate, to: undefined });
    } else {
      // Complete the range
      let from = tempRange.from;
      let to = localDate;
      
      // Ensure from is before to
      if (isAfter(from, to)) {
        [from, to] = [to, from];
      }
      
      const range = { from, to };
      setTempRange(range);
      setSelectedRange(range);
      setSelectedPreset(null);
      onValueChange(range);
      setIsOpen(false);
    }
  };

  const handleReset = () => {
    const emptyRange = { from: undefined, to: undefined };
    setSelectedRange(emptyRange);
    setTempRange(emptyRange);
    setSelectedPreset(null);
    onValueChange(emptyRange);
    setIsOpen(false);
  };

  const formatDisplayValue = () => {
    if (selectedPreset) {
      const preset = timeRangePresets.find(p => p.value === selectedPreset);
      return preset ? preset.label : placeholder;
    }
    if (selectedRange?.from && selectedRange?.to) {
      // Check if it's approximately last 30 days
      const diffTime = Math.abs(selectedRange.to - selectedRange.from);
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
      
      if (diffDays >= 28 && diffDays <= 32) {
        return 'Last 30 days';
      }
      
      return `${format(selectedRange.from, 'MMM d')} - ${format(selectedRange.to, 'MMM d, yyyy')}`;
    }
    if (selectedRange?.from) {
      return `From ${format(selectedRange.from, 'MMM d, yyyy')}`;
    }
    return placeholder;
  };

  const isDateDisabled = (date) => {
    // Disable future dates
    return isAfter(date, new Date());
  };

  const isDateInRange = (date) => {
    if (!tempRange.from) return false;
    if (!tempRange.to) return date.getTime() === tempRange.from.getTime();
    return date >= tempRange.from && date <= tempRange.to;
  };

  const isDateStart = (date) => {
    return tempRange.from && date.getTime() === tempRange.from.getTime();
  };

  const isDateEnd = (date) => {
    return tempRange.to && date.getTime() === tempRange.to.getTime();
  };

  return (
    <Popover open={isOpen} onOpenChange={setIsOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          className={`date-range-picker trigger-button w-full justify-start text-left font-normal ${className}`}
        >
          <div className="flex items-center gap-2">
            <CalendarIcon className={`calendar-icon ${className.includes('text-xs') || className.includes('text-[10px]') ? 'h-3 w-3' : 'h-4 w-4'}`} />
            <span className={`${className.includes('text-xs') || className.includes('text-[10px]') ? 'text-[10px]' : 'text-sm'}`}>{formatDisplayValue()}</span>
          </div>
        </Button>
      </PopoverTrigger>
      <PopoverContent 
        className={`date-range-picker popover-content ${hideCalendar ? 'w-64' : 'w-[440px]'} max-w-[80vw] p-0 fade-in ${forceDown ? 'filters-section' : ''}`} 
        align="end" 
        sideOffset={8} 
        side={forceDown ? "bottom" : "top"} 
        avoidCollisions={true}
      >
        <div className="flex flex-col md:flex-row">
          {/* Left Panel - Time Range Presets */}
          <div className={`date-range-picker preset-panel w-full ${hideCalendar ? 'w-full' : 'md:w-64 border-r-0 md:border-r border-gray-200'} p-3`}>
            <div className="space-y-1">
              {timeRangePresets.map((preset) => (
                <button
                  key={preset.value}
                  onClick={() => handlePresetSelect(preset)}
                  className={`date-range-picker preset-button w-full text-left px-2 py-1.5 text-xs md:text-sm rounded-md transition-colors ${
                    selectedPreset === preset.value
                      ? 'selected'
                      : 'hover:bg-gray-100'
                  }`}
                >
                  {preset.label}
                </button>
              ))}
            </div>
          </div>

          {/* Right Panel - Calendar and Controls - Only show if hideCalendar is false */}
          {!hideCalendar && (
            <div className="date-range-picker calendar-panel w-full md:min-w-[280px] p-3">
              <div className="w-full">
                <Calendar
                  mode="single"
                  selected={undefined}
                  onSelect={handleDateSelect}
                  numberOfMonths={1}
                  showOutsideDays={true}
                  disabled={isDateDisabled}
                  className="w-full"
                  modifiers={{
                    inRange: isDateInRange,
                    start: isDateStart,
                    end: isDateEnd,
                  }}
                  modifiersStyles={{
                    inRange: { backgroundColor: '#e0e7ff', color: '#3730a3' },
                    start: { backgroundColor: '#6366f1', color: 'white' },
                    end: { backgroundColor: '#6366f1', color: 'white' },
                  }}
                />
              </div>
            </div>
          )}
        </div>
      </PopoverContent>
    </Popover>
  );
}
