"use client";

import { useState } from "react";
import {
  FaGripVertical,
  FaTrash,
  FaPlus,
} from "react-icons/fa";

import BlogEditor from "./BlogEditor";

/* =========================================================
   TYPES
========================================================= */

export type BlogSectionType =
  | "introduction"
  | "numbered"
  | "two-column"
  | "standard";

/* =========================================================
   NUMBERED POINT
========================================================= */

export interface NumberedPoint {
  title: string;
  description: string;
}

/* =========================================================
   CARD POINT
========================================================= */

export interface BlogCardPoint {
  title: string;
  description: string;
}

/* =========================================================
   BLOG CARD
========================================================= */

export interface BlogCard {
  title: string;
  description: string;
  points: BlogCardPoint[];
}

/* =========================================================
   BLOG SECTION
========================================================= */

export interface BlogSection {
  id: string;

  type: BlogSectionType;

  /* Section-level content */
  title: string;
  content: string;

  /* Numbered section */
  points: NumberedPoint[];

  /* Two-column / card section */
  cards: BlogCard[];
}

/* =========================================================
   PROPS
========================================================= */

interface Props {
  sections: BlogSection[];

  setSections: React.Dispatch<
    React.SetStateAction<BlogSection[]>
  >;
}

/* =========================================================
   CREATE ID
========================================================= */

const createId = () => {
  if (
    typeof crypto !== "undefined" &&
    typeof crypto.randomUUID === "function"
  ) {
    return crypto.randomUUID();
  }

  return `${Date.now()}-${Math.random()}`;
};

/* =========================================================
   CREATE EMPTY CARD POINT
========================================================= */

const createCardPoint = (): BlogCardPoint => ({
  title: "",
  description: "",
});

/* =========================================================
   CREATE EMPTY CARD
========================================================= */

const createCard = (): BlogCard => ({
  title: "",
  description: "",
  points: [createCardPoint()],
});

/* =========================================================
   CREATE EMPTY SECTION
========================================================= */

const createSection = (
  type: BlogSectionType = "standard"
): BlogSection => ({
  id: createId(),

  type,

  title: "",

  content: "",

  points: [
    {
      title: "",
      description: "",
    },
  ],

  cards: [createCard()],
});

/* =========================================================
   COMPONENT
========================================================= */

