"use client";

import { useMemo, useState } from "react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { ScrollArea } from "@/components/ui/scroll-area";
import { useToast } from "@/hooks/use-toast";
import {
  CalendarCheck, Check, X, Pencil, Zap, Clock, Inbox, Loader2, Link2, Trash2,
} from "lucide-react";
import type { Campaign, Creative } from "./types";
import { CHANNEL_META, FORMAT_LABEL } from "./types";

interface CalendarViewProps {
  campaigns: Campaign[];
  onRefresh: () => void;
}

const DAY_MS = 24 * 3600 * 1000;

function startOfDay(d: Date) {
  const x = new Date(d);
  x.setHours(0, 0, 0, 0);
  return x;
}

const CONNECTED = [
  { name: "Instagram", handle: "@yourshop", color: "bg-pink-500", connected: true },
  { name: "Facebook", handle: "/yourshop", color: "bg-blue-600", connected: true },
  { name: "TikTok", handle: "@yourshop", color: "bg-neutral-900", connected: true },
  { name: "LinkedIn", handle: "Your Shop", color: "bg-sky-700", connected: true },
  { name: "X", handle: "@yourshop", color: "bg-neutral-700", connected: false },
];

export default function CalendarView({ campaigns, onRefresh }: CalendarViewProps) {
  const { toast } = useToast();
  const [editing, setEditing] = useState<Creative | null>(null);
  const [editDraft, setEditDraft] = useState({ headline: "", body: "", caption: "", hashtags: "", cta: "" });
  const [saving, setSaving] = useState(false);
  const [scheduling, setScheduling] = useState(false);

  const days = useMemo(() => {
    const base = startOfDay(new Date());
    return Array.from({ length: 7 }, (_, i) => new Date(base.getTime() + i * DAY_MS));
  }, []);

  const allCreatives = useMemo(
    () => campaigns.flatMap((c) => c.creatives.map((cr) => ({ ...cr, campaignName: c.name, mode: c.mode }))),
    [campaigns]
  );
  const unscheduled = allCreatives.filter((c) => !c.scheduledFor && c.status !== "SKIPPED");
  const byDay = useMemo(() => {
    const map = new Map<number, (typeof allCreatives)[number][]>();
    for (const c of allCreatives) {
      if (!c.scheduledFor || c.status === "SKIPPED") continue;
      const d = startOfDay(new Date(c.scheduledFor)).getTime();
      const key = days.findIndex((day) => day.getTime() === d);
      if (key === -1) continue; // outside this week
      if (!map.has(key)) map.set(key, []);
      map.get(key)!.push(c);
    }
    return map;
  }, [allCreatives, days]);

  async function patchCreative(id: string, body: Record<string, unknown>, successMsg: string) {
    const res = await fetch(`/api/creatives/${id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (res.ok) {
      toast({ title: successMsg });
      onRefresh();
    } else {
      const data = await res.json().catch(() => ({}));
      toast({ title: "Update failed", description: data.error || "Try again." });
    }
  }

  async function scheduleAll() {
    setScheduling(true);
    try {
      const target = campaigns.find((c) => c.creatives.some((cr) => cr.status !== "SKIPPED" && !cr.scheduledFor));
      if (!target) {
        toast({ title: "Nothing to schedule", description: "Generate a campaign first, or everything is already on the calendar." });
        return;
      }
      const res = await fetch(`/api/campaigns/${target.id}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "schedule-all", startDay: 0, perDay: 2 }),
      });
      const data = await res.json();
      if (!res.ok) {
        toast({ title: "Scheduling failed", description: data.error || "Try again." });
        return;
      }
      toast({ title: `Scheduled ${data.scheduled} posts 🎉`, description: "They'll publish automatically at their time slots." });
      onRefresh();
    } finally {
      setScheduling(false);
    }
  }

  function openEdit(c: (typeof allCreatives)[number]) {
    setEditing(c);
    setEditDraft({ headline: c.headline, body: c.body, caption: c.caption || "", hashtags: c.hashtags || "", cta: c.cta || "" });
  }

  async function saveEdit() {
    if (!editing) return;
    setSaving(true);
    await patchCreative(editing.id, {
      headline: editDraft.headline, body: editDraft.body, caption: editDraft.caption,
      hashtags: editDraft.hashtags, cta: editDraft.cta, status: "APPROVED",
    }, "Creative updated & approved");
    setSaving(false);
    setEditing(null);
  }

  return (
    <div className="mx-auto w-full max-w-6xl px-4 py-6">
      {/* header */}
      <div className="mb-5 flex flex-wrap items-center justify-between gap-3">
        <div>
          <h1 className="flex items-center gap-2 text-xl font-bold">
            <CalendarCheck className="h-5 w-5 text-orange-600" /> Approve & Schedule
          </h1>
          <p className="text-sm text-stone-500">Review, tweak and slot posts. Organic mode publishes to connected feeds.</p>
        </div>
        <div className="flex items-center gap-2">
          <Badge variant="outline" className="gap-1.5 border-emerald-200 bg-emerald-50 py-1.5 text-emerald-700">
            <Link2 className="h-3 w-3" /> {CONNECTED.filter((c) => c.connected).length} accounts connected
          </Badge>
          <Button onClick={scheduleAll} disabled={scheduling || unscheduled.length === 0} className="bg-orange-600 hover:bg-orange-700">
            {scheduling ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Zap className="mr-2 h-4 w-4" />}
            Schedule All{unscheduled.length > 0 ? ` (${unscheduled.length})` : ""}
          </Button>
        </div>
      </div>

      {/* connected accounts strip */}
      <div className="mb-5 flex flex-wrap gap-2">
        {CONNECTED.map((acc) => (
          <div key={acc.name} className={`flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs ${acc.connected ? "border-stone-200 bg-white" : "border-dashed border-stone-300 bg-stone-50 text-stone-400"}`}>
            <span className={`h-2.5 w-2.5 rounded-full ${acc.color} ${acc.connected ? "" : "opacity-30"}`} />
            <span className="font-medium">{acc.name}</span>
            <span className="text-stone-400">{acc.connected ? acc.handle : "connect"}</span>
          </div>
        ))}
      </div>

      {/* week grid */}
      <div className="grid gap-3 md:grid-cols-4 lg:grid-cols-7">
        {days.map((day, i) => {
          const items = byDay.get(i) || [];
          const isToday = i === 0;
          return (
            <div key={i} className={`flex min-h-[220px] flex-col rounded-xl border ${isToday ? "border-orange-300 bg-orange-50/40" : "border-stone-200 bg-white"}`}>
              <div className={`flex items-center justify-between border-b px-3 py-2 ${isToday ? "border-orange-200" : "border-stone-100"}`}>
                <div>
                  <p className={`text-xs font-bold ${isToday ? "text-orange-700" : "text-stone-700"}`}>
                    {day.toLocaleDateString("en-US", { weekday: "short" })}
                  </p>
                  <p className="text-[10px] text-stone-400">
                    {day.toLocaleDateString("en-US", { month: "short", day: "numeric" })}
                    {isToday && " · today"}
                  </p>
                </div>
                {items.length > 0 && (
                  <span className="rounded-full bg-stone-900 px-1.5 py-0.5 text-[10px] font-bold text-white">{items.length}</span>
                )}
              </div>
              <div className="flex-1 space-y-2 p-2">
                {items.length === 0 && (
                  <p className="mt-6 text-center text-[11px] text-stone-300">No posts</p>
                )}
                {items.map((c) => (
                  <div key={c.id} className="group rounded-lg border border-stone-200 bg-stone-50 p-2 transition-colors hover:border-orange-200">
                    <div className="flex items-center gap-1">
                      <span className={`rounded px-1 py-0.5 text-[9px] font-bold ${CHANNEL_META[c.channel].chip}`}>{CHANNEL_META[c.channel].label}</span>
                      <button onClick={() => openEdit(c)} className="ml-auto text-stone-300 hover:text-stone-700" title="Edit">
                        <Pencil className="h-3 w-3" />
                      </button>
                    </div>
                    <p className="mt-1 line-clamp-2 text-[11px] font-medium leading-tight text-stone-800">{c.headline || c.body}</p>
                    <div className="mt-1.5 flex items-center justify-between">
                      <span className="flex items-center gap-0.5 text-[9px] text-stone-400">
                        <Clock className="h-2.5 w-2.5" />
                        {c.scheduledFor ? new Date(c.scheduledFor).toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" }) : ""}
                      </span>
                      <span className={`rounded-full px-1.5 py-0.5 text-[8px] font-bold ${c.status === "APPROVED" ? "bg-emerald-100 text-emerald-700" : "bg-amber-100 text-amber-700"}`}>
                        {c.status === "APPROVED" ? "READY" : "REVIEW"}
                      </span>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          );
        })}
      </div>

      {/* unscheduled tray */}
      <div className="mt-6 rounded-2xl border border-stone-200 bg-white">
        <div className="flex items-center justify-between border-b border-stone-100 px-4 py-3">
          <h2 className="flex items-center gap-2 text-sm font-semibold">
            <Inbox className="h-4 w-4 text-stone-400" /> Awaiting review
            <Badge variant="outline" className="ml-1 border-stone-200 text-[10px]">{unscheduled.length}</Badge>
          </h2>
          <p className="text-xs text-stone-400">Approve, tweak, or skip — then Schedule All</p>
        </div>
        <ScrollArea className="max-h-72">
          <div className="grid gap-3 p-4 sm:grid-cols-2 lg:grid-cols-3">
            {unscheduled.length === 0 && (
              <p className="col-span-full py-6 text-center text-sm text-stone-400">
                All clear — every creative is on the calendar. 🎯
              </p>
            )}
            {unscheduled.map((c) => (
              <div key={c.id} className="rounded-xl border border-stone-200 bg-stone-50 p-3">
                <div className="flex items-center justify-between">
                  <span className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${CHANNEL_META[c.channel].chip}`}>
                    {CHANNEL_META[c.channel].label}
                  </span>
                  <span className="text-[9px] text-stone-400">{FORMAT_LABEL[c.format] || c.format}</span>
                </div>
                <p className="mt-2 line-clamp-1 text-xs font-bold text-stone-800">{c.headline}</p>
                <p className="mt-1 line-clamp-2 text-[11px] leading-relaxed text-stone-600">{c.caption || c.body}</p>
                <div className="mt-2.5 flex items-center gap-1.5">
                  <Button size="sm" variant="outline" className="h-7 flex-1 border-emerald-200 text-emerald-700 hover:bg-emerald-50" onClick={() => patchCreative(c.id, { status: "APPROVED" }, "Approved ✓")}>
                    <Check className="mr-1 h-3 w-3" /> Approve
                  </Button>
                  <Button size="sm" variant="outline" className="h-7 flex-1" onClick={() => openEdit(c)}>
                    <Pencil className="mr-1 h-3 w-3" /> Edit
                  </Button>
                  <Button size="sm" variant="outline" className="h-7 w-8 p-0 text-stone-400 hover:text-red-600" title="Skip" onClick={() => patchCreative(c.id, { status: "SKIPPED" }, "Skipped")}>
                    <X className="h-3.5 w-3.5" />
                  </Button>
                </div>
              </div>
            ))}
          </div>
        </ScrollArea>
      </div>

      {/* edit dialog */}
      <Dialog open={!!editing} onOpenChange={(v) => !v && setEditing(null)}>
        <DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-lg" aria-describedby={undefined}>
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              Edit creative
              {editing && <Badge className={`border ${CHANNEL_META[editing.channel].chip} font-semibold hover:${CHANNEL_META[editing.channel].chip}`}>{CHANNEL_META[editing.channel].label}</Badge>}
            </DialogTitle>
          </DialogHeader>
          {editing && (
            <div className="space-y-3">
              <div>
                <Label className="text-xs">Headline</Label>
                <Input value={editDraft.headline} onChange={(e) => setEditDraft({ ...editDraft, headline: e.target.value })} className="mt-1" />
              </div>
              <div>
                <Label className="text-xs">{editing.caption !== null ? "Caption" : "Body"}</Label>
                <Textarea value={editing.caption !== null ? editDraft.caption : editDraft.body} onChange={(e) => editing.caption !== null ? setEditDraft({ ...editDraft, caption: e.target.value }) : setEditDraft({ ...editDraft, body: e.target.value })} rows={4} className="mt-1 resize-none" />
              </div>
              {editing.hashtags !== null && (
                <div>
                  <Label className="text-xs">Hashtags</Label>
                  <Input value={editDraft.hashtags} onChange={(e) => setEditDraft({ ...editDraft, hashtags: e.target.value })} className="mt-1" />
                </div>
              )}
              {editing.cta && (
                <div>
                  <Label className="text-xs">Call to action</Label>
                  <Input value={editDraft.cta} onChange={(e) => setEditDraft({ ...editDraft, cta: e.target.value })} className="mt-1" />
                </div>
              )}
              {editing.videoScript && (
                <div className="rounded-lg border border-fuchsia-200 bg-fuchsia-50 p-3">
                  <p className="text-xs font-semibold text-fuchsia-700">Video script (read-only)</p>
                  <p className="mt-1 whitespace-pre-wrap text-[11px] leading-relaxed text-fuchsia-900">{editing.videoScript}</p>
                </div>
              )}
              <div className="flex gap-2 pt-1">
                <Button onClick={saveEdit} disabled={saving} className="flex-1 bg-orange-600 hover:bg-orange-700">
                  {saving ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Check className="mr-2 h-4 w-4" />} Save & approve
                </Button>
                <Button
                  variant="outline"
                  className="border-red-200 text-red-600 hover:bg-red-50"
                  onClick={async () => {
                    await patchCreative(editing.id, { status: "SKIPPED" }, "Skipped");
                    setEditing(null);
                  }}
                >
                  <Trash2 className="mr-1 h-4 w-4" /> Skip
                </Button>
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}
