import 'server-only';
import { createHash } from 'crypto';
import { unstable_cache } from 'next/cache';
import { inArray } from 'drizzle-orm';
import { db, platformSettings } from '@server/db/drizzle';

export interface ServerBranding {
  site_title: string;
  site_primary_color: string;
  site_logo_url: string;
  site_favicon_url: string;
  site_font_family: string;
  site_tagline: string;
  site_support_email: string;
  site_marketing_url: string;
}

export interface ServerBrandingSnapshot {
  branding: ServerBranding;
  version: string;
}

const BRANDING_KEYS: (keyof ServerBranding)[] = [
  'site_title',
  'site_primary_color',
  'site_logo_url',
  'site_favicon_url',
  'site_font_family',
  'site_tagline',
  'site_support_email',
  'site_marketing_url',
];

export const DEFAULT_SITE_TITLE = 'RestroAgent — AI Voice & Chat for Restaurants';
export const DEFAULT_SITE_NAME = 'RestroAgent';

const DEFAULT_BRANDING: ServerBranding = {
  site_title: '',
  site_primary_color: '',
  site_logo_url: '',
  site_favicon_url: '',
  site_font_family: '',
  site_tagline: '',
  site_support_email: '',
  site_marketing_url: '',
};

function coerceString(v: unknown): string {
  if (typeof v === 'string') return v;
  if (v && typeof v === 'object' && !Array.isArray(v)) {
    const first = Object.values(v as Record<string, unknown>)[0];
    if (typeof first === 'string') return first;
  }
  return '';
}

const loadBrandingCached = unstable_cache(
  async (): Promise<ServerBrandingSnapshot> => {
    try {
      const rows = await db
        .select({ key: platformSettings.key, value: platformSettings.value })
        .from(platformSettings)
        .where(inArray(platformSettings.key, BRANDING_KEYS as string[]));
      const branding: ServerBranding = { ...DEFAULT_BRANDING };
      for (const row of rows) {
        if ((BRANDING_KEYS as string[]).includes(row.key)) {
          (branding as unknown as Record<string, string>)[row.key] = coerceString(row.value);
        }
      }
      const hash = createHash('sha1')
        .update(JSON.stringify(branding))
        .digest('hex')
        .slice(0, 10);
      return { branding, version: hash };
    } catch {
      return { branding: { ...DEFAULT_BRANDING }, version: 'default' };
    }
  },
  ['platform-branding-v1'],
  { revalidate: 60, tags: ['branding'] },
);

export async function loadServerBranding(): Promise<ServerBrandingSnapshot> {
  return loadBrandingCached();
}

export function hexToHslString(hex: string): string | null {
  const m = hex.match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
  if (!m) return null;
  const r = parseInt(m[1], 16) / 255;
  const g = parseInt(m[2], 16) / 255;
  const b = parseInt(m[3], 16) / 255;
  const max = Math.max(r, g, b), min = Math.min(r, g, b);
  let h = 0, s = 0;
  const 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;
      default: h = ((r - g) / d + 4) / 6; break;
    }
  }
  return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
}

export function shadeHex(hex: string, amount: number): string {
  const m = hex.match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
  if (!m) return hex;
  const adj = (n: number) => Math.max(0, Math.min(255, Math.round(n + amount * 255)));
  const r = adj(parseInt(m[1], 16));
  const g = adj(parseInt(m[2], 16));
  const b = adj(parseInt(m[3], 16));
  return '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('');
}

export function hexToRgba(hex: string, alpha: number): string {
  const m = hex.match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
  if (!m) return hex;
  return `rgba(${parseInt(m[1], 16)}, ${parseInt(m[2], 16)}, ${parseInt(m[3], 16)}, ${alpha})`;
}

export function buildBrandingCss(branding: ServerBranding): string {
  const hex = branding.site_primary_color;
  if (!hex) return '';
  const hsl = hexToHslString(hex);
  const decls: string[] = [];
  if (hsl) decls.push(`--primary: ${hsl};`);
  decls.push(`--marketing-accent: ${hex};`);
  decls.push(`--marketing-accent-hover: ${shadeHex(hex, -0.06)};`);
  decls.push(`--marketing-accent-soft: ${hexToRgba(hex, 0.10)};`);
  decls.push(`--marketing-accent-ring: ${hexToRgba(hex, 0.35)};`);
  return `:root{${decls.join('')}}`;
}
