/**
 * Settings card for managing custom XBRL concept mappings.
 */

import React, { useState } from 'react';
import {
  FileDown,
  FileUp,
  Plus,
  RefreshCw,
  Trash2,
  Edit2,
  Power,
  PowerOff,
  FolderOpen,
  FunctionSquare,
} from 'lucide-react';
import { useMappings } from '../../hooks/useMappings';
import {
  TARGET_FIELD_DISPLAY_NAMES,
  isConceptMapping,
  isFormulaMapping,
  getCustomConcept,
  getFormulaExpression,
  type CustomXbrlConceptMapping,
} from '../../types/mappings';
import { MappingEditorModal } from './MappingEditorModal';

export const MappingsSettingsCard: React.FC = () => {
  const {
    mappings,
    isLoading,
    addMapping,
    updateMapping,
    deleteMapping,
    toggleMapping,
    importMappings,
    exportMappings,
  } = useMappings();

  const [editorOpen, setEditorOpen] = useState(false);
  const [editingMapping, setEditingMapping] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [operationError, setOperationError] = useState<string | null>(null);

  const handleAddNew = () => {
    setEditingMapping(null);
    setEditorOpen(true);
    setOperationError(null);
  };

  const handleEdit = (id: string) => {
    setEditingMapping(id);
    setEditorOpen(true);
    setOperationError(null);
  };

  const handleDelete = async (id: string) => {
    setOperationError(null);
    try {
      await deleteMapping(id);
      setSuccess('Mapping deleted successfully');
      setTimeout(() => setSuccess(null), 3000);
    } catch (e) {
      setOperationError(`Failed to delete mapping: ${(e as Error).message}`);
    }
  };

  const handleToggle = async (id: string) => {
    setOperationError(null);
    try {
      await toggleMapping(id);
    } catch (e) {
      setOperationError(`Failed to toggle mapping: ${(e as Error).message}`);
    }
  };

  const handleExport = async () => {
    setOperationError(null);
    try {
      const json = await exportMappings();
      const blob = new Blob([json], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `mappings-${new Date().toISOString().split('T')[0]}.json`;
      a.click();
      URL.revokeObjectURL(url);
      setSuccess('Mappings exported successfully');
      setTimeout(() => setSuccess(null), 3000);
    } catch (e) {
      setOperationError(`Failed to export mappings: ${(e as Error).message}`);
    }
  };

  const handleImport = () => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = 'application/json';
    input.onchange = async (e) => {
      const file = (e.target as HTMLInputElement).files?.[0];
      if (!file) return;

      setOperationError(null);
      try {
        const text = await file.text();
        await importMappings(text);
        setSuccess('Mappings imported successfully');
        setTimeout(() => setSuccess(null), 3000);
      } catch (e) {
        setOperationError(`Failed to import mappings: ${(e as Error).message}`);
      }
    };
    input.click();
  };

  return (
    <section className="rounded-lg bg-term-surface p-6 shadow-sm">
      {/* Header */}
      <div className="mb-6 flex items-start justify-between gap-4">
        <div className="flex-1">
          <div className="flex items-center gap-2">
            <h2 className="text-base font-mono font-semibold text-term-text">
              Custom XBRL Mappings
            </h2>
            <FolderOpen className="h-4 w-4 text-term-text-tertiary" />
          </div>
          <p className="mt-1.5 text-xs font-mono leading-6 text-term-text-muted">
            Define custom XBRL concepts to fill gaps where the standardized data loader misses data.
          </p>
        </div>
        <div className="flex gap-2">
          <button
            onClick={handleImport}
            className="inline-flex items-center gap-2 rounded border border-term-border bg-term-highlight px-3 py-2 text-xs font-mono text-term-text-muted transition-colors hover:border-term-border-focus hover:text-term-text"
            title="Import mappings from JSON file"
          >
            <FileUp className="h-3.5 w-3.5" />
            Import
          </button>
          <button
            onClick={handleExport}
            disabled={mappings.length === 0}
            className="inline-flex items-center gap-2 rounded border border-term-border bg-term-highlight px-3 py-2 text-xs font-mono text-term-text-muted transition-colors hover:border-term-border-focus hover:text-term-text disabled:cursor-not-allowed disabled:opacity-50"
            title="Export mappings to JSON file"
          >
            <FileDown className="h-3.5 w-3.5" />
            Export
          </button>
          <button
            onClick={handleAddNew}
            className="inline-flex items-center gap-2 rounded border border-[var(--term-status-info-border)] bg-[var(--term-status-info)] px-4 py-2 text-xs font-mono text-info transition-colors hover:brightness-110"
          >
            <Plus className="h-3.5 w-3.5" />
            Add Mapping
          </button>
        </div>
      </div>

      {/* Error/Success Messages */}
      {operationError && (
        <div className="mb-4 flex items-center gap-3 rounded-lg border border-[var(--term-status-error-border)] bg-[var(--term-status-error)] px-4 py-3 text-sm font-mono text-negative">
          {operationError}
        </div>
      )}

      {success && (
        <div className="mb-4 flex items-center gap-3 rounded-lg border border-[var(--term-status-success-border)] bg-[var(--term-status-success)] px-4 py-3 text-sm font-mono text-positive">
          {success}
        </div>
      )}

      {/* Loading State */}
      {isLoading ? (
        <div className="flex items-center justify-center py-12">
          <RefreshCw className="h-6 w-6 animate-spin text-term-text-tertiary" />
        </div>
      ) : mappings.length === 0 ? (
        /* Empty State */
        <div className="rounded border border-dashed border-term-border bg-term-bg px-6 py-12 text-center">
          <FolderOpen className="mx-auto h-12 w-12 text-term-text-tertiary" />
          <p className="mt-3 text-sm font-mono text-term-text-muted">No custom mappings defined yet.</p>
          <p className="mt-1 text-xs font-mono text-term-text-tertiary">
            Add a mapping to define custom XBRL concepts for specific tickers or time periods.
          </p>
        </div>
      ) : (
        /* Mappings List */
        <div className="space-y-3">
          {mappings.filter((mapping) => mapping != null).map((mapping) => (
            <MappingRow
              key={mapping.id}
              mapping={mapping}
              onEdit={() => handleEdit(mapping.id)}
              onDelete={() => handleDelete(mapping.id)}
              onToggle={() => handleToggle(mapping.id)}
            />
          ))}
        </div>
      )}

      {/* Editor Modal */}
      {editorOpen && (
        <MappingEditorModal
          mappingId={editingMapping}
          onClose={() => setEditorOpen(false)}
          onSave={async (mapping) => {
            setOperationError(null);
            try {
              if (editingMapping) {
                await updateMapping(editingMapping, mapping);
                setSuccess('Mapping updated successfully');
              } else {
                await addMapping(mapping);
                setSuccess('Mapping added successfully');
              }
              setTimeout(() => setSuccess(null), 3000);
              setEditorOpen(false);
            } catch (e) {
              setOperationError(`Failed to save mapping: ${e instanceof Error ? e.message : String(e)}`);
              throw e;
            }
          }}
        />
      )}
    </section>
  );
};