export default function BlogSectionEditor({
  sections,
  setSections,
}: Props) {
  const [openSection, setOpenSection] =
    useState<string | null>(
      sections[0]?.id || null
    );

  /* =======================================================
     ADD SECTION
  ======================================================= */

  const addSection = () => {
    const newSection =
      createSection("standard");

    setSections((prev) => [
      ...prev,
      newSection,
    ]);

    setOpenSection(newSection.id);
  };

  /* =======================================================
     UPDATE SECTION
  ======================================================= */

  const updateSection = (
    id: string,
    updates: Partial<BlogSection>
  ) => {
    setSections((prev) =>
      prev.map((section) =>
        section.id === id
          ? {
              ...section,
              ...updates,
            }
          : section
      )
    );
  };

  /* =======================================================
     DELETE SECTION
  ======================================================= */

  const deleteSection = (id: string) => {
    const confirmed = window.confirm(
      "Are you sure you want to delete this section?"
    );

    if (!confirmed) return;

    setSections((prev) =>
      prev.filter(
        (section) => section.id !== id
      )
    );

    if (openSection === id) {
      setOpenSection(null);
    }
  };

  /* =======================================================
     CHANGE SECTION TYPE
  ======================================================= */

  const changeSectionType = (
    id: string,
    type: BlogSectionType
  ) => {
    updateSection(id, {
      type,
    });
  };

  /* =======================================================
     NUMBERED POINTS
  ======================================================= */

  const addNumberedPoint = (
    sectionId: string
  ) => {
    setSections((prev) =>
      prev.map((section) =>
        section.id === sectionId
          ? {
              ...section,
              points: [
                ...section.points,
                {
                  title: "",
                  description: "",
                },
              ],
            }
          : section
      )
    );
  };

  const updateNumberedPoint = (
    sectionId: string,
    pointIndex: number,
    updates: Partial<NumberedPoint>
  ) => {
    setSections((prev) =>
      prev.map((section) => {
        if (section.id !== sectionId) {
          return section;
        }

        const points = [
          ...section.points,
        ];

        points[pointIndex] = {
          ...points[pointIndex],
          ...updates,
        };

        return {
          ...section,
          points,
        };
      })
    );
  };

  const deleteNumberedPoint = (
    sectionId: string,
    pointIndex: number
  ) => {
    setSections((prev) =>
      prev.map((section) => {
        if (section.id !== sectionId) {
          return section;
        }

        const points =
          section.points.filter(
            (_, index) =>
              index !== pointIndex
          );

        return {
          ...section,
          points:
            points.length > 0
              ? points
              : [
                  {
                    title: "",
                    description: "",
                  },
                ],
        };
      })
    );
  };

  /* =======================================================
     ADD CARD
  ======================================================= */

  const addCard = (
    sectionId: string
  ) => {
    setSections((prev) =>
      prev.map((section) =>
        section.id === sectionId
          ? {
              ...section,
              cards: [
                ...section.cards,
                createCard(),
              ],
            }
          : section
      )
    );
  };

  /* =======================================================
     UPDATE CARD
  ======================================================= */

  const updateCard = (
    sectionId: string,
    cardIndex: number,
    updates: Partial<BlogCard>
  ) => {
    setSections((prev) =>
      prev.map((section) => {
        if (section.id !== sectionId) {
          return section;
        }

        const cards = [
          ...section.cards,
        ];

        cards[cardIndex] = {
          ...cards[cardIndex],
          ...updates,
        };

        return {
          ...section,
          cards,
        };
      })
    );
  };

  /* =======================================================
     DELETE CARD
  ======================================================= */

  const deleteCard = (
    sectionId: string,
    cardIndex: number
  ) => {
    setSections((prev) =>
      prev.map((section) => {
        if (section.id !== sectionId) {
          return section;
        }

        const cards =
          section.cards.filter(
            (_, index) =>
              index !== cardIndex
          );

        return {
          ...section,
          cards,
        };
      })
    );
  };

  /* =======================================================
     ADD CARD POINT
  ======================================================= */

  const addCardPoint = (
    sectionId: string,
    cardIndex: number
  ) => {
    setSections((prev) =>
      prev.map((section) => {
        if (section.id !== sectionId) {
          return section;
        }

        const cards = [
          ...section.cards,
        ];

        cards[cardIndex] = {
          ...cards[cardIndex],
          points: [
            ...cards[cardIndex].points,
            createCardPoint(),
          ],
        };

        return {
          ...section,
          cards,
        };
      })
    );
  };

  /* =======================================================
     UPDATE CARD POINT
  ======================================================= */

  const updateCardPoint = (
    sectionId: string,
    cardIndex: number,
    pointIndex: number,
    updates: Partial<BlogCardPoint>
  ) => {
    setSections((prev) =>
      prev.map((section) => {
        if (section.id !== sectionId) {
          return section;
        }

        const cards = [
          ...section.cards,
        ];

        const points = [
          ...cards[cardIndex].points,
        ];

        points[pointIndex] = {
          ...points[pointIndex],
          ...updates,
        };

        cards[cardIndex] = {
          ...cards[cardIndex],
          points,
        };

        return {
          ...section,
          cards,
        };
      })
    );
  };

  /* =======================================================
     DELETE CARD POINT
  ======================================================= */

  const deleteCardPoint = (
    sectionId: string,
    cardIndex: number,
    pointIndex: number
  ) => {
    setSections((prev) =>
      prev.map((section) => {
        if (section.id !== sectionId) {
          return section;
        }

        const cards = [
          ...section.cards,
        ];

        const points =
          cards[cardIndex].points.filter(
            (_, index) =>
              index !== pointIndex
          );

        cards[cardIndex] = {
          ...cards[cardIndex],
          points,
        };

        return {
          ...section,
          cards,
        };
      })
    );
  };

  /* =======================================================
     RENDER CARD
  ======================================================= */

  const renderCard = (
    section: BlogSection,
    card: BlogCard,
    cardIndex: number
  ) => {
    return (
      <div
        key={cardIndex}
        className="rounded-2xl border border-stone-200 bg-stone-50 p-5"
      >
        {/* CARD HEADER */}

        <div className="mb-5 flex items-center justify-between">
          <div>
            <h4 className="text-sm font-semibold text-espresso">
              Card {cardIndex + 1}
            </h4>

            <p className="mt-1 text-xs text-gray-500">
              Card content displayed inside the dropdown.
            </p>
          </div>

          <button
            type="button"
            onClick={() =>
              deleteCard(
                section.id,
                cardIndex
              )
            }
            className="rounded-lg p-2 text-red-500 transition hover:bg-red-50"
            title="Delete card"
          >
            <FaTrash size={12} />
          </button>
        </div>

        {/* CARD TITLE */}

        <div>
          <label className="mb-2 block text-sm font-semibold text-espresso">
            Card Title
          </label>

          <input
            value={card.title}
            onChange={(e) =>
              updateCard(
                section.id,
                cardIndex,
                {
                  title:
                    e.target.value,
                }
              )
            }
            className="w-full rounded-xl border bg-white p-3 text-sm outline-none focus:border-[#C9A227]"
            placeholder="Enter card title"
          />
        </div>

        {/* CARD DESCRIPTION */}

        <div className="mt-5">
          <label className="mb-2 block text-sm font-semibold text-espresso">
            Card Description
            <span className="ml-2 text-xs font-normal text-gray-400">
              Optional
            </span>
          </label>

          <BlogEditor
            value={card.description}
            onChange={(html) =>
              updateCard(
                section.id,
                cardIndex,
                {
                  description: html,
                }
              )
            }
          />
        </div>

        {/* CARD POINTS */}

        <div className="mt-6 border-t border-stone-200 pt-5">
          <div className="mb-4 flex items-center justify-between">
            <div>
              <label className="block text-sm font-semibold text-espresso">
                Card Points
              </label>

              <p className="mt-1 text-xs text-gray-500">
                Each point has its own title and description.
              </p>
            </div>

            <button
              type="button"
              onClick={() =>
                addCardPoint(
                  section.id,
                  cardIndex
                )
              }
              className="inline-flex items-center gap-2 rounded-lg border border-[#C9A227] px-3 py-2 text-xs text-espresso transition hover:bg-[#C9A227] hover:text-white"
            >
              <FaPlus size={9} />
              Add Point
            </button>
          </div>

          <div className="space-y-4">
            {card.points.map(
              (point, pointIndex) => (
                <div
                  key={pointIndex}
                  className="rounded-xl border border-stone-200 bg-white p-4"
                >
                  <div className="mb-4 flex items-center justify-between">
                    <span className="flex h-8 w-8 items-center justify-center rounded-lg bg-[#C9A227]/10 text-xs text-[#9c7b13]">
                      {pointIndex + 1}
                    </span>

                    <button
                      type="button"
                      onClick={() =>
                        deleteCardPoint(
                          section.id,
                          cardIndex,
                          pointIndex
                        )
                      }
                      className="rounded-lg p-2 text-red-500 transition hover:bg-red-50"
                      title="Delete point"
                    >
                      <FaTrash size={11} />
                    </button>
                  </div>

                  {/* POINT TITLE */}

                  <div>
                    <label className="mb-2 block text-sm font-semibold text-espresso">
                      Point Title
                    </label>

                    <input
                      value={point.title}
                      onChange={(e) =>
                        updateCardPoint(
                          section.id,
                          cardIndex,
                          pointIndex,
                          {
                            title:
                              e.target.value,
                          }
                        )
                      }
                      className="w-full rounded-xl border p-3 text-sm outline-none focus:border-[#C9A227]"
                      placeholder="Point title"
                    />
                  </div>

                  {/* POINT DESCRIPTION */}

                  <div className="mt-4">
                    <label className="mb-2 block text-sm font-semibold text-espresso">
                      Point Description
                      <span className="ml-2 text-xs font-normal text-gray-400">
                        Optional
                      </span>
                    </label>

                    <BlogEditor
                      value={
                        point.description
                      }
                      onChange={(html) =>
                        updateCardPoint(
                          section.id,
                          cardIndex,
                          pointIndex,
                          {
                            description:
                              html,
                          }
                        )
                      }
                    />
                  </div>
                </div>
              )
            )}
          </div>
        </div>
      </div>
    );
  };

  /* =======================================================
     RENDER
  ======================================================= */

  return (
    <div className="space-y-6">
      {/* HEADER */}

      <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h2 className="text-xl font-bold text-espresso">
            Blog Sections
          </h2>

          <p className="mt-1 text-sm text-gray-500">
            Build your blog using different content layouts.
          </p>
        </div>

        <button
          type="button"
          onClick={addSection}
          className="inline-flex items-center justify-center gap-2 rounded-xl bg-[#C9A227] px-5 py-3 text-sm font-semibold text-white transition hover:bg-[#b08d1d]"
        >
          <FaPlus size={11} />
          Add Section
        </button>
      </div>

      {/* EMPTY STATE */}

      {sections.length === 0 && (
        <div className="rounded-2xl border border-dashed border-stone-300 bg-stone-50 px-6 py-12 text-center">
          <h3 className="font-serif text-xl text-espresso">
            No sections added
          </h3>

          <p className="mt-2 text-sm text-gray-500">
            Start building your blog by adding your first section.
          </p>

          <button
            type="button"
            onClick={addSection}
            className="mt-5 rounded-lg border border-[#C9A227] px-5 py-2 text-sm text-espresso transition hover:bg-[#C9A227] hover:text-white"
          >
            Add First Section
          </button>
        </div>
      )}

      {/* SECTIONS */}

      {sections.map(
        (section, sectionIndex) => {
          const isOpen =
            openSection === section.id;

          return (
            <div
              key={section.id}
              className="overflow-hidden rounded-2xl border border-stone-200 bg-white shadow-sm"
            >
              {/* SECTION HEADER */}

              <div className="flex items-center justify-between gap-4 border-b border-stone-200 bg-stone-50 px-5 py-4">
                <button
                  type="button"
                  onClick={() =>
                    setOpenSection(
                      isOpen
                        ? null
                        : section.id
                    )
                  }
                  className="flex min-w-0 flex-1 items-center gap-3 text-left"
                >
                  <FaGripVertical className="shrink-0 text-stone-400" />

                  <div className="min-w-0">
                    <div className="flex flex-wrap items-center gap-2">
                      <span className="text-sm font-semibold text-espresso">
                        Section{" "}
                        {sectionIndex + 1}
                      </span>

                      <span className="rounded-full bg-[#C9A227]/10 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-[#9c7b13]">
                        {section.type ===
                        "two-column"
                          ? "Cards"
                          : section.type ===
                            "numbered"
                          ? "Numbered Points"
                          : section.type ===
                            "introduction"
                          ? "Introduction"
                          : "Standard"}
                      </span>
                    </div>

                    <p className="mt-1 truncate text-sm text-gray-500">
                      {section.title ||
                        "Untitled section"}
                    </p>
                  </div>
                </button>

                <button
                  type="button"
                  onClick={() =>
                    deleteSection(
                      section.id
                    )
                  }
                  className="shrink-0 rounded-lg p-2 text-red-500 transition hover:bg-red-50"
                  title="Delete section"
                >
                  <FaTrash size={13} />
                </button>
              </div>

              {/* SECTION CONTENT */}

              {isOpen && (
                <div className="space-y-6 p-6">
                  {/* SECTION DESIGN */}

                  <div>
                    <label className="mb-2 block text-sm font-semibold text-espresso">
                      Section Design
                    </label>

                    <select
                      value={section.type}
                      onChange={(e) =>
                        changeSectionType(
                          section.id,
                          e.target
                            .value as BlogSectionType
                        )
                      }
                      className="w-full rounded-xl border bg-white p-3 text-sm outline-none focus:border-[#C9A227]"
                    >
                      <option value="introduction">
                        Introduction
                      </option>

                      <option value="numbered">
                        Numbered Points
                      </option>

                      <option value="two-column">
                        Cards / Dropdown
                      </option>

                      <option value="standard">
                        Standard Content
                      </option>
                    </select>
                  </div>

                  {/* SECTION TITLE */}

                  <div>
                    <label className="mb-2 block text-sm font-semibold text-espresso">
                      Section Title
                    </label>

                    <input
                      value={section.title}
                      onChange={(e) =>
                        updateSection(
                          section.id,
                          {
                            title:
                              e.target
                                .value,
                          }
                        )
                      }
                      className="w-full rounded-xl border p-3 text-sm outline-none focus:border-[#C9A227]"
                      placeholder="Enter section title"
                    />
                  </div>

                  {/* SECTION DESCRIPTION FOR CARDS */}

                  {section.type ===
                    "two-column" && (
                    <div>
                      <label className="mb-2 block text-sm font-semibold text-espresso">
                        Section Description
                        <span className="ml-2 text-xs font-normal text-gray-400">
                          Optional
                        </span>
                      </label>

                      <BlogEditor
                        value={
                          section.content
                        }
                        onChange={(html) =>
                          updateSection(
                            section.id,
                            {
                              content:
                                html,
                            }
                          )
                        }
                      />
                    </div>
                  )}

                  {/* INTRODUCTION */}

                  {section.type ===
                    "introduction" && (
                    <div>
                      <label className="mb-2 block text-sm font-semibold text-espresso">
                        Introduction Content
                      </label>

                      <BlogEditor
                        value={
                          section.content
                        }
                        onChange={(html) =>
                          updateSection(
                            section.id,
                            {
                              content:
                                html,
                            }
                          )
                        }
                      />
                    </div>
                  )}

                  {/* NUMBERED */}

                  {section.type ===
                    "numbered" && (
                    <div>
                      <div className="mb-4">
                        <label className="block text-sm font-semibold text-espresso">
                          Numbered Points
                        </label>

                        <p className="mt-1 text-xs text-gray-500">
                          Each point can have its own title and description.
                        </p>
                      </div>

                      <div className="space-y-4">
                        {section.points.map(
                          (
                            point,
                            pointIndex
                          ) => (
                            <div
                              key={
                                pointIndex
                              }
                              className="rounded-xl border border-stone-200 bg-stone-50 p-4"
                            >
                              <div className="flex items-start gap-3">
                                <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[#C9A227]/10 font-serif text-sm text-[#9c7b13]">
                                  {String(
                                    pointIndex +
                                      1
                                  ).padStart(
                                    2,
                                    "0"
                                  )}
                                </span>

                                <div className="min-w-0 flex-1 space-y-3">
                                  <input
                                    value={
                                      point.title
                                    }
                                    onChange={(
                                      e
                                    ) =>
                                      updateNumberedPoint(
                                        section.id,
                                        pointIndex,
                                        {
                                          title:
                                            e
                                              .target
                                              .value,
                                        }
                                      )
                                    }
                                    className="w-full rounded-xl border bg-white p-3 text-sm outline-none focus:border-[#C9A227]"
                                    placeholder="Point title"
                                  />

                                  <BlogEditor
                                    value={
                                      point.description
                                    }
                                    onChange={(
                                      html
                                    ) =>
                                      updateNumberedPoint(
                                        section.id,
                                        pointIndex,
                                        {
                                          description:
                                            html,
                                        }
                                      )
                                    }
                                  />
                                </div>

                                <button
                                  type="button"
                                  onClick={() =>
                                    deleteNumberedPoint(
                                      section.id,
                                      pointIndex
                                    )
                                  }
                                  className="shrink-0 rounded-lg p-2 text-red-500 hover:bg-red-50"
                                >
                                  <FaTrash
                                    size={12}
                                  />
                                </button>
                              </div>
                            </div>
                          )
                        )}
                      </div>

                      <button
                        type="button"
                        onClick={() =>
                          addNumberedPoint(
                            section.id
                          )
                        }
                        className="mt-4 inline-flex items-center gap-2 rounded-lg border border-[#C9A227] px-4 py-2 text-sm text-espresso transition hover:bg-[#C9A227] hover:text-white"
                      >
                        <FaPlus size={10} />
                        Add Point
                      </button>
                    </div>
                  )}

                  {/* CARDS */}

                  {section.type ===
                    "two-column" && (
                    <div>
                      <div className="mb-5 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                        <div>
                          <label className="block text-sm font-semibold text-espresso">
                            Cards
                          </label>

                          <p className="mt-1 text-xs text-gray-500">
                            Add as many cards as needed. The website automatically arranges them into the appropriate layout.
                          </p>
                        </div>

                        <button
                          type="button"
                          onClick={() =>
                            addCard(
                              section.id
                            )
                          }
                          className="inline-flex items-center justify-center gap-2 rounded-lg bg-[#C9A227] px-4 py-2 text-sm font-semibold text-white transition hover:bg-[#b08d1d]"
                        >
                          <FaPlus size={10} />
                          Add Card
                        </button>
                      </div>

                      <div className="space-y-6">
                        {section.cards.map(
                          (
                            card,
                            cardIndex
                          ) =>
                            renderCard(
                              section,
                              card,
                              cardIndex
                            )
                        )}
                      </div>
                    </div>
                  )}

                  {/* STANDARD */}

                  {section.type ===
                    "standard" && (
                    <div>
                      <label className="mb-2 block text-sm font-semibold text-espresso">
                        Section Content
                      </label>

                      <BlogEditor
                        value={
                          section.content
                        }
                        onChange={(html) =>
                          updateSection(
                            section.id,
                            {
                              content:
                                html,
                            }
                          )
                        }
                      />
                    </div>
                  )}
                </div>
              )}
            </div>
          );
        }
      )}
    </div>
  );
}
