import React, { useEffect, useCallback } from 'react';
import { useCanvasStore } from '../../store/canvasStore';
import { useBrandingStore } from '../../store/brandingStore';
import { FONT_FAMILIES } from '../../types';
import { SocialIcon } from '../elements/SocialIcons';

const POSITION_OPTIONS = [
  { value: 'top-left', label: 'Top Left' },
  { value: 'top-right', label: 'Top Right' },
  { value: 'bottom-left', label: 'Bottom Left' },
  { value: 'bottom-right', label: 'Bottom Right' },
] as const;

const SOCIAL_PLATFORMS = [
  { key: 'twitter', label: 'X (Twitter)', placeholder: '@username' },
  { key: 'linkedin', label: 'LinkedIn', placeholder: '/in/username' },
  { key: 'instagram', label: 'Instagram', placeholder: '@username' },
  { key: 'github', label: 'GitHub', placeholder: 'username' },
  { key: 'youtube', label: 'YouTube', placeholder: '@channel' },
  { key: 'tiktok', label: 'TikTok', placeholder: '@username' },
] as const;

const MAX_AVATAR_DIMENSION = 192;
const MAX_EMBEDDED_AVATAR_LENGTH = 350000;

const readFileAsDataUrl = (file: File) => new Promise<string>((resolve, reject) => {
  const reader = new FileReader();
  reader.onload = () => {
    if (typeof reader.result === 'string') {
      resolve(reader.result);
    } else {
      reject(new Error('Could not read file contents.'));
    }
  };
  reader.onerror = () => reject(reader.error ?? new Error('Avatar read failed.'));
  reader.readAsDataURL(file);
});

const loadImage = (src: string) => new Promise<HTMLImageElement>((resolve, reject) => {
  const img = new Image();
  img.onload = () => resolve(img);
  img.onerror = () => reject(new Error('Avatar image could not be loaded.'));
  img.src = src;
});

const optimiseAvatarFile = async (file: File): Promise<string> => {
  const rawDataUrl = await readFileAsDataUrl(file);

  if (rawDataUrl.length <= MAX_EMBEDDED_AVATAR_LENGTH) {
    return rawDataUrl;
  }

  try {
    const image = await loadImage(rawDataUrl);
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    if (!ctx) {
      return rawDataUrl;
    }

    let targetSize = MAX_AVATAR_DIMENSION;
    let optimised = rawDataUrl;

    while (targetSize >= 96) {
      const maxSide = Math.max(image.width, image.height);
      const scale = maxSide > targetSize ? targetSize / maxSide : 1;
      const width = Math.max(1, Math.round(image.width * scale));
      const height = Math.max(1, Math.round(image.height * scale));

      canvas.width = width;
      canvas.height = height;
      ctx.clearRect(0, 0, width, height);
      ctx.drawImage(image, 0, 0, width, height);

      optimised = canvas.toDataURL('image/png');
      if (optimised.length <= MAX_EMBEDDED_AVATAR_LENGTH) {
        break;
      }

      optimised = canvas.toDataURL('image/jpeg', 0.82);
      if (optimised.length <= MAX_EMBEDDED_AVATAR_LENGTH) {
        break;
      }

      targetSize = Math.floor(targetSize * 0.75);
    }

    return optimised.length <= MAX_EMBEDDED_AVATAR_LENGTH ? optimised : rawDataUrl;
  } catch (error) {
    console.warn('Avatar optimisation failed, keeping the original image.', error);
    return rawDataUrl;
  }
};

