"use client";

import {
  isEnabledSetting,
  normalizeDashboardDateFormat,
  normalizeDashboardTimeFormat,
} from '@/lib/dashboard-settings';
import { useSettings } from '@/hooks/use-settings';
import { usePathname } from '@/i18n/routing';
import { Settings } from '@/types/settings';
import { useTheme } from 'next-themes';
import { createContext, ReactNode, useContext, useEffect, useLayoutEffect } from 'react';

interface SettingsContextValue {
  settings: Settings | null;
  isLoading: boolean;
  showThemeSwitcher: boolean;

  // Computed helpers
  maxFileSize: number;
  maxFilesCount: number;
  allowedExtensions: string[];
  dateFormat: string;
  timeFormat: string;
  timezone: string;
  primaryColor: string;
  secondaryColor: string;
  dashboardLogo: string | null;
  dashboardIcon: string | null;
  dashboardName: string | null;
  browserTitle: string;
}

const SettingsContext = createContext<SettingsContextValue | null>(null);

/**
 * Generate chart color variants from primary and secondary colors
 * This ensures all charts use colors derived from dashboard settings
 * instead of hardcoded values
 */
function generateChartColors(primaryColor: string, secondaryColor: string) {
  // Parse the color to extract HSL or RGB values for manipulation
  // For OKLCH colors from settings, we'll create complementary colors

  // chart-2: Warm accent (orange/amber) - derived from primary with hue shift
  // Use a complementary warm tone
  document.documentElement.style.setProperty(
    '--chart-2',
    adjustColorBrightness(primaryColor, 1.2, 40) // Brighter, hue shifted to warm
  );

  // chart-3: Secondary color or neutral tone
  document.documentElement.style.setProperty(
    '--chart-3',
    secondaryColor
  );

  // chart-4: Cool accent (blue/purple) - derived from primary with hue shift
  document.documentElement.style.setProperty(
    '--chart-4',
    adjustColorBrightness(primaryColor, 1.1, -60) // Slightly brighter, hue shifted to cool
  );

  // chart-5: Light variant of primary (for backgrounds/subtle indicators)
  document.documentElement.style.setProperty(
    '--chart-5',
    adjustColorBrightness(primaryColor, 1.5, 0) // Much lighter version
  );
}

/**
 * Adjust color brightness and hue
 * Works with hex, rgb, rgba, oklch, and hsl colors
 */
function adjustColorBrightness(color: string, brightnessFactor: number, hueShift: number): string {
  // If it's an OKLCH color, manipulate it directly
  if (color.includes('oklch')) {
    const match = color.match(/oklch\(([\d.]+)\s+([\d.]+)\s+([\d.]+)\)/);
    if (match) {
      const lightness = parseFloat(match[1]);
      const chroma = parseFloat(match[2]);
      const hue = parseFloat(match[3]);

      const newLightness = Math.min(1, lightness * brightnessFactor);
      const newHue = (hue + hueShift + 360) % 360;

      return `oklch(${newLightness.toFixed(2)} ${chroma.toFixed(2)} ${newHue.toFixed(0)})`;
    }
  }

  // If it's a hex color, convert to HSL, adjust, and convert back
  if (color.startsWith('#')) {
    const hex = color.replace('#', '');
    const r = parseInt(hex.substring(0, 2), 16) / 255;
    const g = parseInt(hex.substring(2, 4), 16) / 255;
    const b = parseInt(hex.substring(4, 6), 16) / 255;

    const max = Math.max(r, g, b);
    const min = Math.min(r, g, b);
    let h = 0;
    let s = 0;
    let l = (max + min) / 2;

    if (max !== min) {
      const d = max - min;
      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);

      switch (max) {
        case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
        case g: h = ((b - r) / d + 2) / 6; break;
        case b: h = ((r - g) / d + 4) / 6; break;
      }
    }

    // Adjust lightness and hue
    l = Math.min(1, l * brightnessFactor);
    h = (h * 360 + hueShift + 360) % 360;

    return `hsl(${h.toFixed(0)}, ${(s * 100).toFixed(0)}%, ${(l * 100).toFixed(0)}%)`;
  }

  // For other formats, return as-is (already handled by OKLCH above)
  return color;
}

/**
 * Apply primary color to all related CSS variables
 */
function applyPrimaryColor(color: string) {
  const root = document.documentElement;
  root.style.setProperty('--primary', color);
  root.style.setProperty('--accent', color);
  root.style.setProperty('--sidebar-primary', color);
  root.style.setProperty('--sidebar-ring', color);
  root.style.setProperty('--ring', color);
  root.style.setProperty('--chart-1', color);
}

