"use client";

import { useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import type { FortuneType } from "@prisma/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  getPersianDaysInMonth,
  persianDateTimeToISO,
  PERSIAN_MONTH_NAMES,
} from "@/lib/persian-date";
import { fortuneSlugFromPeriod } from "@/lib/fortunes";

const SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;

function buildAutoSlug(
  type: FortuneType,
  year: number,
  month: number,
  day: number
): string {
  return fortuneSlugFromPeriod(type, year, month, type === "DAILY" ? day : undefined);
}

type FortuneInitial = {
  type: FortuneType;
  titleFa: string;
  slug: string;
  excerptFa: string;
  content: string;
  coverImageUrl: string | null;
  status: string;
  publishYear?: number | null;
  publishMonth?: number | null;
  publishDay?: number | null;
  publishHour?: number | null;
  publishMinute?: number | null;
  persianYear: number;
  persianMonth: number;
  persianDay: number;
};

export function FortuneForm({
  fortuneId,
  fortuneType,
  initial,
}: {
  fortuneId?: string;
  fortuneType?: FortuneType;
  initial?: FortuneInitial;
}) {
  const router = useRouter();
  const type = initial?.type ?? fortuneType ?? "DAILY";
  const initialYear = initial?.persianYear ?? 1404;
  const initialMonth = initial?.persianMonth ?? 1;
  const initialDay = initial?.persianDay ?? 1;
  const [titleFa, setTitleFa] = useState(initial?.titleFa ?? "");
  const hasValidSlug = !!initial?.slug && SLUG_PATTERN.test(initial.slug);
  const [slugTouched, setSlugTouched] = useState(hasValidSlug);
  const [slug, setSlug] = useState(
    hasValidSlug ? initial!.slug : buildAutoSlug(type, initialYear, initialMonth, initialDay)
  );
  const [excerptFa, setExcerptFa] = useState(initial?.excerptFa ?? "");
  const [content, setContent] = useState(initial?.content ?? "");
  const [coverImageUrl, setCoverImageUrl] = useState(initial?.coverImageUrl ?? "");
  const [status, setStatus] = useState(initial?.status ?? "DRAFT");
  const [hasPublishDate, setHasPublishDate] = useState(initial?.publishYear != null);
  const [publishYear, setPublishYear] = useState(
    initial?.publishYear != null ? String(initial.publishYear) : ""
  );
  const [publishMonth, setPublishMonth] = useState(
    initial?.publishMonth != null ? String(initial.publishMonth) : "1"
  );
  const [publishDay, setPublishDay] = useState(
    initial?.publishDay != null ? String(initial.publishDay) : "1"
  );
  const [publishHour, setPublishHour] = useState(
    initial?.publishHour != null ? String(initial.publishHour) : "12"
  );
  const [publishMinute, setPublishMinute] = useState(
    initial?.publishMinute != null ? String(initial.publishMinute) : "0"
  );
  const [persianYear, setPersianYear] = useState(String(initial?.persianYear ?? ""));
  const [persianMonth, setPersianMonth] = useState(String(initial?.persianMonth ?? "1"));
  const [persianDay, setPersianDay] = useState(String(initial?.persianDay ?? "1"));
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [coverUploading, setCoverUploading] = useState(false);

  const yearNum = Number(persianYear) || 1404;
  const monthNum = Number(persianMonth) || 1;
  const maxDay = useMemo(
    () => getPersianDaysInMonth(yearNum, monthNum),
    [yearNum, monthNum]
  );
  const dayOptions = useMemo(
    () => Array.from({ length: maxDay }, (_, i) => i + 1),
    [maxDay]
  );

  const publishYearNum = Number(publishYear) || 1404;
  const publishMonthNum = Number(publishMonth) || 1;
  const publishMaxDay = useMemo(
    () => getPersianDaysInMonth(publishYearNum, publishMonthNum),
    [publishYearNum, publishMonthNum]
  );
  const publishDayOptions = useMemo(
    () => Array.from({ length: publishMaxDay }, (_, i) => i + 1),
    [publishMaxDay]
  );

  function handlePublishYearChange(value: string) {
    setPublishYear(value);
    const y = Number(value) || 1404;
    const m = Number(publishMonth) || 1;
    const max = getPersianDaysInMonth(y, m);
    if (Number(publishDay) > max) setPublishDay(String(max));
  }

  function handlePublishMonthChange(value: string) {
    setPublishMonth(value);
    const y = Number(publishYear) || 1404;
    const m = Number(value) || 1;
    const max = getPersianDaysInMonth(y, m);
    if (Number(publishDay) > max) setPublishDay(String(max));
  }

  function syncAutoSlug(y: number, m: number, d: number) {
    if (slugTouched || fortuneId) return;
    setSlug(buildAutoSlug(type, y, m, d));
  }

  function handleYearChange(value: string) {
    setPersianYear(value);
    const y = Number(value) || 1404;
    const m = Number(persianMonth) || 1;
    const d = Number(persianDay) || 1;
    const max = getPersianDaysInMonth(y, m);
    const nextDay = d > max ? max : d;
    if (d > max) setPersianDay(String(max));
    syncAutoSlug(y, m, nextDay);
  }

  function handleMonthChange(value: string) {
    setPersianMonth(value);
    const y = Number(persianYear) || 1404;
    const m = Number(value) || 1;
    const d = Number(persianDay) || 1;
    const max = getPersianDaysInMonth(y, m);
    const nextDay = d > max ? max : d;
    if (d > max) setPersianDay(String(max));
    syncAutoSlug(y, m, nextDay);
  }

  function handleDayChange(value: string) {
    setPersianDay(value);
    syncAutoSlug(Number(persianYear) || 1404, Number(persianMonth) || 1, Number(value) || 1);
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setLoading(true);
    const publishedAtIso = hasPublishDate
      ? persianDateTimeToISO(
          Number(publishYear),
          Number(publishMonth),
          Number(publishDay),
          Number(publishHour),
          Number(publishMinute)
        )
      : null;
    if (hasPublishDate && !publishedAtIso) {
      setError("تاریخ انتشار شمسی معتبر نیست.");
      setLoading(false);
      return;
    }
    const body = {
      type,
      titleFa,
      slug: slug.trim(),
      excerptFa,
      content,
      coverImageUrl: coverImageUrl || undefined,
      status,
      publishedAt: hasPublishDate ? publishedAtIso : null,
      persianYear: Number(persianYear),
      persianMonth: Number(persianMonth),
      persianDay: type === "DAILY" ? Number(persianDay) : undefined,
    };
    const url = fortuneId ? `/api/admin/fortunes/${fortuneId}` : "/api/admin/fortunes";
    const res = await fetch(url, {
      method: fortuneId ? "PATCH" : "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    const data = await res.json().catch(() => ({}));
    setLoading(false);
    if (res.ok) {
      router.push("/admin/fortunes");
    } else {
      setError((data.error as string) || "خطا در ذخیره");
      router.refresh();
    }
  }

  async function handleCoverFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const f = e.target.files?.[0];
    if (!f) return;
    if (!f.type.startsWith("image/")) {
      setError("لطفاً یک فایل تصویری (JPG، PNG، GIF یا WebP) انتخاب کنید.");
      return;
    }
    setError(null);
    setCoverUploading(true);
    try {
      const form = new FormData();
      form.set("file", f);
      const res = await fetch("/api/admin/upload", { method: "POST", body: form });
      const data = await res.json().catch(() => ({}));
      if (res.ok && data.url) {
        setCoverImageUrl(data.url);
      } else {
        setError((data.error as string) || "خطا در آپلود تصویر");
      }
    } catch {
      setError("خطا در آپلود تصویر");
    } finally {
      setCoverUploading(false);
      e.target.value = "";
    }
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      {error && (
        <p className="text-sm text-destructive bg-destructive/10 p-3 rounded-md" role="alert">
          {error}
        </p>
      )}
      <div>
        <Label>نوع فال</Label>
        <p className="text-sm mt-1 font-medium">
          {type === "DAILY" ? "فال روزانه" : "فال ماهانه"}
        </p>
      </div>
      <div>
        <Label>عنوان (فارسی)</Label>
        <Input value={titleFa} onChange={(e) => setTitleFa(e.target.value)} className="mt-1" />
      </div>
      <div>
        <Label>اسلاگ (آدرس صفحه)</Label>
        <Input
          value={slug}
          onChange={(e) => {
            setSlugTouched(true);
            setSlug(e.target.value);
          }}
          className="mt-1"
          dir="ltr"
        />
        <p className="text-xs text-muted-foreground mt-1">
          فقط حروف انگلیسی کوچک، عدد و خط تیره — مثلاً monthly-1405-03
        </p>
      </div>
      <div>
        <Label>خلاصه</Label>
        <textarea
          value={excerptFa}
          onChange={(e) => setExcerptFa(e.target.value)}
          className="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1"
        />
      </div>
      <div>
        <Label>محتوا</Label>
        <textarea
          value={content}
          onChange={(e) => setContent(e.target.value)}
          className="flex min-h-[200px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1"
        />
      </div>
      <div>
        <Label>تصویر کاور (اختیاری)</Label>
        <div className="flex flex-wrap gap-2 items-center mt-1">
          <Input
            value={coverImageUrl}
            onChange={(e) => setCoverImageUrl(e.target.value)}
            placeholder="https://..."
            className="max-w-md"
          />
          <label className="cursor-pointer">
            <input
              type="file"
              accept="image/jpeg,image/png,image/webp"
              className="sr-only"
              disabled={coverUploading}
              onChange={handleCoverFileChange}
            />
            <span className="inline-flex items-center justify-center rounded-md text-sm font-medium bg-primary text-primary-foreground h-10 px-4 hover:bg-primary/90 disabled:opacity-50">
              {coverUploading ? "در حال آپلود..." : "انتخاب فایل"}
            </span>
          </label>
          {coverImageUrl && (
            <Button type="button" variant="outline" size="sm" onClick={() => setCoverImageUrl("")}>
              پاک کردن
            </Button>
          )}
        </div>
        {coverImageUrl && (
          <div className="mt-2 relative inline-block">
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src={coverImageUrl}
              alt="پیش‌نمایش کاور"
              className="max-h-32 rounded border object-cover"
            />
          </div>
        )}
      </div>
      {type === "DAILY" ? (
        <div>
          <Label>تاریخ فال (شمسی)</Label>
          <div className="flex flex-wrap gap-4 mt-1">
            <div>
              <Label className="text-xs text-muted-foreground">سال</Label>
              <Input
                type="number"
                value={persianYear}
                onChange={(e) => handleYearChange(e.target.value)}
                className="mt-1 max-w-[140px]"
                required
              />
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">ماه</Label>
              <select
                value={persianMonth}
                onChange={(e) => handleMonthChange(e.target.value)}
                className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1 min-w-[160px]"
              >
                {PERSIAN_MONTH_NAMES.map((name, i) => (
                  <option key={name} value={String(i + 1)}>
                    {name}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">روز</Label>
              <select
                value={persianDay}
                onChange={(e) => handleDayChange(e.target.value)}
                className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1 min-w-[100px]"
              >
                {dayOptions.map((d) => (
                  <option key={d} value={String(d)}>
                    {d}
                  </option>
                ))}
              </select>
            </div>
          </div>
          <p className="text-xs text-muted-foreground mt-1">
            فال روزانه برای همین تاریخ شمسی در صفحه اصلی نمایش داده می‌شود.
          </p>
        </div>
      ) : (
        <div className="flex flex-wrap gap-4">
          <div>
            <Label>سال شمسی</Label>
            <Input
              type="number"
              value={persianYear}
              onChange={(e) => setPersianYear(e.target.value)}
              className="mt-1 max-w-[140px]"
              required
            />
          </div>
          <div>
            <Label>ماه شمسی</Label>
            <select
              value={persianMonth}
              onChange={(e) => setPersianMonth(e.target.value)}
              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1 min-w-[160px]"
            >
              {PERSIAN_MONTH_NAMES.map((name, i) => (
                <option key={name} value={String(i + 1)}>
                  {name}
                </option>
              ))}
            </select>
          </div>
        </div>
      )}
      <div>
        <Label>وضعیت</Label>
        <select
          value={status}
          onChange={(e) => setStatus(e.target.value)}
          className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1 max-w-xs"
        >
          <option value="DRAFT">پیش‌نویس</option>
          <option value="PUBLISHED">منتشر شده</option>
        </select>
      </div>
      <div>
        <label className="flex items-center gap-2 text-sm cursor-pointer">
          <input
            type="checkbox"
            checked={hasPublishDate}
            onChange={(e) => setHasPublishDate(e.target.checked)}
            className="rounded border-input"
          />
          <span>تاریخ انتشار (اختیاری — شمسی)</span>
        </label>
        {hasPublishDate && (
          <div className="flex flex-wrap gap-4 mt-3">
            <div>
              <Label className="text-xs text-muted-foreground">سال</Label>
              <Input
                type="number"
                value={publishYear}
                onChange={(e) => handlePublishYearChange(e.target.value)}
                className="mt-1 max-w-[140px]"
                required
              />
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">ماه</Label>
              <select
                value={publishMonth}
                onChange={(e) => handlePublishMonthChange(e.target.value)}
                className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1 min-w-[160px]"
              >
                {PERSIAN_MONTH_NAMES.map((name, i) => (
                  <option key={name} value={String(i + 1)}>
                    {name}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">روز</Label>
              <select
                value={publishDay}
                onChange={(e) => setPublishDay(e.target.value)}
                className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm mt-1 min-w-[100px]"
              >
                {publishDayOptions.map((d) => (
                  <option key={d} value={String(d)}>
                    {d}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">ساعت</Label>
              <Input
                type="number"
                min={0}
                max={23}
                value={publishHour}
                onChange={(e) => setPublishHour(e.target.value)}
                className="mt-1 max-w-[100px]"
                required
              />
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">دقیقه</Label>
              <Input
                type="number"
                min={0}
                max={59}
                value={publishMinute}
                onChange={(e) => setPublishMinute(e.target.value)}
                className="mt-1 max-w-[100px]"
                required
              />
            </div>
          </div>
        )}
      </div>
      <Button type="submit" disabled={loading}>
        {loading ? "در حال ذخیره..." : fortuneId ? "بروزرسانی" : "ایجاد"}
      </Button>
    </form>
  );
}
