import React, { useState } from 'react';
import {
  X,
  Download,
  CheckSquare,
  Square,
} from 'lucide-react';
import { toast } from 'react-toastify';
import { exportData } from '../../../shared/utils/exportUtils';
import analyticsService from '../services/analyticsService';

interface ReportMetric {
  id: string;
  category: 'revenue' | 'operational' | 'guest' | 'financial';
  metric: string;
  label: string;
}

interface CustomReportBuilderProps {
  onClose?: () => void;
}

const AVAILABLE_METRICS: ReportMetric[] = [
  // Revenue Metrics
  { id: 'revpar', category: 'revenue', metric: 'revpar', label: 'RevPAR (Revenue Per Available Room)' },
  { id: 'adr', category: 'revenue', metric: 'adr', label: 'ADR (Average Daily Rate)' },
  { id: 'occupancy', category: 'revenue', metric: 'occupancy', label: 'Occupancy Rate' },
  { id: 'forecast', category: 'revenue', metric: 'forecast', label: 'Revenue Forecast' },
  { id: 'market-penetration', category: 'revenue', metric: 'market-penetration', label: 'Market Penetration' },
  
  // Operational Metrics
  { id: 'staff-performance', category: 'operational', metric: 'staff-performance', label: 'Staff Performance' },
  { id: 'service-usage', category: 'operational', metric: 'service-usage', label: 'Service Usage' },
  { id: 'efficiency', category: 'operational', metric: 'efficiency', label: 'Operational Efficiency' },
  
  // Guest Metrics
  { id: 'ltv', category: 'guest', metric: 'lifetime-value', label: 'Guest Lifetime Value' },
  { id: 'cac', category: 'guest', metric: 'acquisition-cost', label: 'Customer Acquisition Cost' },
  { id: 'repeat-rate', category: 'guest', metric: 'repeat-rate', label: 'Repeat Guest Rate' },
  { id: 'satisfaction', category: 'guest', metric: 'satisfaction-trends', label: 'Guest Satisfaction Trends' },
  
  // Financial Metrics
  { id: 'profit-loss', category: 'financial', metric: 'profit-loss', label: 'Profit & Loss' },
  { id: 'payment-methods', category: 'financial', metric: 'payment-methods', label: 'Payment Methods' },
  { id: 'refunds', category: 'financial', metric: 'refunds', label: 'Refund Analysis' },
];

