/**
 * ExportFilters component - Main export interface (Figma Design).
 *
 * Implements new filter builder pattern with:
 * - Filter type → Condition → Value selector workflow
 * - Applied filters as removable badges
 * - Visual card-based file structure selection
 * - Empty state for no filters
 *
 * @package GetMD
 * @since   1.0.0
 */

import { format, subDays } from 'date-fns';
import { Plus, X, FileText, Files, Check, Filter, Loader2 } from 'lucide-react';
import { Button } from './ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
import { MultiSelect } from './ui/multi-select';
import { DateRangePicker } from './ui/date-range-picker';
import { Badge } from './ui/badge';
import { cn } from '../lib/utils';
import { useExport, type AppliedFilter } from '../contexts/ExportContext';
import type { FilterCriteria } from '../types/wordpress';
import { MediaSettings } from './MediaSettings';

/**
 * Render the export filter builder UI for composing and executing content export jobs.
 *
 * Manages applied filters, filter construction (including date ranges and multi-select values),
 * file structure selection, export job lifecycle (create and poll), progress display, and download.
 *
 * @returns A React element containing the export filters user interface
 */
export function ExportFilters() {
  const { i18n, postTypes, statuses, categories, tags, authors } = window.summixGetmdData || {};

  // Get all state and actions from context
  const {
    // Export state
    isExporting,
    exportJob,
    error,
    // Preview state
    previewCount,
    isLoadingPreview,
    // Filter state
    appliedFilters,
    filterType,
    filterCondition,
    filterValues,
    dateRange,
    fileStructure,
    mediaSettings,
    // Export actions
    startExport,
    // Filter setters
    setAppliedFilters,
    setFilterType,
    setFilterCondition,
    setFilterValues,
    setDateRange,
    setFileStructure,
    setMediaSettings,
  } = useExport();

  // Get condition options based on filter type
  const getConditionOptions = () => {
    if (filterType === 'date_range') {
      return [
        { value: 'within', label: i18n?.conditionWithin || 'Within' },
        { value: 'before', label: i18n?.conditionBefore || 'Before' },
        { value: 'after', label: i18n?.conditionAfter || 'After' },
      ];
    }
    return [
      { value: 'include', label: i18n?.conditionInclude || 'Include' },
      { value: 'exclude', label: i18n?.conditionExclude || 'Exclude' },
    ];
  };

  // Get human-readable label for filter
  const getFilterLabel = (filter: AppliedFilter): string => {
    const conditionText = filter.condition.charAt(0).toUpperCase() + filter.condition.slice(1);
    let typeText = '';
    let valueText = '';

    switch (filter.type) {
      case 'post_type':
        typeText = i18n?.filterContentType || 'Content type';
        if (Array.isArray(filter.values)) {
          const labels = filter.values.map(
            (slug) => postTypes?.find((pt) => pt.slug === slug)?.label || slug
          );
          valueText = labels.join(', ');
        }
        break;
      case 'status':
        typeText = i18n?.filterStatus || 'Status';
        if (Array.isArray(filter.values)) {
          valueText = filter.values.map((s) => String(statuses?.[s] || s)).join(', ');
        }
        break;
      case 'category':
        typeText = i18n?.filterCategory || 'Category';
        if (Array.isArray(filter.values)) {
          const labels = filter.values.map(
            (id) => categories?.find((c) => c.id === id)?.name || id
          );
          valueText = labels.join(', ');
        }
        break;
      case 'tag':
        typeText = i18n?.filterTag || 'Tag';
        if (Array.isArray(filter.values)) {
          const labels = filter.values.map((id) => tags?.find((t) => t.id === id)?.name || id);
          valueText = labels.join(', ');
        }
        break;
      case 'author':
        typeText = i18n?.filterAuthor || 'Author';
        if (Array.isArray(filter.values)) {
          const labels = filter.values.map(
            (id) => authors?.find((a) => a.id === id)?.name || id
          );
          valueText = labels.join(', ');
        }
        break;
      case 'date_range':
        typeText = i18n?.filterDateRange || 'Date range';
        if (typeof filter.values === 'object' && 'from' in filter.values && 'to' in filter.values) {
          valueText = `${format(filter.values.from, 'MMM d, yyyy')} - ${format(filter.values.to, 'MMM d, yyyy')}`;
        }
        break;
    }

    return `${conditionText} ${typeText}: ${valueText}`;
  };

  // Add filter to applied filters
  const handleAddFilter = () => {
    let values: any;

    if (filterType === 'date_range') {
      if (!dateRange?.from || !dateRange?.to) return;
      values = { from: dateRange.from, to: dateRange.to };
    } else {
      if (filterValues.length === 0) return;
      values = filterValues;
    }

    const newFilter: AppliedFilter = {
      id: `${filterType}-${Date.now()}`,
      type: filterType as AppliedFilter['type'],
      condition: filterCondition as AppliedFilter['condition'],
      values,
      label: '',
    };

    newFilter.label = getFilterLabel(newFilter);
    setAppliedFilters([...appliedFilters, newFilter]);

    // Reset builder
    setFilterValues([]);
    setDateRange(undefined);
  };

  // Remove filter
  const handleRemoveFilter = (id: string) => {
    setAppliedFilters(appliedFilters.filter((f) => f.id !== id));
  };

  // Reset condition when filter type changes
  const handleFilterTypeChange = (value: string) => {
    setFilterType(value);
    setFilterCondition(value === 'date_range' ? 'within' : 'include');
    setFilterValues([]);
    setDateRange(undefined);
  };

  // Render value selector based on filter type
  const renderValueSelector = () => {
    if (filterType === 'date_range') {
      return (
        <DateRangePicker
          value={dateRange}
          onChange={setDateRange}
          placeholder="Select date range"
          disabled={isExporting}
        />
      );
    }

    let options: { value: any; label: string }[] = [];

    switch (filterType) {
      case 'post_type':
        options =
          postTypes?.map((type) => ({
            value: type.slug,
            label: type.label,
          })) || [];
        break;
      case 'status':
        options = statuses
          ? Object.entries(statuses).map(([key, label]) => ({
              value: key,
              label: String(label),
            }))
          : [];
        break;
      case 'category':
        options =
          categories?.map((cat) => ({
            value: cat.id,
            label: cat.name,
          })) || [];
        break;
      case 'tag':
        options =
          tags?.map((tag) => ({
            value: tag.id,
            label: tag.name,
          })) || [];
        break;
      case 'author':
        options =
          authors?.map((author) => ({
            value: author.id,
            label: author.name,
          })) || [];
        break;
    }

    return (
      <MultiSelect
        options={options}
        selected={filterValues}
        onChange={setFilterValues}
        placeholder={`Select ${filterType.replace('_', ' ')}`}
        disabled={isExporting}
      />
    );
  };

  // Build filter criteria for export
  const buildFilterCriteria = (): FilterCriteria => {
    const criteria: FilterCriteria = {
      post_type: [],
      post_status: [],
      file_structure: fileStructure,
      media_settings: mediaSettings,
    };

    appliedFilters.forEach((filter) => {
      switch (filter.type) {
        case 'post_type':
          if (Array.isArray(filter.values)) {
            criteria.post_type = [...(criteria.post_type || []), ...filter.values] as string[];
          }
          break;
        case 'status':
          if (Array.isArray(filter.values)) {
            criteria.post_status = [...(criteria.post_status || []), ...filter.values] as string[];
          }
          break;
        case 'category':
          if (Array.isArray(filter.values)) {
            criteria.category = filter.values as number[];
            criteria.category_condition = filter.condition as 'include' | 'exclude';
          }
          break;
        case 'tag':
          if (Array.isArray(filter.values)) {
            criteria.tag = filter.values as number[];
            criteria.tag_condition = filter.condition as 'include' | 'exclude';
          }
          break;
        case 'author':
          if (Array.isArray(filter.values)) {
            criteria.author = filter.values as number[];
            criteria.author_condition = filter.condition as 'include' | 'exclude';
          }
          break;
        case 'date_range':
          if (typeof filter.values === 'object' && 'from' in filter.values && 'to' in filter.values) {
            criteria.date_range = {
              start: format(filter.values.from, 'yyyy-MM-dd'),
              end: format(filter.values.to, 'yyyy-MM-dd'),
            };
          }
          break;
      }
    });

    // Remove empty arrays to let backend apply defaults
    // When no post_type is specified, backend exports all public post types
    // When no post_status is specified, backend applies capability-based defaults
    if (criteria.post_type && criteria.post_type.length === 0) {
      delete criteria.post_type;
    }
    if (criteria.post_status && criteria.post_status.length === 0) {
      delete criteria.post_status;
    }

    return criteria;
  };

  // Create export job using context
  const handleExport = async () => {
    const filters = buildFilterCriteria();
    await startExport(filters);
  };

  // Calculate progress percentage
  const getProgressPercent = (): number => {
    if (!exportJob) return 0;
    if (exportJob.status === 'completed') return 100;
    if (exportJob.progress) return exportJob.progress.percent;
    return 0;
  };

  // Check if can add filter
  const canAddFilter = () => {
    if (filterType === 'date_range') {
      return dateRange?.from && dateRange?.to;
    }
    return filterValues.length > 0;
  };

  // Handle quick filter presets
  const handleQuickFilter = (preset: 'posts' | 'pages' | 'published' | 'recent') => {
    if (isExporting) return;

    let newFilter: AppliedFilter;
    const id = `${preset}-${Date.now()}`;

    switch (preset) {
      case 'posts':
        newFilter = {
          id,
          type: 'post_type',
          condition: 'include',
          values: ['post'],
          label: 'Include Post Type: Post',
        };
        break;
      case 'pages':
        newFilter = {
          id,
          type: 'post_type',
          condition: 'include',
          values: ['page'],
          label: 'Include Post Type: Page',
        };
        break;
      case 'published':
        newFilter = {
          id,
          type: 'status',
          condition: 'include',
          values: ['publish'],
          label: 'Include Status: Published',
        };
        break;
      case 'recent':
        const today = new Date();
        const thirtyDaysAgo = subDays(today, 30);
        newFilter = {
          id,
          type: 'date_range',
          condition: 'within',
          values: { from: thirtyDaysAgo, to: today },
          label: `Within Date Range: ${format(thirtyDaysAgo, 'MMM d, yyyy')} - ${format(today, 'MMM d, yyyy')}`,
        };
        break;
    }

    // Check if a similar filter already exists
    const existingFilter = appliedFilters.find(
      (f) => f.type === newFilter.type && JSON.stringify(f.values) === JSON.stringify(newFilter.values)
    );

    if (!existingFilter) {
      setAppliedFilters([...appliedFilters, newFilter]);
    }
  };

  return (
    <div className="smx-space-y-6">
      {/* Content Filters Card */}
      <Card>
        <CardHeader>
          <CardTitle>{i18n?.contentFiltersTitle || 'What to Export'}</CardTitle>
          <CardDescription>
            {i18n?.contentFiltersDesc || 'Choose what gets included. Stack filters for precision.'}
          </CardDescription>
        </CardHeader>
        <CardContent className="smx-space-y-6">
          {/* Quick Filter Presets */}
          <div className="smx-space-y-2">
            <label className="smx-section-label">{i18n?.quickPicks || 'Quick picks'}</label>
            <div className="smx-flex smx-flex-wrap smx-gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={() => handleQuickFilter('posts')}
                disabled={isExporting}
                className="smx-text-xs"
              >
                {i18n?.allPosts || 'All posts'}
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => handleQuickFilter('pages')}
                disabled={isExporting}
                className="smx-text-xs"
              >
                {i18n?.allPages || 'All pages'}
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => handleQuickFilter('published')}
                disabled={isExporting}
                className="smx-text-xs"
              >
                {i18n?.publishedOnly || 'Published only'}
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => handleQuickFilter('recent')}
                disabled={isExporting}
                className="smx-text-xs"
              >
                {i18n?.recentDays || 'Recent (30 days)'}
              </Button>
            </div>
          </div>

          {/* Filter Builder */}
          <div className="smx-space-y-3">
            <label className="smx-section-label">{i18n?.addFilter || 'Add a filter'}</label>

            <div className="smx-flex smx-gap-3 smx-items-end">
              {/* Filter Type Selector */}
              <div className="smx-flex-1 smx-min-w-[140px]">
                <Select value={filterType} onValueChange={handleFilterTypeChange}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="post_type">{i18n?.filterContentType || 'Content type'}</SelectItem>
                    <SelectItem value="author">{i18n?.filterAuthor || 'Author'}</SelectItem>
                    <SelectItem value="category">{i18n?.filterCategory || 'Category'}</SelectItem>
                    <SelectItem value="tag">{i18n?.filterTag || 'Tag'}</SelectItem>
                    <SelectItem value="status">{i18n?.filterStatus || 'Status'}</SelectItem>
                    <SelectItem value="date_range">{i18n?.filterDateRange || 'Date range'}</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              {/* Condition Selector */}
              <div className="smx-flex-1 smx-min-w-[100px]">
                <Select value={filterCondition} onValueChange={setFilterCondition}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {getConditionOptions().map((option) => (
                      <SelectItem key={option.value} value={option.value}>
                        {option.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              {/* Value Selector (dynamic) */}
              <div className="smx-flex-[2] smx-min-w-[200px]">
                {renderValueSelector()}
              </div>

              {/* Add Filter Button */}
              <Button variant="outline" onClick={handleAddFilter} disabled={!canAddFilter() || isExporting} className="smx-shrink-0">
                <Plus className="smx-w-4 smx-h-4 smx-mr-2" />
                {i18n?.addFilterButton || 'Add'}
              </Button>
            </div>
          </div>

          {/* Applied Filters Display */}
          {appliedFilters.length === 0 ? (
            <div className="smx-flex smx-flex-col smx-items-center smx-justify-center smx-py-10 smx-text-center smx-border-2 smx-border-dashed smx-rounded-lg smx-bg-muted/30 smx-empty-state-animated smx-transition-colors">
              <div className="smx-rounded-full smx-bg-primary/10 smx-p-4 smx-mb-4">
                <Filter className="smx-w-8 smx-h-8 smx-text-primary" />
              </div>
              <p className="smx-font-medium smx-text-lg">{i18n?.noFiltersTitle || 'Everything included'}</p>
              <p className="smx-text-sm smx-text-muted-foreground smx-max-w-xs smx-mt-1">
                {i18n?.noFiltersDesc || 'All your content will be exported. Add filters above to narrow it down.'}
              </p>
            </div>
          ) : (
            <div className="smx-flex smx-flex-wrap smx-gap-2">
              {appliedFilters.map((filter) => (
                <Badge key={filter.id} variant="secondary" className="smx-pl-3 smx-pr-1 smx-py-1.5">
                  {filter.label}
                  <button
                    onClick={() => handleRemoveFilter(filter.id)}
                    className="smx-ml-2 smx-rounded-full smx-p-0.5 hover:smx-bg-secondary-foreground/20"
                    disabled={isExporting}
                  >
                    <X className="smx-w-3 smx-h-3" />
                  </button>
                </Badge>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Export Options Card */}
      <Card>
        <CardHeader>
          <CardTitle>{i18n?.exportOptionsTitle || 'Output Format'}</CardTitle>
          <CardDescription>
            {i18n?.exportOptionsDesc || 'How should we package your files?'}
          </CardDescription>
        </CardHeader>
        <CardContent className="smx-space-y-3">
          <h4 className="smx-section-label">{i18n?.fileStructure || 'File structure'}</h4>

          {/* Compact File Structure Selection */}
          <div className="smx-grid smx-grid-cols-2 smx-gap-3">
            {/* Multiple Files Option */}
            <button
              type="button"
              className={cn(
                'smx-flex smx-items-center smx-gap-3 smx-p-3 smx-rounded-lg smx-border smx-text-left smx-transition-all',
                fileStructure === 'multiple'
                  ? 'smx-border-primary smx-bg-primary/5 smx-ring-1 smx-ring-primary'
                  : 'hover:smx-border-primary/50 hover:smx-bg-muted/50'
              )}
              onClick={() => !isExporting && setFileStructure('multiple')}
              disabled={isExporting}
            >
              <Files className="smx-w-5 smx-h-5 smx-text-primary smx-flex-shrink-0" />
              <div className="smx-flex-1 smx-min-w-0">
                <p className="smx-font-medium smx-text-sm">{i18n?.separateFiles || 'Separate files'}</p>
                <p className="smx-text-xs smx-text-muted-foreground">{i18n?.separateFilesDesc || 'One Markdown file per item'}</p>
              </div>
              {fileStructure === 'multiple' && (
                <Check className="smx-w-4 smx-h-4 smx-text-primary smx-flex-shrink-0" />
              )}
            </button>

            {/* Single File Option */}
            <button
              type="button"
              className={cn(
                'smx-flex smx-items-center smx-gap-3 smx-p-3 smx-rounded-lg smx-border smx-text-left smx-transition-all',
                fileStructure === 'single'
                  ? 'smx-border-primary smx-bg-primary/5 smx-ring-1 smx-ring-primary'
                  : 'hover:smx-border-primary/50 hover:smx-bg-muted/50'
              )}
              onClick={() => !isExporting && setFileStructure('single')}
              disabled={isExporting}
            >
              <FileText className="smx-w-5 smx-h-5 smx-text-primary smx-flex-shrink-0" />
              <div className="smx-flex-1 smx-min-w-0">
                <p className="smx-font-medium smx-text-sm">{i18n?.singleFile || 'Single file'}</p>
                <p className="smx-text-xs smx-text-muted-foreground">{i18n?.singleFileDesc || 'Everything in one Markdown file'}</p>
              </div>
              {fileStructure === 'single' && (
                <Check className="smx-w-4 smx-h-4 smx-text-primary smx-flex-shrink-0" />
              )}
            </button>
          </div>
        </CardContent>
      </Card>

      {/* Media Settings Card */}
      <MediaSettings
        settings={mediaSettings}
        onChange={setMediaSettings}
        disabled={isExporting}
      />

      {/* Ready to Export Card */}
      <Card>
        <CardHeader>
          <CardTitle>{i18n?.readyTitle || 'Ready'}</CardTitle>
        </CardHeader>
        <CardContent className="smx-space-y-4">
          <div className="smx-space-y-1">
            <p className="smx-text-sm smx-text-muted-foreground">
              {appliedFilters.length === 0
                ? (i18n?.exportingEverything || 'Exporting everything')
                : appliedFilters.length === 1
                  ? (i18n?.filterActive?.replace('%d', '1') || '1 filter active')
                  : (i18n?.filtersActive?.replace('%d', String(appliedFilters.length)) || `${appliedFilters.length} filters active`)}
            </p>
            <p className="smx-text-sm smx-font-medium smx-text-foreground">
              {isLoadingPreview ? (
                <span className="smx-flex smx-items-center smx-gap-2">
                  <Loader2 className="smx-h-3 smx-w-3 smx-animate-spin" />
                  {i18n?.countingItems || 'Counting items...'}
                </span>
              ) : previewCount !== null ? (
                previewCount === 1
                  ? (i18n?.itemReady?.replace('%s', '1') || '1 item ready')
                  : (i18n?.itemsReady?.replace('%s', previewCount.toLocaleString()) || `${previewCount.toLocaleString()} items ready`)
              ) : null}
            </p>
          </div>

          <Button onClick={handleExport} disabled={isExporting} className="smx-w-full">
            {isExporting ? (i18n?.exporting || 'Exporting...') : (i18n?.export || 'Export')}
          </Button>
        </CardContent>
      </Card>

      {/* Progress Display */}
      {exportJob && (
        <Card>
          <CardHeader>
            <CardTitle>{i18n?.progressTitle || 'Progress'}</CardTitle>
          </CardHeader>
          <CardContent className="smx-space-y-4">
            {/* Status Badge */}
            <div className="smx-flex smx-items-center smx-gap-2">
              <Badge
                variant={
                  exportJob.status === 'completed'
                    ? 'default'
                    : exportJob.status === 'failed'
                    ? 'destructive'
                    : 'secondary'
                }
              >
                {exportJob.status === 'processing' ? (i18n?.statusExporting || 'Exporting...')
                  : exportJob.status === 'completed' ? (i18n?.statusDone || 'Done')
                  : exportJob.status === 'failed' ? (i18n?.statusFailed || 'Failed')
                  : (i18n?.statusQueued || 'Queued')}
              </Badge>
            </div>

            {/* Progress Bar */}
            {(exportJob.status === 'processing' || exportJob.status === 'pending') && (
              <div className="smx-space-y-2">
                <div className="smx-w-full smx-bg-secondary smx-rounded-full smx-h-2.5">
                  <div
                    className="smx-bg-primary smx-h-2.5 smx-rounded-full smx-transition-all smx-duration-300"
                    style={{ width: `${getProgressPercent()}%` }}
                  />
                </div>
                <p className="smx-text-sm smx-text-muted-foreground">
                  {getProgressPercent().toFixed(0)}%
                </p>
              </div>
            )}

            {/* File Info */}
            <div className="smx-grid smx-grid-cols-2 smx-gap-4 smx-text-sm">
              <div>
                <span className="smx-font-medium">{i18n?.files || 'Files'}</span> {exportJob.file_count}
              </div>
              {exportJob.file_size > 0 && (
                <div>
                  <span className="smx-font-medium">{i18n?.size || 'Size'}</span>{' '}
                  {(exportJob.file_size / 1024 / 1024).toFixed(2)} MB
                </div>
              )}
            </div>

            {/* Download Button */}
            {exportJob.status === 'completed' && exportJob.download_url && (
              <Button asChild className="smx-w-full">
                <a href={exportJob.download_url}>{i18n?.downloadZip || 'Download .zip'}</a>
              </Button>
            )}
          </CardContent>
        </Card>
      )}

      {/* Error Display */}
      {error && (
        <Card className="smx-border-destructive">
          <CardContent className="smx-pt-6">
            <p className="smx-text-destructive smx-text-sm">{error}</p>
          </CardContent>
        </Card>
      )}
    </div>
  );
}