interface MappingRowProps {
  mapping: CustomXbrlConceptMapping;
  onEdit: () => void;
  onDelete: () => void;
  onToggle: () => void;
}

const MappingRow: React.FC<MappingRowProps> = ({ mapping, onEdit, onDelete, onToggle }) => {
  // Add defensive null/undefined checks
  if (!mapping) {
    console.error('[MappingRow] Received null or undefined mapping');
    return null;
  }

  const scope = (() => {
    if (!mapping.scope) {
      return 'Global';
    }
    if (mapping.scope.ticker) {
      if (mapping.scope.periodStart || mapping.scope.periodEnd) {
        const start = mapping.scope.periodStart || '...';
        const end = mapping.scope.periodEnd || '...';
        return `${mapping.scope.ticker} (${start} - ${end})`;
      }
      return mapping.scope.ticker;
    }
    return 'Global';
  })();

  let isFormula = false;
  let isConcept = false;

  try {
    isFormula = isFormulaMapping(mapping);
    isConcept = isConceptMapping(mapping);
  } catch (error) {
    console.error('[MappingRow] Error determining mapping type:', error, mapping);
  }

  const conceptOrFormula = (() => {
    try {
      if (isConcept) {
        const customConcept = getCustomConcept(mapping);
        return customConcept ? `${customConcept.taxonomy}:${customConcept.concept}` : 'Unknown';
      } else if (isFormula) {
        // Formula mapping
        return getFormulaExpression(mapping) || 'empty';
      }
      return 'Unknown';
    } catch (error) {
      console.error('[MappingRow] Error getting concept/formula:', error, mapping);
      return 'Error';
    }
  })();

  return (
    <article
      className={`rounded border transition-colors ${
        !mapping.enabled
          ? 'border-term-border bg-term-bg opacity-60'
          : 'border-term-border-subtle bg-term-surface'
      }`}
    >
      <div className="flex items-start justify-between gap-4 p-4">
        <div className="flex-1 min-w-0">
          {/* Header */}
          <div className="flex items-center gap-3">
            <h3 className="text-sm font-mono font-semibold text-term-text">
              {TARGET_FIELD_DISPLAY_NAMES[mapping.targetField as keyof typeof TARGET_FIELD_DISPLAY_NAMES] || mapping.targetField}
            </h3>
            <span
              className={`rounded px-2 py-0.5 text-[10px] font-mono uppercase tracking-wider ${
                mapping.enabled
                  ? 'border border-[var(--term-status-success-border)] bg-[var(--term-status-success)] text-positive'
                  : 'border border-term-border bg-term-highlight text-term-text-muted'
              }`}
            >
              {mapping.enabled ? 'Enabled' : 'Disabled'}
            </span>
          </div>

          {/* Concept/Formula and Scope */}
          <div className="mt-2 flex flex-wrap items-center gap-2 text-xs font-mono text-term-text-muted">
            {isFormula && (
              <div className="flex items-center gap-1 rounded border border-term-border-subtle bg-term-bg px-2 py-0.5">
                <FunctionSquare className="h-3 w-3 text-warning" />
                <code className="text-warning">{conceptOrFormula}</code>
              </div>
            )}
            {isConcept && (
              <code className="rounded border border-term-border-subtle bg-term-bg px-2 py-0.5 text-info">
                {conceptOrFormula}
              </code>
            )}
            <span className="text-term-text-tertiary">→</span>
            <span className="text-term-text">{scope}</span>
            {mapping.notes && (
              <>
                <span className="text-term-text-tertiary">•</span>
                <span className="text-term-text-tertiary italic" title={mapping.notes}>
                  {mapping.notes.length > 40 ? `${mapping.notes.slice(0, 40)}...` : mapping.notes}
                </span>
              </>
            )}
          </div>
        </div>

        {/* Actions */}
        <div className="flex items-center gap-1">
          <button
            onClick={onToggle}
            className="rounded border border-term-border bg-term-highlight p-2 text-term-text-muted transition-colors hover:border-term-border-focus hover:text-term-text"
            title={mapping.enabled ? 'Disable mapping' : 'Enable mapping'}
          >
            {mapping.enabled ? <Power className="h-3.5 w-3.5" /> : <PowerOff className="h-3.5 w-3.5" />}
          </button>
          <button
            onClick={onEdit}
            className="rounded border border-term-border bg-term-highlight p-2 text-term-text-muted transition-colors hover:border-info hover:text-info"
            title="Edit mapping"
          >
            <Edit2 className="h-3.5 w-3.5" />
          </button>
          <button
            onClick={onDelete}
            className="rounded border border-[var(--term-status-error-border)] bg-[var(--term-status-error)] p-2 text-negative transition-colors hover:border-negative hover:brightness-110"
            title="Delete mapping"
          >
            <Trash2 className="h-3.5 w-3.5" />
          </button>
        </div>
      </div>
    </article>
  );
};