const CustomReportBuilder: React.FC<CustomReportBuilderProps> = ({ onClose }) => {
  const [reportName, setReportName] = useState('');
  const [selectedMetrics, setSelectedMetrics] = useState<string[]>([]);
  const [dateRange, setDateRange] = useState({
    from: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
    to: new Date().toISOString().split('T')[0],
  });
  const [loading, setLoading] = useState(false);
  const [activeCategory, setActiveCategory] = useState<'revenue' | 'operational' | 'guest' | 'financial' | 'all'>('all');

  const toggleMetric = (metricId: string) => {
    setSelectedMetrics(prev =>
      prev.includes(metricId)
        ? prev.filter(id => id !== metricId)
        : [...prev, metricId]
    );
  };

  const selectAllInCategory = (category: string) => {
    const categoryMetrics = AVAILABLE_METRICS
      .filter(m => category === 'all' || m.category === category)
      .map(m => m.id);
    
    setSelectedMetrics(prev => {
      const newSelection = [...prev];
      categoryMetrics.forEach(id => {
        if (!newSelection.includes(id)) {
          newSelection.push(id);
        }
      });
      return newSelection;
    });
  };

  const clearSelection = () => {
    setSelectedMetrics([]);
  };

  const fetchMetricData = async (metric: ReportMetric) => {
    const params = { from: dateRange.from, to: dateRange.to };
    
    switch (metric.metric) {
      case 'revpar':
        return await analyticsService.getRevPAR(params);
      case 'adr':
        return await analyticsService.getADR(params);
      case 'occupancy':
        return await analyticsService.getOccupancyRate(params);
      case 'forecast':
        return await analyticsService.getRevenueForecast(30);
      case 'market-penetration':
        return await analyticsService.getMarketPenetration(params);
      case 'staff-performance':
        return await analyticsService.getStaffPerformance(params);
      case 'service-usage':
        return await analyticsService.getServiceUsageAnalytics(params);
      case 'efficiency':
        return await analyticsService.getOperationalEfficiency(params);
      case 'lifetime-value':
        return await analyticsService.getGuestLifetimeValue(params);
      case 'acquisition-cost':
        return await analyticsService.getCustomerAcquisitionCost(params);
      case 'repeat-rate':
        return await analyticsService.getRepeatGuestRate(params);
      case 'satisfaction-trends':
        return await analyticsService.getGuestSatisfactionTrends(params);
      case 'profit-loss':
        return await analyticsService.getProfitLoss(params);
      case 'payment-methods':
        return await analyticsService.getPaymentMethodAnalytics(params);
      case 'refunds':
        return await analyticsService.getRefundAnalysis(params);
      default:
        return null;
    }
  };

  const generateReport = async (format: 'csv' | 'xlsx' | 'pdf' | 'json') => {
    if (selectedMetrics.length === 0) {
      toast.error('Please select at least one metric');
      return;
    }

    setLoading(true);
    try {
      const reportData: Array<Record<string, unknown>> = [];
      const selectedMetricObjects = AVAILABLE_METRICS.filter(m => selectedMetrics.includes(m.id));

      for (const metric of selectedMetricObjects) {
        const response = await fetchMetricData(metric);
        if (response && response.data) {
          // Flatten the data for export
          const flattened = flattenMetricData(metric.label, response.data);
          reportData.push(...flattened);
        }
      }

      if (reportData.length === 0) {
        toast.error('No data available for selected metrics');
        return;
      }

      const filename = reportName || `custom-report-${new Date().toISOString().split('T')[0]}`;
      
      exportData({
        filename,
        title: reportName || 'Custom Analytics Report',
        data: reportData,
        format,
      });

      toast.success(`Report exported as ${format.toUpperCase()} successfully`);
      if (onClose) onClose();
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
      toast.error(`Failed to generate report: ${errorMessage}`);
    } finally {
      setLoading(false);
    }
  };

  const flattenMetricData = (metricLabel: string, data: unknown): Array<Record<string, unknown>> => {
    // Handle different data structures
    if (Array.isArray(data)) {
      return data.map(item => ({ Metric: metricLabel, ...(item as Record<string, unknown>) }));
    }
    
    if (typeof data === 'object' && data !== null) {
      const dataObj = data as Record<string, unknown>;
      // Try to find array properties
      const arrayKeys = Object.keys(dataObj).filter(key => Array.isArray(dataObj[key]));
      
      if (arrayKeys.length > 0) {
        // Use first array found
        const arrayData = dataObj[arrayKeys[0]] as Array<Record<string, unknown>>;
        return arrayData.map((item) => ({
          Metric: metricLabel,
          ...item,
        }));
      }
      
      // Flatten object
      return [{
        Metric: metricLabel,
        ...(dataObj as Record<string, unknown>),
      }];
    }
    
    return [{ Metric: metricLabel, Value: data }];
  };

  const filteredMetrics = activeCategory === 'all'
    ? AVAILABLE_METRICS
    : AVAILABLE_METRICS.filter(m => m.category === activeCategory);

  const categories = [
    { id: 'all' as const, label: 'All Metrics', count: AVAILABLE_METRICS.length },
    { id: 'revenue' as const, label: 'Revenue', count: AVAILABLE_METRICS.filter(m => m.category === 'revenue').length },
    { id: 'operational' as const, label: 'Operational', count: AVAILABLE_METRICS.filter(m => m.category === 'operational').length },
    { id: 'guest' as const, label: 'Guest', count: AVAILABLE_METRICS.filter(m => m.category === 'guest').length },
    { id: 'financial' as const, label: 'Financial', count: AVAILABLE_METRICS.filter(m => m.category === 'financial').length },
  ];

  return (
    <div className="bg-white rounded-xl shadow-xl border border-gray-200 p-6 max-w-4xl mx-auto">
      <div className="flex items-center justify-between mb-6">
        <div>
          <h2 className="text-2xl font-bold text-gray-900">Custom Report Builder</h2>
          <p className="text-gray-600 mt-1">Select metrics and generate custom analytics reports</p>
        </div>
        {onClose && (
          <button
            onClick={onClose}
            className="p-2 text-gray-400 hover:text-gray-600 transition-colors"
          >
            <X className="w-6 h-6" />
          </button>
        )}
      </div>

      {/* Report Name */}
      <div className="mb-6">
        <label className="block text-sm font-medium text-gray-700 mb-2">
          Report Name (Optional)
        </label>
        <input
          type="text"
          value={reportName}
          onChange={(e) => setReportName(e.target.value)}
          placeholder="e.g., Monthly Revenue Report"
          className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
        />
      </div>

      {/* Date Range */}
      <div className="mb-6">
        <label className="block text-sm font-medium text-gray-700 mb-2">Date Range</label>
        <div className="flex items-center gap-3">
          <input
            type="date"
            value={dateRange.from}
            onChange={(e) => setDateRange({ ...dateRange, from: e.target.value })}
            className="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500"
          />
          <span className="text-gray-500">to</span>
          <input
            type="date"
            value={dateRange.to}
            onChange={(e) => setDateRange({ ...dateRange, to: e.target.value })}
            className="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500"
          />
        </div>
      </div>

      {/* Category Filter */}
      <div className="mb-6">
        <label className="block text-sm font-medium text-gray-700 mb-2">Filter by Category</label>
        <div className="flex flex-wrap gap-2">
          {categories.map((category) => (
            <button
              key={category.id}
              onClick={() => setActiveCategory(category.id)}
              className={`px-4 py-2 rounded-lg font-medium transition-all ${
                activeCategory === category.id
                  ? 'bg-indigo-600 text-white'
                  : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
              }`}
            >
              {category.label} ({category.count})
            </button>
          ))}
        </div>
      </div>

      {/* Metrics Selection */}
      <div className="mb-6">
        <div className="flex items-center justify-between mb-3">
          <label className="block text-sm font-medium text-gray-700">
            Select Metrics ({selectedMetrics.length} selected)
          </label>
          <div className="flex gap-2">
            <button
              onClick={() => selectAllInCategory(activeCategory)}
              className="text-sm text-indigo-600 hover:text-indigo-700 font-medium"
            >
              Select All
            </button>
            <button
              onClick={clearSelection}
              className="text-sm text-gray-600 hover:text-gray-700 font-medium"
            >
              Clear
            </button>
          </div>
        </div>
        <div className="border border-gray-200 rounded-lg p-4 max-h-96 overflow-y-auto">
          <div className="space-y-2">
            {filteredMetrics.map((metric) => {
              const isSelected = selectedMetrics.includes(metric.id);
              return (
                <button
                  key={metric.id}
                  onClick={() => toggleMetric(metric.id)}
                  className={`w-full flex items-center gap-3 p-3 rounded-lg transition-all ${
                    isSelected
                      ? 'bg-indigo-50 border-2 border-indigo-500'
                      : 'bg-gray-50 border-2 border-transparent hover:bg-gray-100'
                  }`}
                >
                  {isSelected ? (
                    <CheckSquare className="w-5 h-5 text-indigo-600" />
                  ) : (
                    <Square className="w-5 h-5 text-gray-400" />
                  )}
                  <div className="flex-1 text-left">
                    <div className="font-medium text-gray-900">{metric.label}</div>
                    <div className="text-xs text-gray-500 capitalize">{metric.category}</div>
                  </div>
                </button>
              );
            })}
          </div>
        </div>
      </div>

      {/* Actions */}
      <div className="flex items-center justify-end gap-3 pt-4 border-t border-gray-200">
        <button
          onClick={() => generateReport('csv')}
          disabled={loading || selectedMetrics.length === 0}
          className="px-6 py-2 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
        >
          <Download className="w-4 h-4" />
          Export CSV
        </button>
        <button
          onClick={() => generateReport('xlsx')}
          disabled={loading || selectedMetrics.length === 0}
          className="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
        >
          <Download className="w-4 h-4" />
          Export Excel
        </button>
        <button
          onClick={() => generateReport('pdf')}
          disabled={loading || selectedMetrics.length === 0}
          className="px-6 py-2 bg-rose-600 text-white rounded-lg hover:bg-rose-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
        >
          <Download className="w-4 h-4" />
          Export PDF
        </button>
      </div>

      {loading && (
        <div className="mt-4 text-center text-gray-600">
          Generating report...
        </div>
      )}
    </div>
  );
};

export default CustomReportBuilder;

