import React, { useState, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { Sparkles } from 'lucide-react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import { SettingsLayout } from './components/SettingsLayout';
import { SettingsCard } from './components/SettingsCard';
import { SettingsSection } from './components/SettingsSection';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { SearchableSelect } from '@/components/ui/searchable-select';
import { ImageUpload } from '@/components/ui/image-upload';
import { ColorPicker } from '@/components/ui/color-picker';
import { Button } from '@/components/ui/button';
import { toast } from 'sonner';
import flagsData from '@/data/flags.json';
import { useUnsavedChanges } from '@/hooks/useUnsavedChanges';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';

// Convert country code to emoji flag
function countryCodeToEmoji(countryCode: string): string {
  if (!countryCode || countryCode.length !== 2) return '';
  const codePoints = countryCode
    .toUpperCase()
    .split('')
    .map(char => 127397 + char.charCodeAt(0));
  return String.fromCodePoint(...codePoints);
}

interface StoreSettings {
  storeName: string;
  contactEmail: string;
  supportEmail: string;
  phone: string;
  country: string;
  address: string;
  city: string;
  state: string;
  postcode: string;
  currency: string;
  currencyPosition: 'left' | 'right' | 'left_space' | 'right_space';
  thousandSep: string;
  decimalSep: string;
  decimals: number;
  timezone: string;
  weightUnit: string;
  dimensionUnit: string;
  // Branding
  storeLogo: string;
  storeLogoDark: string;
  storeIcon: string;
  storeTagline: string;
  primaryColor: string;
  accentColor: string;
  errorColor: string;
}

export default function StoreDetailsPage() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [settings, setSettings] = useState<StoreSettings>({
    storeName: '',
    contactEmail: '',
    supportEmail: '',
    phone: '',
    country: 'ID',
    address: '',
    city: '',
    state: '',
    postcode: '',
    currency: 'IDR',
    currencyPosition: 'left',
    thousandSep: ',',
    decimalSep: '.',
    decimals: 0,
    timezone: 'Asia/Jakarta',
    weightUnit: 'kg',
    dimensionUnit: 'cm',
    storeLogo: '',
    storeLogoDark: '',
    storeIcon: '',
    storeTagline: '',
    primaryColor: '#3b82f6',
    accentColor: '#10b981',
    errorColor: '#ef4444',
  });

  // Fetch store settings
  const { data: storeData, isLoading } = useQuery({
    queryKey: ['store-settings'],
    queryFn: () => api.get('/store/settings'),
  });

  // Fetch countries
  const { data: countries = [] } = useQuery({
    queryKey: ['store-countries'],
    queryFn: () => api.get('/store/countries'),
    staleTime: 60 * 60 * 1000, // 1 hour
  });

  // Fetch timezones
  const { data: timezones = {} } = useQuery({
    queryKey: ['store-timezones'],
    queryFn: () => api.get('/store/timezones'),
    staleTime: 60 * 60 * 1000, // 1 hour
  });

  // Fetch currencies
  const { data: currencies = [] } = useQuery({
    queryKey: ['store-currencies'],
    queryFn: () => api.get('/store/currencies'),
    staleTime: 60 * 60 * 1000, // 1 hour
  });

  // Initialize state from data - use useMemo instead of useEffect to avoid cascading renders
  const initialSettings = useMemo(() => {
    if (!storeData) return settings;
    return {
      storeName: storeData.store_name || '',
      contactEmail: storeData.contact_email || '',
      supportEmail: storeData.support_email || '',
      phone: storeData.phone || '',
      country: storeData.country || 'ID',
      address: storeData.address || '',
      city: storeData.city || '',
      state: '',
      postcode: storeData.postcode || '',
      currency: storeData.currency || 'IDR',
      currencyPosition: storeData.currency_position || 'left',
      thousandSep: storeData.thousand_separator || ',',
      decimalSep: storeData.decimal_separator || '.',
      decimals: storeData.number_of_decimals || 0,
      timezone: storeData.timezone || 'Asia/Jakarta',
      weightUnit: storeData.weight_unit || 'kg',
      dimensionUnit: storeData.dimension_unit || 'cm',
      storeLogo: storeData.store_logo || '',
      storeLogoDark: storeData.store_logo_dark || '',
      storeIcon: storeData.store_icon || '',
      storeTagline: storeData.store_tagline || '',
      primaryColor: storeData.primary_color || '#3b82f6',
      accentColor: storeData.accent_color || '#10b981',
      errorColor: storeData.error_color || '#ef4444',
    };
  }, [storeData]);

  // Update settings when initialSettings changes
  useEffect(() => {
    if (storeData) {
      // eslint-disable-next-line react-hooks/set-state-in-effect
      setSettings(initialSettings);
    }
  }, [initialSettings, storeData]);

  // Save mutation
  const saveMutation = useMutation({
    mutationFn: (data: StoreSettings) => api.post('/store/settings', {
      store_name: data.storeName,
      contact_email: data.contactEmail,
      support_email: data.supportEmail,
      phone: data.phone,
      country: data.country,
      address: data.address,
      city: data.city,
      postcode: data.postcode,
      currency: data.currency,
      currency_position: data.currencyPosition,
      thousand_separator: data.thousandSep,
      decimal_separator: data.decimalSep,
      number_of_decimals: data.decimals,
      timezone: data.timezone,
      weight_unit: data.weightUnit,
      dimension_unit: data.dimensionUnit,
      store_logo: data.storeLogo,
      store_logo_dark: data.storeLogoDark,
      store_icon: data.storeIcon,
      store_tagline: data.storeTagline,
      primary_color: data.primaryColor,
      accent_color: data.accentColor,
      error_color: data.errorColor,
    }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['store-settings'] });
      toast.success('Your store details have been updated successfully.');

      // Dispatch event to update site title in header
      window.dispatchEvent(new CustomEvent('woonoow:store:updated', {
        detail: { store_name: settings.storeName }
      }));
    },
    onError: () => {
      toast.error('Failed to save store settings');
    },
  });

  const handleSave = async () => {
    await saveMutation.mutateAsync(settings);
  };

  const isDirty = useMemo(() => {
    return JSON.stringify(settings) !== JSON.stringify(initialSettings);
  }, [settings, initialSettings]);

  // Keyboard shortcut listener
  useEffect(() => {
    const handleSaveShortcut = () => {
      if (isDirty && !saveMutation.isPending) {
        handleSave();
      }
    };
    window.addEventListener('woonoow:shortcut:save', handleSaveShortcut);
    return () => window.removeEventListener('woonoow:shortcut:save', handleSaveShortcut);
  }, [isDirty, saveMutation.isPending, handleSave]);

  const { showPrompt, confirmNavigation, cancelNavigation } = useUnsavedChanges(isDirty);

  const updateSetting = <K extends keyof StoreSettings>(
    key: K,
    value: StoreSettings[K]
  ) => {
    setSettings((prev) => ({ ...prev, [key]: value }));
  };

  // Currency preview
  const formatCurrency = (amount: number) => {
    const formatted = amount.toFixed(settings.decimals)
      .replace('.', settings.decimalSep)
      .replace(/\B(?=(\d{3})+(?!\d))/g, settings.thousandSep);

    // Get currency symbol from currencies data, fallback to currency code
    const currencyInfo = currencies.find((c: any) => c.code === settings.currency);
    let symbol = settings.currency; // Default to currency code

    if (currencyInfo?.symbol && !currencyInfo.symbol.includes('&#')) {
      // Use symbol only if it exists and doesn't contain HTML entities
      symbol = currencyInfo.symbol;
    }

    switch (settings.currencyPosition) {
      case 'left':
        return `${symbol}${formatted}`;
      case 'right':
        return `${formatted}${symbol}`;
      case 'left_space':
        return `${symbol} ${formatted}`;
      case 'right_space':
        return `${formatted} ${symbol}`;
      default:
        return `${symbol}${formatted}`;
    }
  };

  return (
    <SettingsLayout
      title="Store Details"
      description="Manage your store's basic information and regional settings"
      onSave={handleSave}
      isLoading={isLoading}
      action={
        <Button
          variant="outline"
          size="sm"
          onClick={() => navigate('/setup')}
          className="gap-2"
        >
          <Sparkles className="w-4 h-4" />
          Launch Setup Wizard
        </Button>
      }
    >
      {/* Store Overview */}
      <div className="bg-primary/10 border border-primary/20 rounded-lg p-4">
        {(() => {
          const currencyFlag = flagsData.find((f: any) => f.code === settings.currency);
          const currencyInfo = currencies.find((c: any) => c.code === settings.currency);
          const countryName = currencyFlag?.country || settings.country;

          return (
            <>
              <p className="text-sm font-medium">
                📍 Store Location: {countryName}
              </p>
              <p className="text-sm text-muted-foreground mt-1">
                Currency: {currencyInfo?.name || settings.currency} • Timezone: {settings.timezone}
              </p>
            </>
          );
        })()}
      </div>

      {/* Store Identity */}
      <SettingsCard
        title="Store Identity"
        description="Basic information about your store"
      >
        <SettingsSection label="Store name" required htmlFor="storeName">
          <Input
            id="storeName"
            value={settings.storeName}
            onChange={(e) => updateSetting('storeName', e.target.value)}
            placeholder="My Awesome Store"
          />
        </SettingsSection>

        <SettingsSection
          label="Store tagline"
          description="A short tagline or slogan for your store"
          htmlFor="storeTagline"
        >
          <Input
            id="storeTagline"
            value={settings.storeTagline}
            onChange={(e) => updateSetting('storeTagline', e.target.value)}
            placeholder="Quality products, delivered fast"
          />
        </SettingsSection>

        <SettingsSection
          label="Contact email"
          description="Customers will use this email to contact you"
          htmlFor="contactEmail"
        >
          <Input
            id="contactEmail"
            type="email"
            value={settings.contactEmail}
            onChange={(e) => updateSetting('contactEmail', e.target.value)}
            placeholder="contact@example.com"
          />
        </SettingsSection>

        <SettingsSection
          label="Customer support email"
          description="Separate email for customer support inquiries"
          htmlFor="supportEmail"
        >
          <Input
            id="supportEmail"
            type="email"
            value={settings.supportEmail}
            onChange={(e) => updateSetting('supportEmail', e.target.value)}
            placeholder="support@example.com"
          />
        </SettingsSection>

        <SettingsSection
          label="Store phone"
          description="Optional phone number for customer inquiries"
          htmlFor="phone"
        >
          <Input
            id="phone"
            type="tel"
            value={settings.phone}
            onChange={(e) => updateSetting('phone', e.target.value)}
            placeholder="+62 812 3456 7890"
          />
        </SettingsSection>
      </SettingsCard>

      {/* Brand */}
      <SettingsCard
        title="Brand"
        description="Logo, icon, and colors for your store"
      >
        <SettingsSection label="Store logo (Light mode)" description="Recommended size: 200x60px (or similar ratio). PNG with transparent background works best.">
          <ImageUpload
            value={settings.storeLogo}
            onChange={(url) => updateSetting('storeLogo', url)}
            onRemove={() => updateSetting('storeLogo', '')}
            maxSize={2}
            mediaType="logo"
          />
        </SettingsSection>

        <SettingsSection
          label="Store logo (Dark mode)"
          description="Optional. If not set, light mode logo will be used in dark mode."
        >
          <ImageUpload
            className={"bg-gray-900/50"}
            value={settings.storeLogoDark}
            onChange={(url) => updateSetting('storeLogoDark', url)}
            onRemove={() => updateSetting('storeLogoDark', '')}
            maxSize={2}
            mediaType="logo"
          />
        </SettingsSection>

        <SettingsSection label="Store icon" description="Favicon for browser tabs. Recommended: 32x32px or larger square image.">
          <ImageUpload
            value={settings.storeIcon}
            onChange={(url) => updateSetting('storeIcon', url)}
            onRemove={() => updateSetting('storeIcon', '')}
            maxSize={1}
            mediaType="favicon"
          />
        </SettingsSection>

        <div className="pt-4 border-t">
          <h4 className="text-sm font-medium mb-4">Brand Colors</h4>
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
            <ColorPicker
              label="Primary Color"
              description="Main brand color"
              value={settings.primaryColor}
              onChange={(color) => updateSetting('primaryColor', color)}
            />

            <ColorPicker
              label="Accent Color"
              description="Success and highlights"
              value={settings.accentColor}
              onChange={(color) => updateSetting('accentColor', color)}
            />

            <ColorPicker
              label="Error Color"
              description="Errors and warnings"
              value={settings.errorColor}
              onChange={(color) => updateSetting('errorColor', color)}
            />
          </div>

          <div className="flex items-center gap-2 mt-4">
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={() => {
                updateSetting('primaryColor', '#3b82f6');
                updateSetting('accentColor', '#10b981');
                updateSetting('errorColor', '#ef4444');
                toast.success('Colors reset to default');
              }}
            >
              Reset to Default
            </Button>
            <p className="text-sm text-muted-foreground">
              Changes apply after saving
            </p>
          </div>
        </div>
      </SettingsCard>

      {/* Store Address */}
      <SettingsCard
        title="Store Address"
        description="Used for shipping origin, invoices, and tax calculations"
      >
        <SettingsSection label="Country/Region" required htmlFor="country">
          <SearchableSelect
            value={settings.country}
            onChange={(v) => updateSetting('country', v)}
            options={countries.map((country: { code: string; name: string }) => {
              const flagEmoji = countryCodeToEmoji(country.code);
              return {
                value: country.code,
                label: `${flagEmoji} ${country.name}`.trim(),
                searchText: `${country.code} ${country.name}`,
              };
            })}
            placeholder="Select country..."
          />
        </SettingsSection>

        <SettingsSection label="Street address" htmlFor="address">
          <Input
            id="address"
            value={settings.address}
            onChange={(e) => updateSetting('address', e.target.value)}
            placeholder="Jl. Example No. 123"
          />
        </SettingsSection>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <SettingsSection label="City" htmlFor="city">
            <Input
              id="city"
              value={settings.city}
              onChange={(e) => updateSetting('city', e.target.value)}
              placeholder="Jakarta"
            />
          </SettingsSection>

          <SettingsSection label="State/Province" htmlFor="state">
            <Input
              id="state"
              value={settings.state}
              onChange={(e) => updateSetting('state', e.target.value)}
              placeholder="DKI Jakarta"
            />
          </SettingsSection>

          <SettingsSection label="Postal code" htmlFor="postcode">
            <Input
              id="postcode"
              value={settings.postcode}
              onChange={(e) => updateSetting('postcode', e.target.value)}
              placeholder="12345"
            />
          </SettingsSection>
        </div>
      </SettingsCard>

      {/* Currency & Formatting */}
      <SettingsCard
        title="Currency & Formatting"
        description="How prices are displayed in your store"
      >
        <SettingsSection label="Currency" required htmlFor="currency">
          <SearchableSelect
            value={settings.currency}
            onChange={(v) => updateSetting('currency', v)}
            options={currencies.map((currency: { code: string; name: string; symbol: string }) => {
              // Use currency code if symbol contains HTML entities (&#x...) or is empty
              const displaySymbol = (!currency.symbol || currency.symbol.includes('&#'))
                ? currency.code
                : currency.symbol;

              // Find matching flag data and convert to emoji
              const flagInfo = flagsData.find((f: any) => f.code === currency.code);
              const flagEmoji = flagInfo ? countryCodeToEmoji(flagInfo.countryCode) : '';

              return {
                value: currency.code,
                label: `${flagEmoji} ${currency.name} (${displaySymbol})`.trim(),
                searchText: `${currency.code} ${currency.name} ${displaySymbol}`,
              };
            })}
            placeholder="Select currency..."
          />
        </SettingsSection>

        <SettingsSection label="Currency position" htmlFor="currencyPosition">
          <Select
            value={settings.currencyPosition}
            onValueChange={(v: any) => updateSetting('currencyPosition', v)}
          >
            <SelectTrigger id="currencyPosition">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="left">Left (Rp1234)</SelectItem>
              <SelectItem value="right">Right (1234Rp)</SelectItem>
              <SelectItem value="left_space">Left with space (Rp 1234)</SelectItem>
              <SelectItem value="right_space">Right with space (1234 Rp)</SelectItem>
            </SelectContent>
          </Select>
        </SettingsSection>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <SettingsSection label="Thousand separator" htmlFor="thousandSep">
            <Input
              id="thousandSep"
              value={settings.thousandSep}
              onChange={(e) => updateSetting('thousandSep', e.target.value)}
              maxLength={1}
              placeholder=","
            />
          </SettingsSection>

          <SettingsSection label="Decimal separator" htmlFor="decimalSep">
            <Input
              id="decimalSep"
              value={settings.decimalSep}
              onChange={(e) => updateSetting('decimalSep', e.target.value)}
              maxLength={1}
              placeholder="."
            />
          </SettingsSection>

          <SettingsSection label="Number of decimals" htmlFor="decimals">
            <Select
              value={settings.decimals.toString()}
              onValueChange={(v) => updateSetting('decimals', parseInt(v))}
            >
              <SelectTrigger id="decimals">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="0">0</SelectItem>
                <SelectItem value="1">1</SelectItem>
                <SelectItem value="2">2</SelectItem>
                <SelectItem value="3">3</SelectItem>
                <SelectItem value="4">4</SelectItem>
              </SelectContent>
            </Select>
          </SettingsSection>
        </div>

        {/* Live Preview */}
        <div className="mt-4 p-4 bg-muted rounded-lg">
          <p className="text-sm text-muted-foreground mb-2">Preview:</p>
          <p className="text-2xl font-semibold">{formatCurrency(1234567.89)}</p>
        </div>
      </SettingsCard>

      {/* Standards & Formats */}
      <SettingsCard
        title="Standards & Formats"
        description="Timezone and measurement units"
      >
        <SettingsSection label="Timezone" htmlFor="timezone">
          <SearchableSelect
            value={settings.timezone}
            onChange={(v) => updateSetting('timezone', v)}
            options={Object.entries(timezones).flatMap(([continent, tzList]: [string, any]) =>
              tzList.map((tz: { value: string; label: string; offset: string }) => ({
                value: tz.value,
                label: `${tz.label} (${tz.offset})`,
                searchText: `${continent} ${tz.label} ${tz.offset}`,
              }))
            )}
            placeholder="Select timezone..."
          />
        </SettingsSection>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <SettingsSection label="Weight unit" htmlFor="weightUnit">
            <Select value={settings.weightUnit} onValueChange={(v) => updateSetting('weightUnit', v)}>
              <SelectTrigger id="weightUnit">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="kg">Kilogram (kg)</SelectItem>
                <SelectItem value="g">Gram (g)</SelectItem>
                <SelectItem value="lb">Pound (lb)</SelectItem>
                <SelectItem value="oz">Ounce (oz)</SelectItem>
              </SelectContent>
            </Select>
          </SettingsSection>

          <SettingsSection label="Dimension unit" htmlFor="dimensionUnit">
            <Select value={settings.dimensionUnit} onValueChange={(v) => updateSetting('dimensionUnit', v)}>
              <SelectTrigger id="dimensionUnit">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="cm">Centimeter (cm)</SelectItem>
                <SelectItem value="m">Meter (m)</SelectItem>
                <SelectItem value="in">Inch (in)</SelectItem>
                <SelectItem value="ft">Foot (ft)</SelectItem>
              </SelectContent>
            </Select>
          </SettingsSection>
        </div>
      </SettingsCard>

      <AlertDialog open={showPrompt} onOpenChange={cancelNavigation}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Unsaved Changes</AlertDialogTitle>
            <AlertDialogDescription>
              You have unsaved changes. Are you sure you want to leave this page?
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={cancelNavigation}>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={confirmNavigation} className="bg-destructive hover:bg-destructive/90">
              Leave Page
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </SettingsLayout>
  );
}