const BrandingPanel: React.FC = () => {
  const { setBackground } = useCanvasStore();
  const { info, preferences, updateInfo, updateSocial, updatePreferences } = useBrandingStore();

  // Sync branding store to canvas whenever it changes
  useEffect(() => {
    setBackground({
      branding: {
        ...preferences,
        name: info.name,
        website: info.website,
        social: info.social,
        avatarUrl: info.avatarUrl,
      },
    });
  }, [info, preferences, setBackground]);

  const handleUpdatePreferences = (updates: Partial<typeof preferences>) => {
    updatePreferences(updates);
  };

  const handleUpdateInfo = (updates: Partial<typeof info>) => {
    updateInfo(updates);
  };

  const handleUpdateSocial = (platform: string, value: string) => {
    updateSocial(platform, value);
  };

  const handleAvatarUpload = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];

    const resetInput = () => {
      if (event.target) {
        event.target.value = '';
      }
    };

    if (!file || !file.type.startsWith('image/')) {
      resetInput();
      return;
    }

    void optimiseAvatarFile(file)
      .then((dataUrl) => {
        handleUpdateInfo({ avatarUrl: dataUrl });
        handleUpdatePreferences({ showAvatar: true });
      })
      .catch((error) => {
        console.warn('Avatar upload cancelled.', error);
      })
      .finally(resetInput);
  }, [handleUpdateInfo, handleUpdatePreferences]);

  const handleAvatarClear = useCallback(() => {
    handleUpdateInfo({ avatarUrl: '' });
  }, [handleUpdateInfo]);

  return (
    <div className="space-y-6">
      {/* Enable Branding */}
      <div className="flex items-center justify-between">
        <label className="block text-xs font-medium text-neutral-500 uppercase tracking-wider">
          Branding Watermark
        </label>
        <button
          onClick={() => handleUpdatePreferences({ enabled: !preferences.enabled })}
          className={`relative inline-flex h-5 w-9 items-center rounded-full transition-colors ${
            preferences.enabled ? 'bg-blue-600' : 'bg-white/10'
          }`}
        >
          <span
            className={`inline-block h-3.5 w-3.5 transform rounded-full bg-white transition-transform ${
              preferences.enabled ? 'translate-x-4' : 'translate-x-1'
            }`}
          />
        </button>
      </div>

      {preferences.enabled && (
        <div className="space-y-5">
          {/* Position */}
          <div>
            <label className="block text-xs font-medium text-neutral-500 uppercase tracking-wider mb-2">
              Position
            </label>
            <div className="grid grid-cols-2 gap-2">
              {POSITION_OPTIONS.map((opt) => (
                <button
                  key={opt.value}
                  onClick={() => handleUpdatePreferences({ position: opt.value })}
                  className={`py-2 px-3 rounded-lg text-xs font-medium transition-all border ${
                    preferences.position === opt.value
                      ? 'bg-blue-600/20 text-blue-400 border-blue-500/50'
                      : 'bg-white/5 text-neutral-400 hover:text-white hover:bg-white/10 border-white/5'
                  }`}
                >
                  {opt.label}
                </button>
              ))}
            </div>
          </div>

          {/* Avatar */}
          <div>
            <div className="flex items-center justify-between mb-2">
              <label className="block text-xs font-medium text-neutral-500 uppercase tracking-wider">
                Avatar
              </label>
              <button
                onClick={() => handleUpdatePreferences({ showAvatar: !preferences.showAvatar })}
                className={`text-xs px-2 py-0.5 rounded ${
                  preferences.showAvatar
                    ? 'bg-blue-600/20 text-blue-400'
                    : 'bg-white/5 text-neutral-500'
                }`}
              >
                {preferences.showAvatar ? 'Hide' : 'Show'}
              </button>
            </div>
            <div className="flex items-center gap-3">
              <label className="relative w-16 h-16 rounded-full border border-white/10 bg-white/5 overflow-hidden cursor-pointer group">
                {info.avatarUrl ? (
                  <img
                    src={info.avatarUrl}
                    alt="Brand avatar"
                    className="w-full h-full object-cover"
                  />
                ) : (
                  <div className="absolute inset-0 flex flex-col items-center justify-center text-[10px] text-neutral-500 group-hover:text-neutral-300">
                    <span>Upload</span>
                    <span className="text-[9px] text-neutral-600">PNG/JPG</span>
                  </div>
                )}
                <input
                  type="file"
                  accept="image/*"
                  onChange={handleAvatarUpload}
                  className="absolute inset-0 opacity-0 cursor-pointer"
                  aria-label="Upload avatar"
                />
              </label>
              <div className="flex-1 text-[11px] text-neutral-500 space-y-1">
                <p>Use a square image for best results. Supported formats: PNG, JPG, SVG.</p>
                {info.avatarUrl && (
                  <button
                    onClick={handleAvatarClear}
                    className="text-xs text-neutral-400 hover:text-red-400 transition-colors"
                  >
                    Remove avatar
                  </button>
                )}
              </div>
            </div>
            {preferences.showAvatar && (
              <div className="mt-3">
                <label className="block text-xs text-neutral-500 mb-2">
                  Size: {preferences.avatarSize}px
                </label>
                <input
                  type="range"
                  min={32}
                  max={120}
                  value={preferences.avatarSize}
                  onChange={(e) => handleUpdatePreferences({ avatarSize: parseInt(e.target.value) })}
                  className="w-full h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-blue-600"
                />
              </div>
            )}
          </div>

          {/* Name */}
          <div>
            <div className="flex items-center justify-between mb-2">
              <label className="block text-xs font-medium text-neutral-500 uppercase tracking-wider">
                Name
              </label>
              <button
                onClick={() => handleUpdatePreferences({ showName: !preferences.showName })}
                className={`text-xs px-2 py-0.5 rounded ${
                  preferences.showName
                    ? 'bg-blue-600/20 text-blue-400'
                    : 'bg-white/5 text-neutral-500'
                }`}
              >
                {preferences.showName ? 'Show' : 'Hide'}
              </button>
            </div>
            <input
              type="text"
              value={info.name}
              onChange={(e) => handleUpdateInfo({ name: e.target.value })}
              placeholder="Your Name"
              className="w-full bg-white/5 text-white px-3 py-2 rounded-lg text-sm border border-white/5 focus:border-blue-500/50 focus:outline-none"
            />
          </div>

          {/* Website */}
          <div>
            <div className="flex items-center justify-between mb-2">
              <label className="block text-xs font-medium text-neutral-500 uppercase tracking-wider">
                Website
              </label>
              <button
                onClick={() => handleUpdatePreferences({ showWebsite: !preferences.showWebsite })}
                className={`text-xs px-2 py-0.5 rounded ${
                  preferences.showWebsite
                    ? 'bg-blue-600/20 text-blue-400'
                    : 'bg-white/5 text-neutral-500'
                }`}
              >
                {preferences.showWebsite ? 'Show' : 'Hide'}
              </button>
            </div>
            <input
              type="text"
              value={info.website}
              onChange={(e) => handleUpdateInfo({ website: e.target.value })}
              placeholder="yourwebsite.com"
              className="w-full bg-white/5 text-white px-3 py-2 rounded-lg text-sm border border-white/5 focus:border-blue-500/50 focus:outline-none"
            />
          </div>

          {/* Social Media */}
          <div>
            <div className="flex items-center justify-between mb-3">
              <label className="block text-xs font-medium text-neutral-500 uppercase tracking-wider">
                Social Media
              </label>
              <button
                onClick={() => handleUpdatePreferences({ showSocial: !preferences.showSocial })}
                className={`text-xs px-2 py-0.5 rounded ${
                  preferences.showSocial
                    ? 'bg-blue-600/20 text-blue-400'
                    : 'bg-white/5 text-neutral-500'
                }`}
              >
                {preferences.showSocial ? 'Show' : 'Hide'}
              </button>
            </div>
            <div className="space-y-2">
              {SOCIAL_PLATFORMS.map((platform) => (
                <div key={platform.key} className="flex items-center gap-2">
                  <div className="w-5 h-5 shrink-0 flex items-center justify-center text-neutral-400">
                    <SocialIcon platform={platform.key} size={16} color="currentColor" />
                  </div>
                  <input
                    type="text"
                    value={info.social[platform.key as keyof typeof info.social] || ''}
                    onChange={(e) => handleUpdateSocial(platform.key, e.target.value)}
                    placeholder={platform.placeholder}
                    className="flex-1 bg-white/5 text-white px-2 py-1.5 rounded-md text-xs border border-white/5 focus:border-blue-500/50 focus:outline-none"
                  />
                </div>
              ))}
            </div>

            {/* Social Icons Layout */}
            <div className="mt-4 space-y-3">
              <div>
                <label className="block text-xs text-neutral-500 mb-2">Layout</label>
                <div className="flex gap-2">
                  <button
                    onClick={() => handleUpdatePreferences({ socialLayout: 'horizontal' })}
                    className={`flex-1 py-2 px-3 rounded-lg text-xs font-medium transition-all border ${
                      preferences.socialLayout === 'horizontal'
                        ? 'bg-blue-600/20 text-blue-400 border-blue-500/50'
                        : 'bg-white/5 text-neutral-400 hover:text-white hover:bg-white/10 border-white/5'
                    }`}
                  >
                    Horizontal
                  </button>
                  <button
                    onClick={() => handleUpdatePreferences({ socialLayout: 'vertical' })}
                    className={`flex-1 py-2 px-3 rounded-lg text-xs font-medium transition-all border ${
                      preferences.socialLayout === 'vertical'
                        ? 'bg-blue-600/20 text-blue-400 border-blue-500/50'
                        : 'bg-white/5 text-neutral-400 hover:text-white hover:bg-white/10 border-white/5'
                    }`}
                  >
                    Vertical
                  </button>
                </div>
              </div>

              <div>
                <label className="block text-xs text-neutral-500 mb-2">
                  Icon Size: {preferences.socialIconSize}px
                </label>
                <input
                  type="range"
                  min="14"
                  max="32"
                  value={preferences.socialIconSize}
                  onChange={(e) => handleUpdatePreferences({ socialIconSize: parseInt(e.target.value) })}
                  className="w-full h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-blue-600"
                />
              </div>
            </div>
          </div>

          {/* Styling */}
          <div className="pt-4 border-t border-white/5">
            <label className="block text-xs font-medium text-neutral-500 uppercase tracking-wider mb-3">
              Styling
            </label>

            {/* Font Family */}
            <div className="mb-4">
              <label className="block text-xs text-neutral-500 mb-2">Font</label>
              <select
                value={preferences.fontFamily}
                onChange={(e) => handleUpdatePreferences({ fontFamily: e.target.value })}
                className="w-full bg-white/5 text-white px-3 py-2 rounded-lg text-sm border border-white/5 focus:border-blue-500/50 focus:outline-none"
              >
                {FONT_FAMILIES.text.map((font) => (
                  <option key={font} value={font} style={{ fontFamily: font }}>
                    {font}
                  </option>
                ))}
              </select>
            </div>

            {/* Font Size */}
            <div className="mb-4">
              <label className="block text-xs text-neutral-500 mb-2">
                Font Size: {preferences.fontSize}px
              </label>
              <input
                type="range"
                min="10"
                max="24"
                value={preferences.fontSize}
                onChange={(e) => handleUpdatePreferences({ fontSize: parseInt(e.target.value) })}
                className="w-full h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-blue-600"
              />
            </div>

            {/* Color */}
            <div className="mb-4">
              <label className="block text-xs text-neutral-500 mb-2">Color</label>
              <div className="flex gap-2 items-center p-2 bg-white/5 rounded-lg border border-white/5">
                <div className="w-6 h-6 rounded overflow-hidden relative border border-white/10 shrink-0">
                  <input
                    type="color"
                    value={preferences.color}
                    onChange={(e) => handleUpdatePreferences({ color: e.target.value })}
                    className="absolute inset-[-4px] w-[200%] h-[200%] cursor-pointer"
                  />
                </div>
                <input
                  type="text"
                  value={preferences.color}
                  onChange={(e) => handleUpdatePreferences({ color: e.target.value })}
                  className="w-full bg-transparent text-white text-xs focus:outline-none font-mono"
                />
              </div>
            </div>

            {/* Opacity */}
            <div className="mb-4">
              <label className="block text-xs text-neutral-500 mb-2">
                Opacity: {Math.round(preferences.opacity * 100)}%
              </label>
              <input
                type="range"
                min="0.1"
                max="1"
                step="0.05"
                value={preferences.opacity}
                onChange={(e) => handleUpdatePreferences({ opacity: parseFloat(e.target.value) })}
                className="w-full h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-blue-600"
              />
            </div>

            {/* Padding */}
            <div>
              <label className="block text-xs text-neutral-500 mb-2">
                Padding: {preferences.padding}px
              </label>
              <input
                type="range"
                min="8"
                max="48"
                value={preferences.padding}
                onChange={(e) => handleUpdatePreferences({ padding: parseInt(e.target.value) })}
                className="w-full h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-blue-600"
              />
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default BrandingPanel;
