import { Input } from "@/components/ui/input";
import { CardEditGroup, CardEditPanel } from "./CardEditLayout";
import { EmojiPickerField } from "./EmojiPickerField";
import {
    defaultHowItWorksContent,
    parseProgressHowItWorksContent,
} from "@/components/page-blocks/ProgressHowItWorksBlock";
import type {
    HeatmapStudent,
    IconCard,
    MasteryScaleLevel,
    ReadTip,
    TimelineItem,
} from "@/components/page-blocks/progress-report/types";

type BlockContent = Record<string, unknown>;

const formRow = "mb-4";
const labelCls = "block text-sm font-medium text-slate-700 mb-1.5";
const sectionCls = "mt-6 mb-2 text-xs font-semibold uppercase tracking-wide text-slate-500";

const COLOR_OPTIONS = [
    { value: "moss", label: "Moss" },
    { value: "deep-sea", label: "Deep Sea" },
    { value: "sunflower", label: "Sunflower" },
    { value: "valencia", label: "Valencia" },
];

function moveItem<T>(items: T[], index: number, direction: -1 | 1): T[] {
    const target = index + direction;
    if (target < 0 || target >= items.length) return items;
    const next = [...items];
    [next[index], next[target]] = [next[target], next[index]];
    return next;
}

function emptyCard(): IconCard {
    return { emoji: "📌", title: "", description: "", color: "" };
}

function emptyScale(): MasteryScaleLevel {
    return { level: 1, label: "", color: "valencia", description: "" };
}

function emptyTimeline(): TimelineItem {
    return { quarter: "", month: "", label: "", description: "" };
}

function emptyTip(): ReadTip {
    return { lead: "", text: "" };
}

function emptyStudent(columns: number): HeatmapStudent {
    return { name: "", scores: Array.from({ length: columns }, () => 1) };
}

