"use client";

import { useState, type FormEvent } from "react";
import { useRouter } from "next/navigation";
import type { Announcement } from "@/types/cms";
import { formatDate } from "@/lib/format";
import { Button } from "@/components/ui/button";
import { Input, Textarea } from "@/components/ui/input";
import { useConfirmDialog } from "@/components/ui/confirm-dialog";
import { useToast } from "@/components/ui/toast";
import { cardClasses } from "@/components/ui/styles";
import { cn } from "@/lib/utils";
import { clientFetch } from "@/lib/api/client";

interface AnnouncementFormState {
  title: string;
  content: string;
  is_active: boolean;
  starts_at: string;
  ends_at: string;
}

const EMPTY_FORM: AnnouncementFormState = {
  title: "",
  content: "",
  is_active: true,
  starts_at: "",
  ends_at: "",
};

function toDatetimeLocal(value: string | null) {
  if (!value) return "";
  return value.slice(0, 16);
}

export function AnnouncementManager({ announcements }: { announcements: Announcement[] }) {
  const router = useRouter();
  const [showCreate, setShowCreate] = useState(false);
  const [createForm, setCreateForm] = useState<AnnouncementFormState>(EMPTY_FORM);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [editForm, setEditForm] = useState<AnnouncementFormState>(EMPTY_FORM);
  const [error, setError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [deletingId, setDeletingId] = useState<number | null>(null);
  const { confirm, dialog } = useConfirmDialog();
  const { toast } = useToast();

  function toPayload(form: AnnouncementFormState) {
    return {
      title: form.title,
      content: form.content,
      is_active: form.is_active,
      starts_at: form.starts_at || null,
      ends_at: form.ends_at || null,
    };
  }

  async function handleCreate(formEvent: FormEvent<HTMLFormElement>) {
    formEvent.preventDefault();
    setError(null);
    setIsSubmitting(true);

    const res = await clientFetch("/api/admin/cms/announcements", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(toPayload(createForm)),
    });

    setIsSubmitting(false);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.errors?.ends_at?.[0] ?? body?.message ?? "Failed to create announcement.";
      setError(message);
      toast(message, "error");
      return;
    }

    setShowCreate(false);
    setCreateForm(EMPTY_FORM);
    toast("Announcement created successfully.", "success");
    router.refresh();
  }

  async function handleUpdate(formEvent: FormEvent<HTMLFormElement>, id: number) {
    formEvent.preventDefault();
    setError(null);
    setIsSubmitting(true);

    const res = await clientFetch(`/api/admin/cms/announcements/${id}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(toPayload(editForm)),
    });

    setIsSubmitting(false);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.errors?.ends_at?.[0] ?? body?.message ?? "Failed to update announcement.";
      setError(message);
      toast(message, "error");
      return;
    }

    setEditingId(null);
    toast("Announcement updated successfully.", "success");
    router.refresh();
  }

  async function handleDelete(id: number) {
    if (!(await confirm("Delete this announcement?"))) return;

    setError(null);
    setDeletingId(id);
    const res = await clientFetch(`/api/admin/cms/announcements/${id}`, { method: "DELETE" });
    setDeletingId(null);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to delete announcement.";
      setError(message);
      toast(message, "error");
      return;
    }
    toast("Announcement deleted successfully.", "success");
    router.refresh();
  }

  return (
    <div>
      {dialog}
      {error && <p className="mb-3 text-sm text-red-600">{error}</p>}

      <div className={cn("flex flex-col divide-y divide-kolabora-neutral-dark/10", cardClasses())}>
        {announcements.length === 0 && (
          <p className="px-4 py-6 text-center text-sm text-kolabora-neutral-dark/70">
            No announcements yet.
          </p>
        )}
        {announcements.map((announcement) =>
          editingId === announcement.id ? (
            <form
              key={announcement.id}
              onSubmit={(e) => handleUpdate(e, announcement.id)}
              className="flex flex-col gap-2 px-4 py-3"
            >
              <Input
                size="sm"
                required
                value={editForm.title}
                onChange={(e) => setEditForm({ ...editForm, title: e.target.value })}
                placeholder="Title"
              />
              <Textarea
                size="sm"
                required
                rows={3}
                value={editForm.content}
                onChange={(e) => setEditForm({ ...editForm, content: e.target.value })}
                placeholder="Announcement content"
              />
              <div className="flex flex-wrap items-center gap-3">
                <label className="flex flex-col gap-1 text-xs">
                  Starts
                  <Input
                    size="sm"
                    type="datetime-local"
                    value={editForm.starts_at}
                    onChange={(e) => setEditForm({ ...editForm, starts_at: e.target.value })}
                  />
                </label>
                <label className="flex flex-col gap-1 text-xs">
                  Ends
                  <Input
                    size="sm"
                    type="datetime-local"
                    value={editForm.ends_at}
                    onChange={(e) => setEditForm({ ...editForm, ends_at: e.target.value })}
                  />
                </label>
                <label className="flex items-center gap-1.5 text-sm">
                  <input
                    type="checkbox"
                    checked={editForm.is_active}
                    onChange={(e) => setEditForm({ ...editForm, is_active: e.target.checked })}
                  />
                  Active
                </label>
                <Button type="submit" size="sm" loading={isSubmitting} className="ml-auto">
                  Save
                </Button>
                <Button
                  type="button"
                  variant="secondary"
                  size="sm"
                  onClick={() => setEditingId(null)}
                  disabled={isSubmitting}
                >
                  Cancel
                </Button>
              </div>
            </form>
          ) : (
            <div key={announcement.id} className="flex items-start justify-between gap-3 px-4 py-3">
              <div>
                <p className="font-medium">{announcement.title}</p>
                <p className="mt-1 text-sm text-kolabora-neutral-dark/70">{announcement.content}</p>
                <p className="mt-1 text-xs text-kolabora-neutral-dark/70">
                  {announcement.starts_at && `Starts ${formatDate(announcement.starts_at)}`}
                  {announcement.starts_at && announcement.ends_at && " · "}
                  {announcement.ends_at && `Ends ${formatDate(announcement.ends_at)}`}
                </p>
                {!announcement.is_active && (
                  <span className="mt-1 inline-block rounded-full bg-kolabora-neutral-dark/10 px-2 py-0.5 text-xs">
                    Inactive
                  </span>
                )}
              </div>
              <div className="flex shrink-0 gap-2">
                <Button
                  type="button"
                  variant="secondary"
                  size="sm"
                  onClick={() => {
                    setEditingId(announcement.id);
                    setEditForm({
                      title: announcement.title,
                      content: announcement.content,
                      is_active: announcement.is_active,
                      starts_at: toDatetimeLocal(announcement.starts_at),
                      ends_at: toDatetimeLocal(announcement.ends_at),
                    });
                  }}
                >
                  Edit
                </Button>
                <Button
                  type="button"
                  variant="danger"
                  size="sm"
                  onClick={() => handleDelete(announcement.id)}
                  loading={deletingId === announcement.id}
                >
                  Delete
                </Button>
              </div>
            </div>
          ),
        )}
      </div>

      {showCreate ? (
        <form
          onSubmit={handleCreate}
          className={cn("mt-4 flex flex-col gap-2", cardClasses("p-4"))}
        >
          <Input
            required
            value={createForm.title}
            onChange={(e) => setCreateForm({ ...createForm, title: e.target.value })}
            placeholder="Title"
          />
          <Textarea
            required
            rows={3}
            value={createForm.content}
            onChange={(e) => setCreateForm({ ...createForm, content: e.target.value })}
            placeholder="Announcement content"
          />
          <div className="flex flex-wrap items-center gap-3">
            <label className="flex flex-col gap-1 text-xs">
              Starts
              <Input
                type="datetime-local"
                value={createForm.starts_at}
                onChange={(e) => setCreateForm({ ...createForm, starts_at: e.target.value })}
              />
            </label>
            <label className="flex flex-col gap-1 text-xs">
              Ends
              <Input
                type="datetime-local"
                value={createForm.ends_at}
                onChange={(e) => setCreateForm({ ...createForm, ends_at: e.target.value })}
              />
            </label>
            <label className="flex items-center gap-1.5 text-sm">
              <input
                type="checkbox"
                checked={createForm.is_active}
                onChange={(e) => setCreateForm({ ...createForm, is_active: e.target.checked })}
              />
              Active
            </label>
            <Button type="submit" loading={isSubmitting} className="ml-auto">
              Save
            </Button>
            <Button type="button" variant="secondary" onClick={() => setShowCreate(false)} disabled={isSubmitting}>
              Cancel
            </Button>
          </div>
        </form>
      ) : (
        <Button type="button" onClick={() => setShowCreate(true)} className="mt-4">
          + Add Announcement
        </Button>
      )}
    </div>
  );
}
