"use client";

import { useState, useMemo } from "react";
import { ChevronLeft, ChevronRight, Plus } from "lucide-react";
import { Button } from "@/components/ui/button";
import { PostPill } from "./PostPill";
import type { PostAnalyticsData, PostSource } from "./PostPill";
import type { PostStatus, Network, Region } from "@/lib/types";

interface CalendarPost {
  id: string;
  content: string;
  status: PostStatus;
  networks: Network[];
  scheduledAt: string;
  originalScheduledAt?: string | null;
  analytics?: PostAnalyticsData[];
  source?: PostSource;
  campaignId?: string | null;
  campaignName?: string | null;
  region?: Region | null;
  mediaUrls?: string[];
}

interface CalendarGridProps {
  posts: CalendarPost[];
  view: "month" | "week";
  onPostClick?: (post: CalendarPost) => void;
  onNewPost?: (date: Date) => void;
  readOnly?: boolean;
  sourceFilter?: PostSource | "ALL";
}

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 MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const DAYS_SHORT = ["S", "M", "T", "W", "T", "F", "S"];

export function CalendarGrid({ posts, view, onPostClick, onNewPost, readOnly, sourceFilter }: CalendarGridProps) {
  const [currentDate, setCurrentDate] = useState(new Date());
  const [expandedDay, setExpandedDay] = useState<string | null>(null);
  const year = currentDate.getFullYear();
  const month = currentDate.getMonth();

  const navigate = (dir: number) => {
    const d = new Date(currentDate);
    if (view === "month") {
      d.setMonth(d.getMonth() + dir);
    } else {
      d.setDate(d.getDate() + dir * 7);
    }
    setCurrentDate(d);
  };

  const calendarDays = useMemo(() => {
    if (view === "week") {
      const start = new Date(currentDate);
      start.setDate(start.getDate() - start.getDay());
      return Array.from({ length: 7 }, (_, i) => {
        const d = new Date(start);
        d.setDate(d.getDate() + i);
        return d;
      });
    }

    const daysInMonth = getDaysInMonth(year, month);
    const firstDay = getFirstDayOfMonth(year, month);
    const days: (Date | null)[] = [];

    for (let i = 0; i < firstDay; i++) days.push(null);
    for (let i = 1; i <= daysInMonth; i++) days.push(new Date(year, month, i));
    while (days.length % 7 !== 0) days.push(null);

    return days;
  }, [currentDate, view, year, month]);

  const filteredPosts = useMemo(() => {
    if (!sourceFilter || sourceFilter === "ALL") return posts;
    return posts.filter((p) => p.source === sourceFilter);
  }, [posts, sourceFilter]);

  const postsByDate = useMemo(() => {
    const map: Record<string, CalendarPost[]> = {};
    filteredPosts.forEach((p) => {
      const key = new Date(p.scheduledAt).toDateString();
      if (!map[key]) map[key] = [];
      map[key].push(p);
    });
    return map;
  }, [filteredPosts]);

  const today = new Date().toDateString();

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-semibold text-gray-900">
          {MONTHS[month]} {year}
        </h2>
        <div className="flex items-center gap-2">
          <Button variant="outline" size="icon" className="border-gray-200 text-gray-700 hover:bg-gray-50" onClick={() => navigate(-1)}>
            <ChevronLeft className="h-4 w-4" />
          </Button>
          <Button variant="outline" size="sm" className="border-gray-200 text-gray-700 hover:bg-gray-50" onClick={() => setCurrentDate(new Date())}>
            Today
          </Button>
          <Button variant="outline" size="icon" className="border-gray-200 text-gray-700 hover:bg-gray-50" onClick={() => navigate(1)}>
            <ChevronRight className="h-4 w-4" />
          </Button>
        </div>
      </div>

      <div className="grid grid-cols-7 border border-gray-200 rounded-xl overflow-hidden">
        {DAYS.map((d, i) => (
          <div key={d} className="border-b border-gray-200 bg-white px-0.5 sm:px-2 py-1.5 text-center text-xs font-medium uppercase text-gray-500">
            <span className="hidden sm:inline">{d}</span>
            <span className="sm:hidden">{DAYS_SHORT[i]}</span>
          </div>
        ))}
        {calendarDays.map((day, i) => {
          const dateStr = day?.toDateString() ?? "";
          const dayPosts = day ? postsByDate[dateStr] || [] : [];
          const isToday = dateStr === today;

          return (
            <div
              key={i}
              className={`group min-h-[60px] sm:min-h-[100px] border-b border-r border-gray-200 p-0.5 sm:p-1 hover:bg-gray-50 transition-colors cursor-pointer ${
                !day ? "bg-gray-50/50" : "bg-white"
              } ${isToday ? "ring-2 ring-inset ring-gray-900" : ""}`}
              onClick={() => {
                if (day && !readOnly && onNewPost && dayPosts.length === 0) {
                  onNewPost(day);
                }
              }}
            >
              {day && (
                <>
                  <div className="flex items-center justify-between mb-1">
                    <span className={`text-xs ${isToday ? "text-gray-900 font-bold" : "text-gray-500"}`}>
                      {day.getDate()}
                    </span>
                    {!readOnly && onNewPost && (
                      <button
                        onClick={() => onNewPost(day)}
                        className="opacity-0 group-hover:opacity-100 hover:opacity-100 text-gray-400 hover:text-gray-600 transition-opacity"
                      >
                        <Plus className="h-3 w-3" />
                      </button>
                    )}
                  </div>
                  <div className="space-y-0.5">
                    {dayPosts.slice(0, expandedDay === dateStr ? dayPosts.length : 3).map((post) => (
                      <PostPill
                        key={post.id}
                        title={post.content.slice(0, 20)}
                        status={post.status}
                        networks={post.networks}
                        scheduledAt={post.scheduledAt}
                        originalScheduledAt={post.originalScheduledAt}
                        analytics={post.analytics}
                        source={post.source}
                        campaignName={post.campaignName}
                        region={post.region}
                        hasMedia={!!post.mediaUrls && post.mediaUrls.length > 0}
                        onClick={() => onPostClick?.(post)}
                      />
                    ))}
                    {dayPosts.length > 3 && (
                      <button
                        className="text-xs text-blue-600 hover:text-blue-800 underline pl-1 cursor-pointer"
                        onClick={(e) => {
                          e.stopPropagation();
                          setExpandedDay(expandedDay === dateStr ? null : dateStr);
                        }}
                        data-testid="calendar-expand"
                      >
                        {expandedDay === dateStr ? "Show less" : `+${dayPosts.length - 3} more`}
                      </button>
                    )}
                  </div>
                </>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