/**
 * Apply secondary color to all related CSS variables
 */
function applySecondaryColor(color: string) {
  const root = document.documentElement;
  root.style.setProperty('--secondary', color);
  root.style.setProperty('--sidebar', color);
  root.style.setProperty('--sidebar-accent', color);
}

function upsertMetaTag(
  selector: string,
  attribute: "name" | "property",
  key: string,
  content?: string | null,
) {
  const trimmedContent = content?.trim();
  const existing = document.head.querySelector(selector) as HTMLMetaElement | null;

  if (!trimmedContent) {
    existing?.remove();
    return;
  }

  const tag = existing || document.createElement("meta");
  tag.setAttribute(attribute, key);
  tag.content = trimmedContent;

  if (!existing) {
    document.head.appendChild(tag);
  }
}

export function SettingsProvider({ children }: { children: ReactNode }) {
  const {
    settings,
    isLoading,
  } = useSettings();
  const { resolvedTheme } = useTheme();
  const pathname = usePathname();
  const showThemeSwitcher = isEnabledSetting(
    settings?.dashboard_dark_mode ?? settings?.dark_mode,
  );

  // Immediately restore cached colors from localStorage on mount (before API responds)
  // This prevents the flash of default colors on page refresh
  useLayoutEffect(() => {
    const isDarkMode = resolvedTheme === 'dark';
    if (isDarkMode) return;

    const cachedPrimary = localStorage.getItem('dashboard_primary_color');
    const cachedSecondary = localStorage.getItem('dashboard_secondary_color');

    if (cachedPrimary) {
      applyPrimaryColor(cachedPrimary);
      if (cachedSecondary) {
        generateChartColors(cachedPrimary, cachedSecondary);
      }
    }
    if (cachedSecondary) {
      applySecondaryColor(cachedSecondary);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []); // Run once on mount

  // Apply dynamic colors as CSS variables (LIGHT MODE ONLY)
  // Dark mode uses its own separate color scheme defined in globals.css
  useLayoutEffect(() => {
    // Only apply backend colors in light mode
    const isDarkMode = resolvedTheme === 'dark';

    if (isDarkMode) {
      // In dark mode, reset to CSS defaults by removing inline styles
      // This allows the .dark class styles from globals.css to take effect
      const root = document.documentElement;
      root.style.removeProperty('--primary');
      root.style.removeProperty('--accent');
      root.style.removeProperty('--sidebar-primary');
      root.style.removeProperty('--sidebar-ring');
      root.style.removeProperty('--ring');
      root.style.removeProperty('--chart-1');
      root.style.removeProperty('--secondary');
      root.style.removeProperty('--sidebar');
      root.style.removeProperty('--sidebar-accent');
      return;
    }

    // Light mode - apply backend colors
    if (settings?.dashboard_primary_color) {
      localStorage.setItem('dashboard_primary_color', settings.dashboard_primary_color);
      applyPrimaryColor(settings.dashboard_primary_color);
      generateChartColors(settings.dashboard_primary_color, settings.dashboard_secondary_color);
    }

    // Cache logo/icon URLs for instant sidebar rendering on next load
    if (settings?.dashboard_logo) {
      localStorage.setItem('dashboard_logo', settings.dashboard_logo);
    } else if (settings && !settings.dashboard_logo) {
      localStorage.removeItem('dashboard_logo');
    }
    if (settings?.dashboard_name) {
      localStorage.setItem('dashboard_name', settings.dashboard_name);
    } else if (settings && !settings.dashboard_name) {
      localStorage.removeItem('dashboard_name');
    }

    if (settings?.dashboard_secondary_color) {
      localStorage.setItem('dashboard_secondary_color', settings.dashboard_secondary_color);
      applySecondaryColor(settings.dashboard_secondary_color);

      if (settings?.dashboard_primary_color) {
        generateChartColors(settings.dashboard_primary_color, settings.dashboard_secondary_color);
      }
    }

    if (settings?.dashboard_timezone) {
      localStorage.setItem('dashboard_timezone', settings.dashboard_timezone);
    } else if (settings) {
      localStorage.removeItem('dashboard_timezone');
    }
  }, [resolvedTheme, settings, settings?.dashboard_primary_color, settings?.dashboard_secondary_color]);

  // Browser title from settings
  const browserTitle = settings?.browser_title || settings?.dashboard_name || 'Dashboard';

  // Update document title when browser_title changes
  useEffect(() => {
    if (browserTitle) {
      document.title = browserTitle;
    }
  }, [browserTitle]);

  useEffect(() => {
    const existingDescription =
      document.querySelector('meta[name="description"]')?.getAttribute("content") || null;
    const existingOgImage =
      document.querySelector('meta[property="og:image"]')?.getAttribute("content") || null;
    const existingTwitterImage =
      document.querySelector('meta[name="twitter:image"]')?.getAttribute("content") || null;

    const pageTitle =
      settings?.browser_title ||
      settings?.dashboard_name ||
      settings?.site_name ||
      document.title ||
      null;
    const pageDescription =
      settings?.site_description ||
      existingDescription ||
      "منصة إدارة الأعمال والتداول - Business Management & Trading Platform";
    const shareImage =
      settings?.dashboard_logo ||
      settings?.site_logo ||
      settings?.dashboard_icon ||
      settings?.site_icon ||
      existingOgImage ||
      existingTwitterImage ||
      null;

    upsertMetaTag('meta[name="description"]', "name", "description", pageDescription);
    upsertMetaTag('meta[property="og:title"]', "property", "og:title", pageTitle);
    upsertMetaTag('meta[property="og:description"]', "property", "og:description", pageDescription);
    upsertMetaTag('meta[property="og:image"]', "property", "og:image", shareImage);
    upsertMetaTag('meta[name="twitter:title"]', "name", "twitter:title", pageTitle);
    upsertMetaTag('meta[name="twitter:description"]', "name", "twitter:description", pageDescription);
    upsertMetaTag('meta[name="twitter:image"]', "name", "twitter:image", shareImage);
    upsertMetaTag(
      'meta[name="twitter:card"]',
      "name",
      "twitter:card",
      shareImage ? "summary_large_image" : "summary",
    );
  }, [
    settings?.browser_title,
    settings?.dashboard_name,
    settings?.site_name,
    settings?.site_description,
    settings?.dashboard_logo,
    settings?.site_logo,
    settings?.dashboard_icon,
    settings?.site_icon,
  ]);

  // Update favicon when dashboard_icon changes or pathname changes
  useEffect(() => {
    if (settings?.dashboard_icon) {
      // Helper function to safely update or create link elements
      const updateLink = (selector: string, rel: string) => {
        let link = document.querySelector(selector) as HTMLLinkElement;
        if (!link) {
          link = document.createElement('link');
          link.rel = rel;
          document.head.appendChild(link);
        }
        link.type = 'image/png';
        link.href = settings.dashboard_icon!; // non-null assertion safe due to outer check
      };

      // Update standard favicon
      updateLink('link[rel~="icon"]', 'icon');
      updateLink('link[rel="shortcut icon"]', 'shortcut icon');

      // Update apple touch icon
      updateLink('link[rel="apple-touch-icon"]', 'apple-touch-icon');
    }
  }, [settings?.dashboard_icon, pathname]);



  const value: SettingsContextValue = {
    settings,
    isLoading,
    showThemeSwitcher,
    maxFileSize: parseInt(settings?.max_file_size || '5', 10),
    maxFilesCount: parseInt(settings?.max_files_count || '10', 10),
    allowedExtensions: settings?.allowed_extensions?.split(',').map(e => e.trim()) || ['png', 'jpg', 'jpeg', 'pdf'],
    dateFormat: normalizeDashboardDateFormat(
      settings?.dashboard_date_format || settings?.date_format,
    ),
    timeFormat: normalizeDashboardTimeFormat(
      settings?.dashboard_time_format || settings?.time_format,
    ),
    timezone: settings?.dashboard_timezone || 'UTC',
    primaryColor: settings?.dashboard_primary_color || '#1b8354',
    secondaryColor: settings?.dashboard_secondary_color || '#14573a',
    dashboardLogo: settings?.dashboard_logo || null,
    dashboardIcon: settings?.dashboard_icon || null,
    dashboardName: settings?.dashboard_name || null,
    browserTitle,
  };

  return (
    <SettingsContext.Provider value={value}>
      {children}
    </SettingsContext.Provider>
  );
}

export function useSettingsContext() {
  const context = useContext(SettingsContext);
  if (!context) {
    throw new Error('useSettingsContext must be used within SettingsProvider');
  }
  return context;
}

// Convenience hooks
export function useFileUploadSettings() {
  const { maxFileSize, maxFilesCount, allowedExtensions } = useSettingsContext();
  return { maxFileSize, maxFilesCount, allowedExtensions };
}

export function useOptionalFileUploadSettings() {
  const context = useContext(SettingsContext);
  if (!context) return null;
  const { maxFileSize, maxFilesCount, allowedExtensions } = context;
  return { maxFileSize, maxFilesCount, allowedExtensions };
}

export function useDateTimeSettings() {
  const { dateFormat, timeFormat, timezone } = useSettingsContext();
  return { dateFormat, timeFormat, timezone };
}