export function ProgressHowItWorksForm({
    content,
    onChange,
}: {
    content: BlockContent;
    onChange: (content: BlockContent) => void;
}) {
    const data = parseProgressHowItWorksContent(
        Object.keys(content).length > 0 ? content : defaultHowItWorksContent() as unknown as BlockContent,
    );
    const set = (patch: Partial<BlockContent>) => onChange({ ...content, ...data, ...patch });

    return (
        <>
            <p className="text-[11px] text-slate-500 mb-4 rounded-lg bg-slate-50 border border-slate-200 px-3 py-2">
                Content for the Progress Report &quot;How It Works&quot; tab. Pair with Grade Hero → Competition
                Navigation targeting this component.
            </p>

            <p className={sectionCls}>Why Mastery</p>
            <div className={formRow}>
                <label className={labelCls}>Section title</label>
                <Input value={data.whyTitle} onChange={(e) => set({ whyTitle: e.target.value })} />
            </div>
            <div className={formRow}>
                <label className={labelCls}>Intro (HTML allowed)</label>
                <textarea
                    value={data.whyIntroHtml}
                    onChange={(e) => set({ whyIntroHtml: e.target.value })}
                    rows={3}
                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                />
            </div>
            <div className={formRow}>
                <CardEditGroup
                    label="Why Mastery cards"
                    layout="grid-3"
                    onAdd={() => set({ whyCards: [...data.whyCards, emptyCard()] })}
                    addLabel="Add card"
                    isEmpty={data.whyCards.length === 0}
                >
                    {data.whyCards.map((card, index) => (
                        <CardEditPanel
                            key={`why-${index}`}
                            index={index}
                            total={data.whyCards.length}
                            layout="grid-3"
                            positionLabel={`Card ${index + 1}`}
                            label={card.title || `Card ${index + 1}`}
                            preview={{ emoji: card.emoji, title: card.title, subtitle: card.description }}
                            onMoveUp={index > 0 ? () => set({ whyCards: moveItem(data.whyCards, index, -1) }) : undefined}
                            onMoveDown={index < data.whyCards.length - 1 ? () => set({ whyCards: moveItem(data.whyCards, index, 1) }) : undefined}
                            onInsertAfter={() => set({
                                whyCards: [...data.whyCards.slice(0, index + 1), emptyCard(), ...data.whyCards.slice(index + 1)],
                            })}
                            onRemove={data.whyCards.length > 1
                                ? () => set({ whyCards: data.whyCards.filter((_, i) => i !== index) })
                                : undefined}
                        >
                            <div className="mb-3">
                                <label className={labelCls}>Emoji</label>
                                <EmojiPickerField
                                    compact
                                    value={card.emoji}
                                    onChange={(value) => set({
                                        whyCards: data.whyCards.map((item, i) => (i === index ? { ...item, emoji: value } : item)),
                                    })}
                                />
                            </div>
                            <div className="mb-3">
                                <label className={labelCls}>Title</label>
                                <Input
                                    value={card.title}
                                    onChange={(e) => set({
                                        whyCards: data.whyCards.map((item, i) => (i === index ? { ...item, title: e.target.value } : item)),
                                    })}
                                />
                            </div>
                            <div>
                                <label className={labelCls}>Description</label>
                                <textarea
                                    value={card.description}
                                    onChange={(e) => set({
                                        whyCards: data.whyCards.map((item, i) => (i === index ? { ...item, description: e.target.value } : item)),
                                    })}
                                    rows={3}
                                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                                />
                            </div>
                        </CardEditPanel>
                    ))}
                </CardEditGroup>
            </div>

            <p className={sectionCls}>Mastery Scale</p>
            <div className={formRow}>
                <label className={labelCls}>Title</label>
                <Input value={data.scaleTitle} onChange={(e) => set({ scaleTitle: e.target.value })} />
            </div>
            <div className={formRow}>
                <label className={labelCls}>Subtitle</label>
                <Input value={data.scaleSubtitle} onChange={(e) => set({ scaleSubtitle: e.target.value })} />
            </div>
            <div className={formRow}>
                <CardEditGroup
                    label="Scale levels"
                    layout="grid-2"
                    onAdd={() => set({ masteryScale: [...data.masteryScale, emptyScale()] })}
                    addLabel="Add level"
                    isEmpty={data.masteryScale.length === 0}
                >
                    {data.masteryScale.map((level, index) => (
                        <CardEditPanel
                            key={`scale-${index}`}
                            index={index}
                            total={data.masteryScale.length}
                            layout="grid-2"
                            positionLabel={`Level ${index + 1}`}
                            label={level.label || `Level ${level.level}`}
                            preview={{ title: `${level.level} – ${level.label}`, subtitle: level.description }}
                            onMoveUp={index > 0 ? () => set({ masteryScale: moveItem(data.masteryScale, index, -1) }) : undefined}
                            onMoveDown={index < data.masteryScale.length - 1 ? () => set({ masteryScale: moveItem(data.masteryScale, index, 1) }) : undefined}
                            onInsertAfter={() => set({
                                masteryScale: [...data.masteryScale.slice(0, index + 1), emptyScale(), ...data.masteryScale.slice(index + 1)],
                            })}
                            onRemove={data.masteryScale.length > 1
                                ? () => set({ masteryScale: data.masteryScale.filter((_, i) => i !== index) })
                                : undefined}
                        >
                            <div className="grid grid-cols-2 gap-3 mb-3">
                                <div>
                                    <label className={labelCls}>Level #</label>
                                    <Input
                                        type="number"
                                        value={level.level}
                                        onChange={(e) => set({
                                            masteryScale: data.masteryScale.map((item, i) => (
                                                i === index ? { ...item, level: Number(e.target.value) || 0 } : item
                                            )),
                                        })}
                                    />
                                </div>
                                <div>
                                    <label className={labelCls}>Color</label>
                                    <select
                                        value={level.color}
                                        onChange={(e) => set({
                                            masteryScale: data.masteryScale.map((item, i) => (
                                                i === index ? { ...item, color: e.target.value } : item
                                            )),
                                        })}
                                        className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                                    >
                                        {COLOR_OPTIONS.map((option) => (
                                            <option key={option.value} value={option.value}>{option.label}</option>
                                        ))}
                                    </select>
                                </div>
                            </div>
                            <div className="mb-3">
                                <label className={labelCls}>Label</label>
                                <Input
                                    value={level.label}
                                    onChange={(e) => set({
                                        masteryScale: data.masteryScale.map((item, i) => (
                                            i === index ? { ...item, label: e.target.value } : item
                                        )),
                                    })}
                                />
                            </div>
                            <div>
                                <label className={labelCls}>Description</label>
                                <textarea
                                    value={level.description}
                                    onChange={(e) => set({
                                        masteryScale: data.masteryScale.map((item, i) => (
                                            i === index ? { ...item, description: e.target.value } : item
                                        )),
                                    })}
                                    rows={2}
                                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                                />
                            </div>
                        </CardEditPanel>
                    ))}
                </CardEditGroup>
            </div>

            <p className={sectionCls}>How We Track Progress</p>
            <div className={formRow}>
                <label className={labelCls}>Title</label>
                <Input value={data.trackTitle} onChange={(e) => set({ trackTitle: e.target.value })} />
            </div>
            <div className={formRow}>
                <label className={labelCls}>Intro (HTML allowed)</label>
                <textarea
                    value={data.trackIntroHtml}
                    onChange={(e) => set({ trackIntroHtml: e.target.value })}
                    rows={3}
                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                />
            </div>
            <div className={formRow}>
                <CardEditGroup
                    label="Track cards"
                    layout="grid-2"
                    onAdd={() => set({ trackCards: [...data.trackCards, emptyCard()] })}
                    addLabel="Add card"
                    isEmpty={data.trackCards.length === 0}
                >
                    {data.trackCards.map((card, index) => (
                        <CardEditPanel
                            key={`track-${index}`}
                            index={index}
                            total={data.trackCards.length}
                            layout="grid-2"
                            positionLabel={`Card ${index + 1}`}
                            label={card.title || `Card ${index + 1}`}
                            preview={{ emoji: card.emoji, title: card.title, subtitle: card.description }}
                            onMoveUp={index > 0 ? () => set({ trackCards: moveItem(data.trackCards, index, -1) }) : undefined}
                            onMoveDown={index < data.trackCards.length - 1 ? () => set({ trackCards: moveItem(data.trackCards, index, 1) }) : undefined}
                            onInsertAfter={() => set({
                                trackCards: [...data.trackCards.slice(0, index + 1), emptyCard(), ...data.trackCards.slice(index + 1)],
                            })}
                            onRemove={data.trackCards.length > 1
                                ? () => set({ trackCards: data.trackCards.filter((_, i) => i !== index) })
                                : undefined}
                        >
                            <div className="mb-3">
                                <label className={labelCls}>Emoji</label>
                                <EmojiPickerField
                                    compact
                                    value={card.emoji}
                                    onChange={(value) => set({
                                        trackCards: data.trackCards.map((item, i) => (i === index ? { ...item, emoji: value } : item)),
                                    })}
                                />
                            </div>
                            <div className="mb-3">
                                <label className={labelCls}>Title</label>
                                <Input
                                    value={card.title}
                                    onChange={(e) => set({
                                        trackCards: data.trackCards.map((item, i) => (i === index ? { ...item, title: e.target.value } : item)),
                                    })}
                                />
                            </div>
                            <div>
                                <label className={labelCls}>Description</label>
                                <textarea
                                    value={card.description}
                                    onChange={(e) => set({
                                        trackCards: data.trackCards.map((item, i) => (i === index ? { ...item, description: e.target.value } : item)),
                                    })}
                                    rows={3}
                                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                                />
                            </div>
                        </CardEditPanel>
                    ))}
                </CardEditGroup>
            </div>

            <p className={sectionCls}>Heatmap</p>
            <div className={formRow}>
                <label className={labelCls}>Heatmap title</label>
                <Input value={data.heatmapTitle} onChange={(e) => set({ heatmapTitle: e.target.value })} />
            </div>
            <div className={formRow}>
                <label className={labelCls}>Heatmap description</label>
                <textarea
                    value={data.heatmapDescription}
                    onChange={(e) => set({ heatmapDescription: e.target.value })}
                    rows={2}
                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                />
            </div>
            <div className={formRow}>
                <label className={labelCls}>Columns (comma-separated)</label>
                <Input
                    value={data.heatmapColumns.join(", ")}
                    onChange={(e) => {
                        const columns = e.target.value.split(",").map((part) => part.trim()).filter(Boolean);
                        set({
                            heatmapColumns: columns,
                            heatmapStudents: data.heatmapStudents.map((student) => ({
                                ...student,
                                scores: columns.map((_, i) => student.scores[i] ?? 1),
                            })),
                        });
                    }}
                />
            </div>
            <div className={formRow}>
                <CardEditGroup
                    label="Heatmap students"
                    layout="vertical"
                    onAdd={() => set({
                        heatmapStudents: [...data.heatmapStudents, emptyStudent(data.heatmapColumns.length)],
                    })}
                    addLabel="Add student"
                    isEmpty={data.heatmapStudents.length === 0}
                >
                    {data.heatmapStudents.map((student, index) => (
                        <CardEditPanel
                            key={`student-${index}`}
                            index={index}
                            total={data.heatmapStudents.length}
                            layout="vertical"
                            positionLabel={`Student ${index + 1}`}
                            label={student.name || `Student ${index + 1}`}
                            preview={{ title: student.name, subtitle: student.scores.join(" · ") }}
                            onMoveUp={index > 0 ? () => set({ heatmapStudents: moveItem(data.heatmapStudents, index, -1) }) : undefined}
                            onMoveDown={index < data.heatmapStudents.length - 1 ? () => set({ heatmapStudents: moveItem(data.heatmapStudents, index, 1) }) : undefined}
                            onInsertAfter={() => set({
                                heatmapStudents: [
                                    ...data.heatmapStudents.slice(0, index + 1),
                                    emptyStudent(data.heatmapColumns.length),
                                    ...data.heatmapStudents.slice(index + 1),
                                ],
                            })}
                            onRemove={data.heatmapStudents.length > 1
                                ? () => set({ heatmapStudents: data.heatmapStudents.filter((_, i) => i !== index) })
                                : undefined}
                        >
                            <div className="mb-3">
                                <label className={labelCls}>Name</label>
                                <Input
                                    value={student.name}
                                    onChange={(e) => set({
                                        heatmapStudents: data.heatmapStudents.map((item, i) => (
                                            i === index ? { ...item, name: e.target.value } : item
                                        )),
                                    })}
                                />
                            </div>
                            <div>
                                <label className={labelCls}>Scores (1–4, comma-separated)</label>
                                <Input
                                    value={student.scores.join(", ")}
                                    onChange={(e) => {
                                        const scores = e.target.value
                                            .split(",")
                                            .map((part) => Number(part.trim()) || 1)
                                            .slice(0, data.heatmapColumns.length);
                                        while (scores.length < data.heatmapColumns.length) scores.push(1);
                                        set({
                                            heatmapStudents: data.heatmapStudents.map((item, i) => (
                                                i === index ? { ...item, scores } : item
                                            )),
                                        });
                                    }}
                                />
                            </div>
                        </CardEditPanel>
                    ))}
                </CardEditGroup>
            </div>
            <div className={formRow}>
                <label className={labelCls}>Continuum note (HTML allowed)</label>
                <textarea
                    value={data.continuumHtml}
                    onChange={(e) => set({ continuumHtml: e.target.value })}
                    rows={3}
                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                />
            </div>

            <p className={sectionCls}>Reporting Timeline</p>
            <div className={formRow}>
                <label className={labelCls}>Title</label>
                <Input value={data.timelineTitle} onChange={(e) => set({ timelineTitle: e.target.value })} />
            </div>
            <div className={formRow}>
                <label className={labelCls}>Subtitle</label>
                <Input value={data.timelineSubtitle} onChange={(e) => set({ timelineSubtitle: e.target.value })} />
            </div>
            <div className={formRow}>
                <CardEditGroup
                    label="Timeline items"
                    layout="vertical"
                    onAdd={() => set({ timeline: [...data.timeline, emptyTimeline()] })}
                    addLabel="Add quarter"
                    isEmpty={data.timeline.length === 0}
                >
                    {data.timeline.map((item, index) => (
                        <CardEditPanel
                            key={`timeline-${index}`}
                            index={index}
                            total={data.timeline.length}
                            layout="vertical"
                            positionLabel={`Item ${index + 1}`}
                            label={item.label || item.quarter || `Item ${index + 1}`}
                            preview={{ title: `${item.quarter} · ${item.label}`, subtitle: item.month }}
                            onMoveUp={index > 0 ? () => set({ timeline: moveItem(data.timeline, index, -1) }) : undefined}
                            onMoveDown={index < data.timeline.length - 1 ? () => set({ timeline: moveItem(data.timeline, index, 1) }) : undefined}
                            onInsertAfter={() => set({
                                timeline: [...data.timeline.slice(0, index + 1), emptyTimeline(), ...data.timeline.slice(index + 1)],
                            })}
                            onRemove={data.timeline.length > 1
                                ? () => set({ timeline: data.timeline.filter((_, i) => i !== index) })
                                : undefined}
                        >
                            <div className="grid grid-cols-2 gap-3 mb-3">
                                <div>
                                    <label className={labelCls}>Quarter</label>
                                    <Input
                                        value={item.quarter}
                                        onChange={(e) => set({
                                            timeline: data.timeline.map((row, i) => (i === index ? { ...row, quarter: e.target.value } : row)),
                                        })}
                                    />
                                </div>
                                <div>
                                    <label className={labelCls}>Month</label>
                                    <Input
                                        value={item.month}
                                        onChange={(e) => set({
                                            timeline: data.timeline.map((row, i) => (i === index ? { ...row, month: e.target.value } : row)),
                                        })}
                                    />
                                </div>
                            </div>
                            <div className="mb-3">
                                <label className={labelCls}>Label</label>
                                <Input
                                    value={item.label}
                                    onChange={(e) => set({
                                        timeline: data.timeline.map((row, i) => (i === index ? { ...row, label: e.target.value } : row)),
                                    })}
                                />
                            </div>
                            <div>
                                <label className={labelCls}>Description</label>
                                <textarea
                                    value={item.description}
                                    onChange={(e) => set({
                                        timeline: data.timeline.map((row, i) => (i === index ? { ...row, description: e.target.value } : row)),
                                    })}
                                    rows={2}
                                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                                />
                            </div>
                        </CardEditPanel>
                    ))}
                </CardEditGroup>
            </div>

            <p className={sectionCls}>How to Read</p>
            <div className="grid grid-cols-[auto_1fr] gap-3 mb-4">
                <div>
                    <label className={labelCls}>Emoji</label>
                    <EmojiPickerField compact value={data.readEmoji} onChange={(value) => set({ readEmoji: value })} />
                </div>
                <div>
                    <label className={labelCls}>Title</label>
                    <Input value={data.readTitle} onChange={(e) => set({ readTitle: e.target.value })} />
                </div>
            </div>
            <div className={formRow}>
                <CardEditGroup
                    label="Reading tips"
                    layout="vertical"
                    onAdd={() => set({ readTips: [...data.readTips, emptyTip()] })}
                    addLabel="Add tip"
                    isEmpty={data.readTips.length === 0}
                >
                    {data.readTips.map((tip, index) => (
                        <CardEditPanel
                            key={`tip-${index}`}
                            index={index}
                            total={data.readTips.length}
                            layout="vertical"
                            positionLabel={`Tip ${index + 1}`}
                            label={tip.lead || `Tip ${index + 1}`}
                            preview={{ title: tip.lead, subtitle: tip.text }}
                            onMoveUp={index > 0 ? () => set({ readTips: moveItem(data.readTips, index, -1) }) : undefined}
                            onMoveDown={index < data.readTips.length - 1 ? () => set({ readTips: moveItem(data.readTips, index, 1) }) : undefined}
                            onInsertAfter={() => set({
                                readTips: [...data.readTips.slice(0, index + 1), emptyTip(), ...data.readTips.slice(index + 1)],
                            })}
                            onRemove={data.readTips.length > 1
                                ? () => set({ readTips: data.readTips.filter((_, i) => i !== index) })
                                : undefined}
                        >
                            <div className="mb-3">
                                <label className={labelCls}>Lead (bold)</label>
                                <Input
                                    value={tip.lead}
                                    onChange={(e) => set({
                                        readTips: data.readTips.map((item, i) => (i === index ? { ...item, lead: e.target.value } : item)),
                                    })}
                                />
                            </div>
                            <div>
                                <label className={labelCls}>Text</label>
                                <textarea
                                    value={tip.text}
                                    onChange={(e) => set({
                                        readTips: data.readTips.map((item, i) => (i === index ? { ...item, text: e.target.value } : item)),
                                    })}
                                    rows={2}
                                    className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                                />
                            </div>
                        </CardEditPanel>
                    ))}
                </CardEditGroup>
            </div>
        </>
    );
}
