"use client";

/* eslint-disable @next/next/no-img-element */

import { MediaKind } from "@prisma/client";
import { ImageIcon, Search, Type } from "lucide-react";
import { useState } from "react";

import { MediaFieldPicker, type MediaFieldState } from "@/components/root/media-field-picker";
import { AppCard } from "@/components/ui/app-card";
import { CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  PAGE_TITLE_TOKEN,
  SITE_NAME_TOKEN,
  type SiteSettings,
  type SiteSettingsMediaBindings,
} from "@/lib/site-settings";
import type { AppLocale } from "@/lib/locale";
import type { MediaOption } from "@/lib/media";

type SiteSettingsFormProps = {
  action: (formData: FormData) => Promise<void>;
  initialSettings: SiteSettings;
  initialBindings: SiteSettingsMediaBindings;
  mediaOptions: MediaOption[];
};

const localeFields: Array<{
  key: AppLocale;
  label: string;
  suffix: "Ar" | "En" | "De";
  sampleTitle: string;
}> = [
  {
    key: "ar",
    label: "Arabic",
    suffix: "Ar",
    sampleTitle: "Home",
  },
  {
    key: "en",
    label: "English",
    suffix: "En",
    sampleTitle: "About",
  },
  {
    key: "de",
    label: "Deutsch",
    suffix: "De",
    sampleTitle: "Portfolio",
  },
];

function createImageFieldState(
  assetId: string | null | undefined,
  url: string | null | undefined,
  label: string,
): MediaFieldState {
  if (assetId) {
    return {
      mode: "library",
      assetId,
      url: "",
      label,
      kind: MediaKind.IMAGE,
    };
  }

  if (url) {
    return {
      mode: "external",
      assetId: "",
      url,
      label,
      kind: MediaKind.IMAGE,
    };
  }

  return {
    mode: "upload",
    assetId: "",
    url: "",
    label,
    kind: MediaKind.IMAGE,
  };
}

function getMediaPreviewUrl(
  value: MediaFieldState,
  options: MediaOption[],
  fallbackUrl: string | null | undefined,
) {
  if (value.mode === "external") {
    return value.url || fallbackUrl || "";
  }

  if (value.mode === "library") {
    return options.find((option) => option.id === value.assetId)?.url ?? fallbackUrl ?? "";
  }

  return fallbackUrl ?? "";
}

