import { Head, router, usePage } from '@inertiajs/react';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import { useMemo, useEffect, useCallback } from 'react';
import { useFormContext } from 'react-hook-form';
import { Form } from '@admin/components/form';
import { FontSelector } from '@admin/components/font-selector';
import { HexColorPicker } from '@admin/components/hex-color-picker';
import { Card, CardContent } from '@admin/components/ui/card';
import { Button } from '@admin/components/ui/button';
import { toast } from 'sonner';
import AppLayout from '@admin/layouts/app-layout';
import SettingsLayout from '@admin/layouts/settings/layout';
import HeadingSmall from '@admin/components/heading-small';
import { Activity } from 'lucide-react';
import { ActivityLogSidebar } from '@admin/components/activity-log/ActivityLogSidebar';
import { useModelActivityLog } from '@admin/components/activity-log/useModelActivityLog';
import { useColors } from '@admin/hooks/use-colors';
import { useFont, FontFamily } from '@admin/hooks/use-font';
import { removeCssVar, setSidebarColors } from '@admin/lib/theme';
import { BreadcrumbItem } from '@admin/types';

export default function Edit() {
  const { props } = usePage<any>();
  const { fontFamily, updateFont } = useFont();
  const { colorTheme, isLoaded, updateColors } = useColors();
  const activityLogCtl = useModelActivityLog();

  const breadcrumbs: BreadcrumbItem[] = [{ title: 'Theme settings', href: route('settings.theme.edit') }];

  const fontOptions = [
    { value: 'Inter', label: 'Inter' },
    { value: 'Roboto', label: 'Roboto' },
    { value: 'Open Sans', label: 'Open Sans' },
    { value: 'Helvetica', label: 'Helvetica' },
    { value: 'Arial', label: 'Arial' },
    { value: 'Times New Roman', label: 'Times New Roman' },
    { value: 'Georgia', label: 'Georgia' },
    { value: 'Courier New', label: 'Courier New' },
  ];

  const hexValidator = (value?: string) =>
    !value || /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value);

  const schema = yup.object({
    font: yup.string().nullable(),
    primary_color: yup.string().nullable().test('is-valid-hex', 'Invalid hex', hexValidator),
    secondary_color: yup.string().nullable().test('is-valid-hex', 'Invalid hex', hexValidator),
  });

  // Default values should come from server-provided data only.
  // Avoid using local theme state here so user edits aren't clobbered
  // when `colorTheme` / `fontFamily` update during live preview.
  const defaultValues = useMemo(() => ({
    font: props?.themeData?.font ?? '',
    primary_color: props?.themeData?.primary_color ?? '',
    secondary_color: props?.themeData?.secondary_color ?? '',
  }), [props?.themeData]);

  // Apply server-saved values immediately to the UI (font and colors) when themeData changes
  useEffect(() => {
    if (!props?.themeData) return;
    if (props.themeData && typeof props.themeData.font === 'string' && props.themeData.font) {
      updateFont(props.themeData.font as FontFamily);
    }

    const serverPrimary = props.themeData.primary_color ?? '';
    const serverSecondary = props.themeData.secondary_color ?? '';
    if (serverPrimary || serverSecondary) {
      updateColors({
        primary: serverPrimary || colorTheme?.primary || '#000000',
        secondary: serverSecondary || colorTheme?.secondary || '',
      });
    }
  }, [props.themeData, updateFont, updateColors]);

  // Font Watcher Component - watches form changes and applies font immediately
  const FontWatcher = () => {
    const { watch } = useFormContext();
    const selectedFont = watch('font');
    useEffect(() => {
      if (selectedFont && selectedFont !== fontFamily) {
        updateFont(selectedFont as FontFamily);
      }
    }, [selectedFont, updateFont, fontFamily]);
    return null;
  };

  // Color Watcher Component - watches form changes and applies colors immediately
  const ColorWatcher = () => {
    const { watch } = useFormContext();
    const primary = watch('primary_color');
    const secondary = watch('secondary_color');
    useEffect(() => {
      if (!isLoaded) return;
      if (primary && /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(primary) && primary !== colorTheme?.primary) {
        updateColors({ primary, secondary: colorTheme?.secondary || '' });
      }
    }, [primary, updateColors, colorTheme?.primary, isLoaded]);
    useEffect(() => {
      if (!isLoaded) return;
      if (secondary && /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(secondary) && secondary !== colorTheme?.secondary) {
        updateColors({ primary: colorTheme?.primary || '', secondary });
      }
    }, [secondary, updateColors, colorTheme?.secondary, isLoaded]);
    return null;
  };

  // Note: per-form watchers are handled by FontWatcher and ColorWatcher (above)

  const handleSubmit = (data: any) => {
    if (data.font) updateFont(data.font as FontFamily);

    updateColors({
      primary: data.primary_color || colorTheme?.primary || '#000000',
      secondary: data.secondary_color || colorTheme?.secondary || '',
    });

    router.post(route('settings.theme.update'), data, {
      preserveScroll: true,
      onSuccess: (page: any) => {
        const success = page.props?.flash?.success;
        if (success) toast.success(success);
      },
      onError: () => toast.error('Failed to save theme settings'),
    });
  };

  const handleResetEverything = useCallback(() => {
    localStorage.removeItem('font-family');
    localStorage.removeItem('color-theme');

    removeCssVar('--font-sans');
    removeCssVar('--color-primary');
    removeCssVar('--primary');
    removeCssVar('--color-brand');
    removeCssVar('--brand');
    removeCssVar('--color-secondary');
    removeCssVar('--secondary');
    removeCssVar('--color-brand-secondary');
    removeCssVar('--brand-secondary');
    document.documentElement.style.fontFamily = '';
    setSidebarColors('#12162d', '#FFFFFF');

    globalThis.location.reload();
  }, []);

  return (
    <AppLayout breadcrumbs={breadcrumbs}>
      <Head title="Theme settings" />
      <SettingsLayout tab="platform">
        <div className="space-y-6">
          <Card className="rounded-lg border px-5 py-3">
            <div className="mb-3 flex items-center justify-between border-b">
              <HeadingSmall
                title="Appearance"
                description="Customize the appearance of the app. Automatically switch between day and night themes."
              />
              <Button
                variant="outline"
                size="sm"
                onClick={() =>
                  activityLogCtl.show({
                    modelClass: 'Setting',
                    title: 'Appearance Activity',
                    action: 'theme_settings_updated',
                  })
                }
              >
                <Activity className="mr-1 h-4 w-4" /> Activity
              </Button>
            </div>
            <CardContent className="w-xl px-0">
              {isLoaded ? (
                <Form submitHandler={handleSubmit} formClassNames="space-y-4" resolver={yupResolver(schema)} defaultValues={defaultValues}>
                  {/* Font Watcher for live preview */}
                  <FontWatcher />

                  {/* Color Watcher for live preview */}
                  <ColorWatcher />

                  <div className="space-y-4">
                    <div>
                      <label htmlFor="theme-font" className="text-sm font-medium dark:text-gray-300">Font</label>
                      <p className="text-sm text-gray-500 dark:text-gray-400">
                        Set the font you want to use in the dashboard.
                      </p>
                      <FontSelector id="theme-font" name="font" placeholder="Select font" options={fontOptions} />
                    </div>

                    <div>
                      <HexColorPicker name="primary_color" label="Primary Color" placeholder="#14b8a6" />
                      <p className="text-sm text-gray-500 dark:text-gray-400">Set the primary brand color.</p>
                    </div>

                    <div>
                      <HexColorPicker name="secondary_color" label="Secondary Color" placeholder="#f5791f" />
                      <p className="text-sm text-gray-500 dark:text-gray-400">Set the secondary accent color.</p>
                    </div>

                    <div className="flex gap-3 pt-6">
                      <Button type="submit" className="bg-success px-8 py-2 text-white hover:bg-brand-800">
                        Save Changes
                      </Button>
                      <Button type="button" variant="outline" className="px-8 py-2" onClick={handleResetEverything}>
                        Reset All
                      </Button>
                    </div>
                  </div>
                </Form>
              ) : (
                <div className="flex items-center justify-center py-8 text-sm text-muted-foreground">
                  Loading theme settings...
                </div>
              )}
            </CardContent>
          </Card>
        </div>
      </SettingsLayout>

      <ActivityLogSidebar
        open={activityLogCtl.open}
        onOpenChange={activityLogCtl.setOpen}
        modelClass={activityLogCtl.modelClass}
        modelId={activityLogCtl.modelId}
        title={activityLogCtl.title}
        action={activityLogCtl.action}
      />
    </AppLayout>
  );
}
