export type BrandingFormValues = {
  primary: string;
  accent: string;
  background: string;
  surface: string;
  headingFont: string;
  bodyFont: string;
  fontSize: 's' | 'm' | 'l';
  logoDataUrl: string;
  logoValue: string;
  logoMode: 'upload' | 'emoticon';
  logoPosition: 'left' | 'center' | 'right';
  logoSize: 's' | 'm' | 'l';
  mode: 'light' | 'dark' | 'auto';
  buttonStyle: 'filled' | 'outline';
  buttonRadius: number;
  buttonPrimary: string;
  buttonSecondary: string;
  linkColor: string;
  useDefaultBranding: boolean;
};

export type BrandingFormDefaults = Pick<
  BrandingFormValues,
  | 'primary'
  | 'accent'
  | 'background'
  | 'surface'
  | 'mode'
  | 'buttonStyle'
  | 'buttonRadius'
  | 'buttonPrimary'
  | 'buttonSecondary'
  | 'linkColor'
  | 'fontSize'
  | 'logoMode'
  | 'logoPosition'
  | 'logoSize'
>;

type BrandingRecord = Record<string, unknown>;

const isRecord = (value: unknown): value is BrandingRecord =>
  Boolean(value) && typeof value === 'object' && !Array.isArray(value);

const readHexColor = (value: unknown, fallback: string): string => {
  if (typeof value === 'string' && value.trim().startsWith('#')) {
    return value.trim();
  }
  return fallback;
};

const readEnum = <T extends string>(value: unknown, allowed: readonly T[], fallback: T): T => (
  allowed.includes(value as T) ? (value as T) : fallback
);

const readNumber = (value: unknown, fallback: number): number => (
  typeof value === 'number' && !Number.isNaN(value) ? value : fallback
);

const resolveAssetPreviewUrl = (value: string | null | undefined): string => {
  if (typeof value !== 'string') {
    return '';
  }

  const trimmed = value.trim();
  if (!trimmed) {
    return '';
  }

  if (trimmed.startsWith('data:') || trimmed.startsWith('http://') || trimmed.startsWith('https://')) {
    return trimmed;
  }

  const normalized = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed;

  if (normalized.startsWith('storage/')) {
    return `/${normalized}`;
  }

  if (normalized.startsWith('branding/') || normalized.startsWith('tenant-branding/')) {
    return `/storage/${normalized}`;
  }

  return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
};

export function extractBrandingForm(settings: unknown, defaults: BrandingFormDefaults): BrandingFormValues {
  const settingsRecord = isRecord(settings) ? settings : {};
  const branding = isRecord(settingsRecord.branding) ? (settingsRecord.branding as BrandingRecord) : settingsRecord;
  const palette = isRecord(branding.palette) ? (branding.palette as BrandingRecord) : {};
  const typography = isRecord(branding.typography) ? (branding.typography as BrandingRecord) : {};
  const buttons = isRecord(branding.buttons) ? (branding.buttons as BrandingRecord) : {};
  const logo = isRecord(branding.logo) ? (branding.logo as BrandingRecord) : {};

  const primary = readHexColor(palette.primary, readHexColor(branding.primary_color, defaults.primary));
  const accent = readHexColor(
    palette.secondary,
    readHexColor(branding.secondary_color, readHexColor(branding.accent_color, defaults.accent))
  );
  const background = readHexColor(palette.background, readHexColor(branding.background_color, defaults.background));
  const surface = readHexColor(palette.surface, readHexColor(branding.surface_color, background));

  const headingFont = typeof typography.heading === 'string' ? typography.heading : (branding.heading_font as string | undefined);
  const bodyFont = typeof typography.body === 'string' ? typography.body : (branding.body_font as string | undefined);
  const mode = readEnum(branding.mode, ['light', 'dark', 'auto'], defaults.mode);
  const fontSize = readEnum(typography.size ?? branding.font_size, ['s', 'm', 'l'], defaults.fontSize);

  const logoMode = readEnum(logo.mode ?? branding.logo_mode, ['upload', 'emoticon'], defaults.logoMode);
  const logoValue = logoMode === 'emoticon'
    ? (typeof logo.value === 'string' ? logo.value : (branding.logo_value as string | undefined) ?? '')
    : '';
  const logoPosition = readEnum(logo.position ?? branding.logo_position, ['left', 'center', 'right'], defaults.logoPosition);
  const logoSize = readEnum(logo.size ?? branding.logo_size, ['s', 'm', 'l'], defaults.logoSize);
  const logoUploadValue =
    typeof branding.logo_data_url === 'string'
      ? branding.logo_data_url
      : logoMode === 'upload'
        ? (typeof logo.value === 'string' ? logo.value : (branding.logo_url as string | undefined))
        : undefined;

  const buttonStyle = readEnum(buttons.style ?? branding.button_style, ['filled', 'outline'], defaults.buttonStyle);
  const buttonRadius = readNumber(buttons.radius ?? branding.button_radius, defaults.buttonRadius);
  const buttonPrimary = readHexColor(buttons.primary, readHexColor(branding.button_primary_color, primary));
  const buttonSecondary = readHexColor(buttons.secondary, readHexColor(branding.button_secondary_color, accent));
  const linkColor = readHexColor(buttons.link_color ?? buttons.linkColor, readHexColor(branding.link_color, accent));

  return {
    primary,
    accent,
    background,
    surface,
    headingFont: headingFont ?? '',
    bodyFont: bodyFont ?? '',
    fontSize,
    logoDataUrl: resolveAssetPreviewUrl(logoUploadValue),
    logoValue,
    logoMode,
    logoPosition,
    logoSize,
    mode,
    buttonStyle,
    buttonRadius,
    buttonPrimary,
    buttonSecondary,
    linkColor,
    useDefaultBranding: branding.use_default_branding === true,
  };
}