export function SiteSettingsForm({
  action,
  initialSettings,
  initialBindings,
  mediaOptions,
}: SiteSettingsFormProps) {
  const [settings, setSettings] = useState(initialSettings);
  const [favicon, setFavicon] = useState<MediaFieldState>(
    createImageFieldState(
      initialBindings.favicon?.assetId,
      initialBindings.favicon?.url,
      "Favicon",
    ),
  );
  const [defaultOgImage, setDefaultOgImage] = useState<MediaFieldState>(
    createImageFieldState(
      initialBindings.defaultOgImage?.assetId,
      initialBindings.defaultOgImage?.url,
      "Default OG Image",
    ),
  );
  const faviconPreviewUrl = getMediaPreviewUrl(favicon, mediaOptions, initialBindings.favicon?.url);
  const defaultOgImagePreviewUrl = getMediaPreviewUrl(
    defaultOgImage,
    mediaOptions,
    initialBindings.defaultOgImage?.url,
  );

  return (
    <form id="site-settings-form" action={action} className="space-y-6">
      <div className="grid gap-6 xl:grid-cols-[minmax(0,3fr)_minmax(320px,1fr)]">
        <div className="space-y-6">
          <AppCard>
            <CardHeader>
              <CardTitle>SEO Basics</CardTitle>
              <CardDescription>
                Diese Einstellungen bilden die globale Basis fuer Seitentitel, Description und Vorschau in Suchmaschinen.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-2">
              <p className="text-sm text-muted-foreground">
                Nutze
                {" "}
                <code>{PAGE_TITLE_TOKEN}</code>
                {" "}
                fuer den aktuellen Seitentitel.
                und
                {" "}
                <code>{SITE_NAME_TOKEN}</code>
                {" "}
                fuer den Namen der aktuellen Sprache.
              </p>
              <p className="text-sm text-muted-foreground">
                Beispiel:
                {" "}
                <code>{PAGE_TITLE_TOKEN} | {SITE_NAME_TOKEN}</code>
              </p>
            </CardContent>
          </AppCard>

          <AppCard>
            <CardHeader>
              <CardTitle>Localized Titles And Copy</CardTitle>
              <CardDescription>
                Diese Werte gelten als globale Standards pro Sprache und werden verwendet, wenn eine Seite keinen eigenen Fallback hat.
              </CardDescription>
            </CardHeader>
            <CardContent className="grid gap-4 lg:grid-cols-3">
              {localeFields.map((locale) => (
                <div key={locale.key} className="space-y-4 rounded-surface border border-border bg-surface-1 p-4">
                  <div>
                    <p className="text-sm font-medium text-foreground">{locale.label}</p>
                    <p className="mt-1 text-xs text-muted-foreground">Globale Standardwerte fuer diese Sprache.</p>
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor={`siteName${locale.suffix}`}>Site Name</Label>
                    <Input
                      id={`siteName${locale.suffix}`}
                      name={`siteName${locale.suffix}`}
                      value={settings.locales[locale.key].siteName}
                      onChange={(event) =>
                        setSettings((current) => ({
                          ...current,
                          locales: {
                            ...current.locales,
                            [locale.key]: {
                              ...current.locales[locale.key],
                              siteName: event.target.value,
                            },
                          },
                        }))
                      }
                    />
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor={`titleTemplate${locale.suffix}`}>Title Template</Label>
                    <Input
                      id={`titleTemplate${locale.suffix}`}
                      name={`titleTemplate${locale.suffix}`}
                      value={settings.locales[locale.key].titleTemplate}
                      onChange={(event) =>
                        setSettings((current) => ({
                          ...current,
                          locales: {
                            ...current.locales,
                            [locale.key]: {
                              ...current.locales[locale.key],
                              titleTemplate: event.target.value,
                            },
                          },
                        }))
                      }
                      placeholder="{pageTitle} | {siteName}"
                    />
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor={`siteDescription${locale.suffix}`}>Site Description</Label>
                    <Input
                      id={`siteDescription${locale.suffix}`}
                      name={`siteDescription${locale.suffix}`}
                      value={settings.locales[locale.key].siteDescription}
                      onChange={(event) =>
                        setSettings((current) => ({
                          ...current,
                          locales: {
                            ...current.locales,
                            [locale.key]: {
                              ...current.locales[locale.key],
                              siteDescription: event.target.value,
                            },
                          },
                        }))
                      }
                    />
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor={`subhead${locale.suffix}`}>Subhead</Label>
                    <Input
                      id={`subhead${locale.suffix}`}
                      name={`subhead${locale.suffix}`}
                      value={settings.locales[locale.key].subhead}
                      onChange={(event) =>
                        setSettings((current) => ({
                          ...current,
                          locales: {
                            ...current.locales,
                            [locale.key]: {
                              ...current.locales[locale.key],
                              subhead: event.target.value,
                            },
                          },
                        }))
                      }
                    />
                  </div>
                </div>
              ))}
            </CardContent>
          </AppCard>

          <AppCard>
            <CardHeader>
              <CardTitle>Preview Images</CardTitle>
              <CardDescription>
                Favicon erscheint im Browser. Das Default OG Bild wird fuer Social Sharing genutzt, wenn eine Seite kein eigenes Bild liefert.
              </CardDescription>
            </CardHeader>
            <CardContent className="grid gap-6 xl:grid-cols-2">
              <MediaFieldPicker
                title="Favicon"
                value={favicon}
                onChange={setFavicon}
                options={mediaOptions}
                inputName="faviconMedia"
                fileFieldName="faviconFile"
                fileLabel="Upload Favicon"
                externalLabel="Favicon URL"
                libraryLabel="Favicon Library"
                accept=".png,.svg,.ico,image/png,image/svg+xml,image/x-icon,image/vnd.microsoft.icon"
              />

              <MediaFieldPicker
                title="Default OG Image"
                value={defaultOgImage}
                onChange={setDefaultOgImage}
                options={mediaOptions}
                inputName="defaultOgImageMedia"
                fileFieldName="defaultOgImageFile"
                fileLabel="Upload OG Image"
                externalLabel="OG Image URL"
                libraryLabel="OG Image Library"
                accept="image/*,.svg"
              />
            </CardContent>
          </AppCard>
        </div>

        <div className="xl:sticky xl:top-6 xl:self-start">
          <AppCard>
            <CardHeader>
              <CardTitle>Preview</CardTitle>
              <CardDescription>Suchmaschine und Social Sharing Vorschau.</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="space-y-4 text-sm">
                {localeFields.map((locale) => {
                  const localeSettings = settings.locales[locale.key];
                  const previewTitle = localeSettings.titleTemplate.includes(PAGE_TITLE_TOKEN)
                    ? localeSettings.titleTemplate
                        .replace(PAGE_TITLE_TOKEN, locale.sampleTitle)
                        .replaceAll(SITE_NAME_TOKEN, localeSettings.siteName)
                    : `${locale.sampleTitle} | ${localeSettings.siteName}`;

                  return (
                    <div key={locale.key} className="rounded-nested border border-border bg-background p-3">
                      <p className="font-medium text-foreground">{locale.label}</p>
                      <p className="mt-2 text-xs text-muted-foreground">
                        Example page title: {locale.sampleTitle}
                      </p>
                      <p className="mt-2 text-sm text-foreground">{previewTitle}</p>
                      <p className="mt-1 text-sm text-muted-foreground">
                        {localeSettings.siteDescription || "No description"}
                      </p>
                      <p className="mt-2 text-xs text-muted-foreground">
                        {localeSettings.subhead || "No subhead"}
                      </p>
                    </div>
                  );
                })}
              </div>

              <div className="flex items-center gap-2 text-sm font-medium text-foreground">
                <Search className="h-4 w-4 text-brand-primary" />
                Search Preview
              </div>
              <div className="rounded-nested border border-border bg-background p-4">
                <div className="flex items-center gap-3">
                  {faviconPreviewUrl ? (
                    <img src={faviconPreviewUrl} alt="Favicon" className="h-5 w-5 rounded-sm" />
                  ) : (
                    <div className="flex h-5 w-5 items-center justify-center rounded-sm border border-border bg-surface-1">
                      <Type className="h-3.5 w-3.5 text-muted-foreground" />
                    </div>
                  )}
                  <p className="text-sm font-medium text-brand-primary">
                    {settings.locales.de.titleTemplate.includes(PAGE_TITLE_TOKEN)
                      ? settings.locales.de.titleTemplate
                          .replace(PAGE_TITLE_TOKEN, "About")
                          .replaceAll(SITE_NAME_TOKEN, settings.locales.de.siteName)
                      : `About | ${settings.locales.de.siteName}`}
                  </p>
                </div>
                <p className="mt-2 text-xs text-muted-foreground">
                  {settings.locales.de.siteDescription || "No description"}
                </p>
                <p className="mt-2 text-xs text-muted-foreground/80">
                  {settings.locales.de.subhead || "No subhead"}
                </p>
              </div>

              <div className="flex items-center gap-2 text-sm font-medium text-foreground">
                <ImageIcon className="h-4 w-4 text-brand-secondary" />
                Social Preview
              </div>
              <div className="overflow-hidden rounded-nested border border-border bg-background">
                {defaultOgImagePreviewUrl ? (
                  <img src={defaultOgImagePreviewUrl} alt="Default OG" className="h-32 w-full object-cover" />
                ) : (
                  <div className="flex h-32 items-center justify-center bg-surface-1 text-sm text-muted-foreground">
                    No OG image selected
                  </div>
                )}
                <div className="space-y-2 p-4">
                  <p className="text-sm font-medium text-foreground">
                    {settings.locales.en.titleTemplate.includes(PAGE_TITLE_TOKEN)
                      ? settings.locales.en.titleTemplate
                          .replace(PAGE_TITLE_TOKEN, "Portfolio")
                          .replaceAll(SITE_NAME_TOKEN, settings.locales.en.siteName)
                      : `Portfolio | ${settings.locales.en.siteName}`}
                  </p>
                  <p className="text-xs text-muted-foreground">
                    {settings.locales.en.siteDescription || "No description"}
                  </p>
                </div>
              </div>
            </CardContent>
          </AppCard>
        </div>
      </div>
    </form>
  );
}
