import { useState, useEffect, useMemo } from 'react';
import { ChevronLeft, ChevronRight, Lock } from 'lucide-react';
import { Badge } from '../../components/ui/Badge';
import { Button } from '../../components/ui/Button';
import { api } from '../../api/client';
import type { Booking, RentalListing, AvailabilityBlock } from '../../types/rental';

function getDaysInMonth(year: number, month: number) {
  return new Date(year, month + 1, 0).getDate();
}

function getFirstDayOfMonth(year: number, month: number) {
  return new Date(year, month, 1).getDay();
}

const MONTH_NAMES = [
  'January', 'February', 'March', 'April', 'May', 'June',
  'July', 'August', 'September', 'October', 'November', 'December',
];

export function LandlordCalendarPage() {
  const today = new Date();
  const [year, setYear] = useState(today.getFullYear());
  const [month, setMonth] = useState(today.getMonth());
  const [bookings, setBookings] = useState<Booking[]>([]);
  const [blocks, setBlocks] = useState<AvailabilityBlock[]>([]);
  const [rentals, setRentals] = useState<RentalListing[]>([]);
  const [selectedRental, setSelectedRental] = useState<string>('all');
  const [blockingStart, setBlockingStart] = useState<string | null>(null);
  const [blockingEnd, setBlockingEnd] = useState<string | null>(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const [rentalsRes, bookingsRes] = await Promise.all([
          api.get<RentalListing[]>('/rentals/mine'),
          api.get<Booking[]>('/bookings?role=landlord'),
        ]);
        setRentals(rentalsRes);
        setBookings(bookingsRes);

        const allBlocks: AvailabilityBlock[] = [];
        for (const rental of rentalsRes) {
          try {
            const res = await api.get<{ blocks: AvailabilityBlock[]; bookings: unknown[] }>(`/rentals/${rental.id}/availability`);
            allBlocks.push(...res.blocks);
          } catch {
            // skip if endpoint not available
          }
        }
        setBlocks(allBlocks);
      } catch {
        // silently fail
      }
    }
    fetchData();
  }, []);

  const filteredBookings = useMemo(() => {
    if (selectedRental === 'all') return bookings;
    return bookings.filter((b) => b.rentalListingId === selectedRental);
  }, [bookings, selectedRental]);

  const filteredBlocks = useMemo(() => {
    if (selectedRental === 'all') return blocks;
    return blocks.filter((b) => b.rentalListingId === selectedRental);
  }, [blocks, selectedRental]);

  const daysInMonth = getDaysInMonth(year, month);
  const firstDay = getFirstDayOfMonth(year, month);

  const getDateStr = (day: number) => {
    return `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
  };

  const getBookingsForDay = (day: number) => {
    const dateStr = getDateStr(day);
    return filteredBookings.filter((b) => {
      const start = b.startDate.slice(0, 10);
      const end = b.endDate.slice(0, 10);
      return dateStr >= start && dateStr <= end;
    });
  };

  const isBlockedDay = (day: number) => {
    const dateStr = getDateStr(day);
    return filteredBlocks.some((b) => {
      const start = b.startDate.slice(0, 10);
      const end = b.endDate.slice(0, 10);
      return dateStr >= start && dateStr <= end && b.isBlocked;
    });
  };

  const isInBlockingRange = (day: number) => {
    if (!blockingStart) return false;
    const dateStr = getDateStr(day);
    if (!blockingEnd) return dateStr === blockingStart;
    const start = blockingStart < blockingEnd ? blockingStart : blockingEnd;
    const end = blockingStart < blockingEnd ? blockingEnd : blockingStart;
    return dateStr >= start && dateStr <= end;
  };

  const handleDayClick = (day: number) => {
    const dateStr = getDateStr(day);
    if (!blockingStart) {
      setBlockingStart(dateStr);
      setBlockingEnd(null);
    } else if (!blockingEnd) {
      setBlockingEnd(dateStr);
    } else {
      setBlockingStart(dateStr);
      setBlockingEnd(null);
    }
  };

  const handleBlockDates = async () => {
    if (!blockingStart || !blockingEnd || selectedRental === 'all') return;
    const start = blockingStart < blockingEnd ? blockingStart : blockingEnd;
    const end = blockingStart < blockingEnd ? blockingEnd : blockingStart;
    try {
      await api.post(`/rentals/${selectedRental}/availability`, {
        startDate: start,
        endDate: end,
        isBlocked: true,
        reason: 'Blocked by landlord',
      });
      const res = await api.get<{ blocks: AvailabilityBlock[]; bookings: unknown[] }>(`/rentals/${selectedRental}/availability`);
      setBlocks((prev) => [
        ...prev.filter((b) => b.rentalListingId !== selectedRental),
        ...res.blocks,
      ]);
      setBlockingStart(null);
      setBlockingEnd(null);
    } catch {
      // silently fail
    }
  };

  const prevMonth = () => {
    if (month === 0) {
      setMonth(11);
      setYear(year - 1);
    } else {
      setMonth(month - 1);
    }
  };

  const nextMonth = () => {
    if (month === 11) {
      setMonth(0);
      setYear(year + 1);
    } else {
      setMonth(month + 1);
    }
  };

  return (
    <div>
      <h1 className="text-2xl font-bold text-gray-900 mb-4">Calendar</h1>

      <div className="flex flex-col sm:flex-row items-start sm:items-center gap-4 mb-6">
        <select
          value={selectedRental}
          onChange={(e) => setSelectedRental(e.target.value)}
          className="px-3 py-2 rounded-xl border border-gray-200 text-sm focus:border-violet-400 focus:ring-2 focus:ring-violet-100 focus:outline-none"
        >
          <option value="all">All Rentals</option>
          {rentals.map((r) => (
            <option key={r.id} value={r.id}>{r.title}</option>
          ))}
        </select>

        {blockingStart && blockingEnd && selectedRental !== 'all' && (
          <Button variant="primary" size="sm" onClick={handleBlockDates}>
            <Lock className="w-3.5 h-3.5 mr-1.5" />
            Block Selected Dates
          </Button>
        )}
      </div>

      <div className="bg-white rounded-2xl border border-gray-200 shadow-sm p-5">
        {/* Month navigation */}
        <div className="flex items-center justify-between mb-5">
          <button onClick={prevMonth} className="p-2 rounded-lg hover:bg-gray-100 cursor-pointer">
            <ChevronLeft className="w-5 h-5 text-gray-600" />
          </button>
          <h2 className="text-lg font-semibold text-gray-900">
            {MONTH_NAMES[month]} {year}
          </h2>
          <button onClick={nextMonth} className="p-2 rounded-lg hover:bg-gray-100 cursor-pointer">
            <ChevronRight className="w-5 h-5 text-gray-600" />
          </button>
        </div>

        {/* Day headers */}
        <div className="grid grid-cols-7 gap-1 mb-1">
          {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map((d) => (
            <div key={d} className="text-center text-xs font-medium text-gray-400 py-2">{d}</div>
          ))}
        </div>

        {/* Calendar grid */}
        <div className="grid grid-cols-7 gap-1">
          {Array.from({ length: firstDay }).map((_, i) => (
            <div key={`empty-${i}`} className="h-20 rounded-lg" />
          ))}
          {Array.from({ length: daysInMonth }).map((_, i) => {
            const day = i + 1;
            const dayBookings = getBookingsForDay(day);
            const blocked = isBlockedDay(day);
            const inRange = isInBlockingRange(day);
            const isToday =
              day === today.getDate() && month === today.getMonth() && year === today.getFullYear();

            return (
              <div
                key={day}
                onClick={() => handleDayClick(day)}
                className={`h-20 rounded-lg p-1.5 text-sm cursor-pointer transition-colors border ${
                  inRange
                    ? 'border-violet-300 bg-violet-50'
                    : blocked
                    ? 'border-red-200 bg-red-50'
                    : isToday
                    ? 'border-violet-200 bg-violet-50/50'
                    : 'border-transparent hover:bg-gray-50'
                }`}
              >
                <span className={`text-xs font-medium ${isToday ? 'text-violet-700' : 'text-gray-700'}`}>
                  {day}
                </span>
                {blocked && (
                  <div className="mt-0.5">
                    <Badge variant="error" size="sm">Blocked</Badge>
                  </div>
                )}
                {dayBookings.slice(0, 2).map((b) => (
                  <div
                    key={b.id}
                    className="mt-0.5 text-xs px-1 py-0.5 rounded bg-violet-100 text-violet-700 truncate"
                    title={b.rentalListing.title}
                  >
                    {b.tenant.fullName.split(' ')[0]}
                  </div>
                ))}
                {dayBookings.length > 2 && (
                  <span className="text-xs text-gray-400">+{dayBookings.length - 2}</span>
                )}
              </div>
            );
          })}
        </div>
      </div>

      {/* Legend */}
      <div className="flex items-center gap-4 mt-4 text-xs text-gray-500">
        <div className="flex items-center gap-1.5">
          <div className="w-3 h-3 rounded bg-violet-100 border border-violet-200" />
          <span>Booked</span>
        </div>
        <div className="flex items-center gap-1.5">
          <div className="w-3 h-3 rounded bg-red-50 border border-red-200" />
          <span>Blocked</span>
        </div>
        <div className="flex items-center gap-1.5">
          <div className="w-3 h-3 rounded bg-violet-50 border border-violet-300" />
          <span>Selected</span>
        </div>
      </div>
    </div>
  );
}
