/**
 * Export Button Component
 *
 * Reusable component for exporting data to CSV or Excel
 */

'use client';

import { useState, useRef, useEffect } from 'react';
import { useTranslations, useLocale } from 'next-intl';
import { Download, FileSpreadsheet, FileText, ChevronDown, Lock } from 'lucide-react';
import { useSubscription } from '@/lib/context/subscription-context';

interface ExportButtonProps<T> {
  data: T[];
  filename: string;
  columns: {
    key: keyof T | string;
    label: string;
    format?: (value: any, row: T) => string;
  }[];
  disabled?: boolean;
}

export default function ExportButton<T extends Record<string, any>>({
  data,
  filename,
  columns,
  disabled = false,
}: ExportButtonProps<T>) {
  const t = useTranslations('components.exportButton');
  const locale = useLocale();
  const dateLocale = locale === 'fr' ? 'fr-FR' : 'en-US';
  const { hasFeature } = useSubscription();
  const canExport = hasFeature('csv_export');
  const [isOpen, setIsOpen] = useState(false);
  const [isExporting, setIsExporting] = useState(false);
  const dropdownRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const formatValue = (value: any): string => {
    if (value === null || value === undefined) return '';
    if (typeof value === 'boolean') return value ? t('boolean.true') : t('boolean.false');
    if (value instanceof Date) return value.toLocaleDateString(dateLocale);
    if (typeof value === 'object') return JSON.stringify(value);
    return String(value);
  };

  const getNestedValue = (obj: T, path: string): any => {
    return path.split('.').reduce((acc, part) => acc?.[part], obj as any);
  };

  const generateCSV = (): string => {
    const headers = columns.map(col => `"${col.label.replace(/"/g, '""')}"`).join(';');

    const rows = data.map(row => {
      return columns
        .map(col => {
          const value = getNestedValue(row, col.key as string);
          const formattedValue = col.format ? col.format(value, row) : formatValue(value);
          return `"${formattedValue.replace(/"/g, '""')}"`;
        })
        .join(';');
    });

    return [headers, ...rows].join('\n');
  };

  const downloadFile = (content: string, mimeType: string, extension: string) => {
    const BOM = '\uFEFF';
    const blob = new Blob([BOM + content], { type: `${mimeType};charset=utf-8` });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `${filename}_${new Date().toISOString().split('T')[0]}.${extension}`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  };

  const handleExportCSV = async () => {
    setIsExporting(true);
    try {
      const csv = generateCSV();
      downloadFile(csv, 'text/csv', 'csv');
    } catch (error) {
      console.error('Export CSV error:', error);
      alert(t('errorCsv'));
    } finally {
      setIsExporting(false);
      setIsOpen(false);
    }
  };

  const handleExportExcel = async () => {
    setIsExporting(true);
    try {
      const xmlHeader = `<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
  <Styles>
    <Style ss:ID="Header">
      <Font ss:Bold="1" ss:Color="#FFFFFF"/>
      <Interior ss:Color="#3B82F6" ss:Pattern="Solid"/>
      <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
    </Style>
    <Style ss:ID="Default">
      <Alignment ss:Vertical="Center"/>
    </Style>
  </Styles>
  <Worksheet ss:Name="Export">
    <Table>`;

      const columnWidths = columns
        .map(() => '<Column ss:AutoFitWidth="1" ss:Width="120"/>')
        .join('');

      const headerRow = `<Row ss:StyleID="Header">
        ${columns.map(col => `<Cell><Data ss:Type="String">${escapeXml(col.label)}</Data></Cell>`).join('')}
      </Row>`;

      const dataRows = data
        .map(row => {
          const cells = columns
            .map(col => {
              const value = getNestedValue(row, col.key as string);
              const formattedValue = col.format ? col.format(value, row) : formatValue(value);
              const type = typeof value === 'number' ? 'Number' : 'String';
              return `<Cell ss:StyleID="Default"><Data ss:Type="${type}">${escapeXml(formattedValue)}</Data></Cell>`;
            })
            .join('');
          return `<Row>${cells}</Row>`;
        })
        .join('');

      const xmlFooter = `</Table>
  </Worksheet>
</Workbook>`;

      const xmlContent = xmlHeader + columnWidths + headerRow + dataRows + xmlFooter;
      downloadFile(xmlContent, 'application/vnd.ms-excel', 'xls');
    } catch (error) {
      console.error('Export Excel error:', error);
      alert(t('errorExcel'));
    } finally {
      setIsExporting(false);
      setIsOpen(false);
    }
  };

  const escapeXml = (str: string): string => {
    return str
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&apos;');
  };

  return (
    <div className="relative" ref={dropdownRef}>
      <button
        onClick={() => (canExport ? setIsOpen(!isOpen) : (window.location.href = '/pricing'))}
        disabled={disabled || data.length === 0 || isExporting}
        title={!canExport ? t('lockedTooltip') : undefined}
        className={`inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md bg-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors ${
          canExport ? 'text-gray-700 hover:bg-gray-50' : 'text-gray-400 hover:bg-gray-50'
        }`}
      >
        {isExporting ? (
          <>
            <svg
              className="animate-spin -ml-1 mr-2 h-4 w-4 text-gray-600"
              fill="none"
              viewBox="0 0 24 24"
            >
              <circle
                className="opacity-25"
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                strokeWidth="4"
              />
              <path
                className="opacity-75"
                fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
              />
            </svg>
            {t('exporting')}
          </>
        ) : (
          <>
            {canExport ? <Download className="mr-2 h-4 w-4" /> : <Lock className="mr-2 h-4 w-4" />}
            {t('label')}
            {canExport && <ChevronDown className="ml-2 h-4 w-4" />}
          </>
        )}
      </button>

      {/* Dropdown Menu */}
      {isOpen && !isExporting && canExport && (
        <div className="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border border-gray-200 z-50">
          <div className="py-1">
            <button
              onClick={handleExportCSV}
              className="flex items-center w-full px-4 py-2.5 text-sm text-gray-700 hover:bg-gray-50 transition-colors"
            >
              <FileText className="mr-3 h-4 w-4 text-green-600" />
              <div className="text-left">
                <div className="font-medium">{t('csvTitle')}</div>
                <div className="text-xs text-gray-500">{t('csvSubtitle')}</div>
              </div>
            </button>
            <button
              onClick={handleExportExcel}
              className="flex items-center w-full px-4 py-2.5 text-sm text-gray-700 hover:bg-gray-50 transition-colors"
            >
              <FileSpreadsheet className="mr-3 h-4 w-4 text-blue-600" />
              <div className="text-left">
                <div className="font-medium">{t('excelTitle')}</div>
                <div className="text-xs text-gray-500">{t('excelSubtitle')}</div>
              </div>
            </button>
          </div>
          <div className="border-t border-gray-100 px-4 py-2">
            <p className="text-xs text-gray-500">{t('rowsToExport', { count: data.length })}</p>
          </div>
        </div>
      )}
    </div>
  );
}
