/**
 * TrusteeExpenseImportView
 * 
 * Setup page for automatic expense import from SharePoint PDFs.
 * Allows users to connect their Microsoft account, select a SharePoint folder,
 * and activate daily automation for expense extraction.
 */

import React, { useState, useEffect, useCallback } from 'react';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import { useConnections } from '../../../hooks/useConnections';
import { useToast } from '../../../contexts/ToastContext';
import api from '../../../api';
import styles from './TrusteeViews.module.css';

// Default extraction prompt (from automation template)
const DEFAULT_EXTRACTION_PROMPT = `Du bist ein Spezialist für die Extraktion von Spesendaten aus PDF-Dokumenten.

AUFGABE:
Extrahiere alle Speseneinträge aus dem bereitgestellten PDF-Dokument und gib sie im CSV-Format zurück.

WICHTIGE REGELN:
1. Pro MwSt-Prozentsatz einen separaten Datensatz erstellen
2. Alle Datensätze zusammen müssen den Gesamtbetrag des Dokuments ergeben
3. Der gesamte extrahierte Text des Dokuments muss im Feld "desc" erfasst werden
4. Feld "company" enthält den Lieferanten/Verkäufer der Buchung
5. Tags müssen aus dieser Liste gewählt werden: customer, meeting, license, subscription, fuel, food, material
   - Mehrere zutreffende Tags mit Komma trennen

CSV-SPALTEN (in dieser Reihenfolge):
valuta,transactionDateTime,company,desc,tags,bookingCurrency,bookingAmount,originalCurrency,originalAmount,vatPercentage,vatAmount

DATENFORMAT:
- valuta: YYYY-MM-DD (Valutadatum)
- transactionDateTime: Unix-Timestamp in Sekunden (Transaktionszeitpunkt)
- company: Lieferant/Verkäufer Name
- desc: Vollständiger extrahierter Text des Dokuments
- tags: Komma-getrennte Tags aus der erlaubten Liste
- bookingCurrency: Währungscode (CHF, EUR, USD, GBP)
- bookingAmount: Buchungsbetrag als Dezimalzahl
- originalCurrency: Original-Währungscode
- originalAmount: Original-Betrag als Dezimalzahl
- vatPercentage: MwSt-Prozentsatz (z.B. 8.1 für 8.1%)
- vatAmount: MwSt-Betrag als Dezimalzahl

HINWEISE:
- Wenn nur ein MwSt-Satz vorhanden ist, einen Datensatz erstellen
- Wenn mehrere MwSt-Sätze vorhanden sind, separate Datensätze erstellen
- Bei fehlenden Informationen: leeres Feld oder Standardwert`;

interface SiteOption {
  value: string;
  label: string;
  siteId: string;
  siteName: string;
  webUrl: string;
  path: string;
}

interface FolderOption {
  value: string;
  label: string;
  siteId: string;
  folderName: string;
  path: string;
}

interface Connection {
  id: string;
  type?: string;
  authority: string;
  status: string;
  externalUsername?: string;
  accountName?: string;  // Legacy fallback
}

interface ExistingAutomation {
  id: string;
  label: string;
  active: boolean;
  schedule: string;
  placeholders: Record<string, string>;
}

// Helper function to safely convert error detail to string
const parseErrorDetail = (detail: any): string => {
  if (typeof detail === 'string') return detail;
  if (Array.isArray(detail)) {
    // FastAPI validation errors come as array of {type, loc, msg, input}
    return detail.map(e => e.msg || JSON.stringify(e)).join(', ');
  }
  if (typeof detail === 'object' && detail !== null) {
    return detail.msg || detail.message || JSON.stringify(detail);
  }
  return String(detail);
};

export const TrusteeExpenseImportView: React.FC = () => {
  // Use instanceId/mandateId from URL params (always available)
  const { instanceId, mandateId } = useCurrentInstance();
  const { connections, createMicrosoftConnectionAndAuth, fetchConnections } = useConnections();
  const { showSuccess, showError } = useToast();
  
  const [msftConnections, setMsftConnections] = useState<Connection[]>([]);
  const [msftConnection, setMsftConnection] = useState<Connection | null>(null);
  const [siteOptions, setSiteOptions] = useState<SiteOption[]>([]);
  const [folderOptions, setFolderOptions] = useState<FolderOption[]>([]);
  const [selectedSite, setSelectedSite] = useState<SiteOption | null>(null);
  const [currentPath, setCurrentPath] = useState<string>('');
  const [selectedFolder, setSelectedFolder] = useState<string>('');
  const [isLoadingSites, setIsLoadingSites] = useState(false);
  const [isLoadingFolders, setIsLoadingFolders] = useState(false);
  const [isActivating, setIsActivating] = useState(false);
  const [isConnecting, setIsConnecting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [successMessage, setSuccessMessage] = useState<string | null>(null);
  const [existingAutomation, setExistingAutomation] = useState<ExistingAutomation | null>(null);
  const [isLoadingAutomation, setIsLoadingAutomation] = useState(true);
  const [showInfoTooltip, setShowInfoTooltip] = useState(false);
  
  // Find all active Microsoft connections
  useEffect(() => {
    const msftConns = connections.filter((c: Connection) => 
      (c.type === 'msft' || c.authority === 'msft') && c.status === 'active'
    );
    setMsftConnections(msftConns);
    
    // Auto-select if only one connection
    if (msftConns.length === 1) {
      setMsftConnection(msftConns[0]);
    } else if (msftConns.length === 0) {
      setMsftConnection(null);
    }
    // Note: When multiple connections exist, user must select manually
  }, [connections]);
  
  // Load existing automation for this feature instance
  useEffect(() => {
    const loadExistingAutomation = async () => {
      if (!instanceId) return;
      
      setIsLoadingAutomation(true);
      try {
        // Fetch all automations and filter client-side
        const response = await api.get('/api/automations');
        
        const automations = response.data?.items || response.data?.data || response.data || [];
        // Find automation by label AND featureInstanceId
        const expenseAutomation = automations.find((a: any) => 
          a.label === 'Expense Import' && a.featureInstanceId === instanceId
        );
        
        if (expenseAutomation) {
          setExistingAutomation({
            id: expenseAutomation.id,
            label: expenseAutomation.label,
            active: expenseAutomation.active,
            schedule: expenseAutomation.schedule,
            placeholders: expenseAutomation.placeholders || {}
          });
          // Pre-fill selected folder from existing automation
          if (expenseAutomation.placeholders?.sharepointFolder) {
            setSelectedFolder(expenseAutomation.placeholders.sharepointFolder);
          }
        }
      } catch (err) {
        console.error('Failed to load existing automation:', err);
      } finally {
        setIsLoadingAutomation(false);
      }
    };
    
    loadExistingAutomation();
  }, [instanceId]);
  
  // Pre-select connection from existing automation when connections are loaded
  useEffect(() => {
    if (!existingAutomation || msftConnections.length === 0 || msftConnection) return;
    
    // Try to match connection from existing automation placeholders
    // Format: "connection:msft:externalUsername" or just the connection ID
    const savedConnectionRef = existingAutomation.placeholders?.connectionName || '';
    
    // Try to find matching connection by externalUsername, accountName, or id
    const matchingConn = msftConnections.find(c => 
      savedConnectionRef.includes(c.externalUsername || '') || 
      savedConnectionRef.includes(c.accountName || '') || 
      savedConnectionRef.includes(c.id)
    );
    
    if (matchingConn) {
      setMsftConnection(matchingConn);
    } else if (msftConnections.length === 1) {
      // Fallback to single connection
      setMsftConnection(msftConnections[0]);
    }
  }, [existingAutomation, msftConnections, msftConnection]);
  
  // Load SharePoint sites when connected
  const loadSiteOptions = useCallback(async () => {
    if (!msftConnection) return;
    
    setIsLoadingSites(true);
    setError(null);
    
    try {
      const response = await api.get(`/api/sharepoint/${msftConnection.id}/folder-options`);
      setSiteOptions(response.data || []);
    } catch (err: any) {
      console.error('Failed to load sites:', err);
      setError(parseErrorDetail(err.response?.data?.detail) || 'Failed to load SharePoint sites');
      setSiteOptions([]);
    } finally {
      setIsLoadingSites(false);
    }
  }, [msftConnection]);
  
  // Load folders when site is selected
  const loadFolderOptions = useCallback(async (siteId: string, path: string = '') => {
    if (!msftConnection || !siteId) return;
    
    setIsLoadingFolders(true);
    setError(null);
    
    try {
      const params = new URLSearchParams({ siteId });
      if (path) params.append('path', path);
      
      const response = await api.get(`/api/sharepoint/${msftConnection.id}/folder-options?${params}`);
      setFolderOptions(response.data || []);
    } catch (err: any) {
      console.error('Failed to load folders:', err);
      setError(parseErrorDetail(err.response?.data?.detail) || 'Failed to load folders');
      setFolderOptions([]);
    } finally {
      setIsLoadingFolders(false);
    }
  }, [msftConnection]);
  
  useEffect(() => {
    if (msftConnection) {
      loadSiteOptions();
    }
  }, [msftConnection, loadSiteOptions]);
  
  // Load root folders when site changes
  useEffect(() => {
    if (selectedSite) {
      setCurrentPath('');
      setSelectedFolder('');
      loadFolderOptions(selectedSite.siteId, '');
    }
  }, [selectedSite, loadFolderOptions]);
  
  const handleSiteChange = (siteId: string) => {
    const site = siteOptions.find(s => s.siteId === siteId);
    setSelectedSite(site || null);
  };
  
  const handleFolderNavigate = (folder: FolderOption) => {
    const newPath = folder.path;
    setCurrentPath(newPath);
    loadFolderOptions(selectedSite!.siteId, newPath);
  };
  
  const handleFolderSelect = (folder: FolderOption) => {
    // Build full path: /sites/SiteName/FolderPath
    const fullPath = `${selectedSite?.path || ''}/${folder.path}`;
    setSelectedFolder(fullPath);
  };
  
  const handleGoUp = () => {
    if (!currentPath) return;
    const parts = currentPath.split('/');
    parts.pop();
    const parentPath = parts.join('/');
    setCurrentPath(parentPath);
    loadFolderOptions(selectedSite!.siteId, parentPath);
  };
  
  const handleConnect = async () => {
    setIsConnecting(true);
    setError(null);
    
    try {
      await createMicrosoftConnectionAndAuth();
      await fetchConnections();
    } catch (err: any) {
      console.error('Connection failed:', err);
      setError(err.message || 'Microsoft connection failed');
    } finally {
      setIsConnecting(false);
    }
  };
  
  const handleSave = async (activate: boolean = true) => {
    // Validate required fields with user feedback
    if (!msftConnection) {
      showError('Missing Connection', 'Please select a Microsoft connection first.');
      return;
    }
    if (!selectedFolder) {
      showError('Missing Folder', 'Please select a SharePoint folder first.');
      return;
    }
    if (!instanceId || !mandateId) {
      showError('Error', 'Feature instance not found. Please refresh the page.');
      return;
    }
    
    setIsActivating(true);
    setError(null);
    setSuccessMessage(null);
    
    try {
      const connectionReference = `connection:msft:${msftConnection.externalUsername || msftConnection.accountName || msftConnection.id}`;
      
      const automationData = {
        label: 'Expense Import',
        schedule: '0 22 * * *',  // Daily at 22:00
        template: JSON.stringify({
          overview: "Expenses PDF to Trustee Position",
          tasks: [{
            id: "Task01",
            title: "Extract Expenses from SharePoint PDFs",
            description: "Automatic expense extraction",
            objective: "Extract expense data from PDF documents",
            actionList: [{
              execMethod: "sharepoint",
              execAction: "getExpensesFromPdf",
              execParameters: {
                connectionReference: connectionReference,
                sharepointFolder: selectedFolder,
                featureInstanceId: instanceId,
                prompt: DEFAULT_EXTRACTION_PROMPT
              },
              execResultLabel: "expense_extraction_result"
            }]
          }]
        }),
        placeholders: {
          connectionName: connectionReference,
          sharepointFolder: selectedFolder,
          featureInstanceId: instanceId
        },
        active: activate,
        mandateId: mandateId,
        featureInstanceId: instanceId
      };
      
      let response;
      if (existingAutomation) {
        // Update existing automation
        response = await api.put(`/api/automations/${existingAutomation.id}`, {
          ...automationData,
          id: existingAutomation.id,
          mandateId: mandateId
        });
        const msg = activate 
          ? 'Expense import automation updated and activated!' 
          : 'Expense import automation updated and deactivated.';
        setSuccessMessage(msg);
        showSuccess('Success', msg);
      } else {
        // Create new automation
        response = await api.post('/api/automations', automationData);
        const msg = 'Expense import automation created and activated! It will run daily at 22:00.';
        setSuccessMessage(msg);
        showSuccess('Success', msg);
      }
      
      // Update local state with response
      const savedAutomation = response.data;
      setExistingAutomation({
        id: savedAutomation.id,
        label: savedAutomation.label,
        active: savedAutomation.active,
        schedule: savedAutomation.schedule,
        placeholders: savedAutomation.placeholders || {}
      });
      
    } catch (err: any) {
      console.error('Save failed:', err);
      const errorMsg = parseErrorDetail(err.response?.data?.detail) || err.message || 'Failed to save automation';
      setError(errorMsg);
      showError('Error', errorMsg);
    } finally {
      setIsActivating(false);
    }
  };
  
  const handleDeactivate = async () => {
    if (!existingAutomation) return;
    
    setIsActivating(true);
    setError(null);
    
    try {
      // Use dedicated PATCH endpoint for status changes
      await api.patch(`/api/automations/${existingAutomation.id}/status`, {
        active: false
      });
      
      setExistingAutomation(prev => prev ? { ...prev, active: false } : null);
      setSuccessMessage('Expense import automation deactivated.');
      showSuccess('Deactivated', 'Expense import automation deactivated.');
    } catch (err: any) {
      console.error('Deactivation failed:', err);
      const errorMsg = parseErrorDetail(err.response?.data?.detail) || err.message || 'Failed to deactivate automation';
      setError(errorMsg);
      showError('Error', errorMsg);
    } finally {
      setIsActivating(false);
    }
  };
  
  return (
    <div className={styles.listView}>
      <div className={styles.expenseImportSection}>
        <h3 className={styles.sectionTitle}>Expense Import Setup</h3>
        <p className={styles.sectionDescription}>
          Connect your Microsoft account and select a SharePoint folder containing expense PDFs.
          The system will automatically extract expense data daily and save it as positions.
          <span 
            className={styles.infoIcon}
            onMouseEnter={() => setShowInfoTooltip(true)}
            onMouseLeave={() => setShowInfoTooltip(false)}
            onClick={() => setShowInfoTooltip(!showInfoTooltip)}
            title="How it works"
          >
            ⓘ
          </span>
          {showInfoTooltip && (
            <span className={styles.infoTooltip}>
              <strong>How it works:</strong>
              <ul>
                <li>Place expense PDF documents (receipts, invoices) in the selected SharePoint folder</li>
                <li>The system runs daily at 22:00 and processes all PDF files</li>
                <li>AI extracts expense data: date, amount, VAT, company, description</li>
                <li>Each expense is saved as a position in this Trustee instance</li>
                <li>Processed PDFs are moved to a "processed" subfolder</li>
                <li>Failed PDFs are moved to an "error" subfolder</li>
                <li>Maximum 50 PDFs are processed per run</li>
              </ul>
            </span>
          )}
        </p>
        
        {error && (
          <div className={styles.errorMessage}>
            {error}
          </div>
        )}
        
        {successMessage && (
          <div className={styles.successMessage}>
            {successMessage}
          </div>
        )}
        
        {/* Current Status */}
        {!isLoadingAutomation && existingAutomation && (
          <div className={existingAutomation.active ? styles.successMessage : styles.infoBox} style={{ marginBottom: '1rem' }}>
            <strong>Current Status:</strong> {existingAutomation.active ? '✓ Active' : '○ Inactive'}
            {existingAutomation.placeholders?.sharepointFolder && (
              <><br />Folder: {existingAutomation.placeholders.sharepointFolder}</>
            )}
          </div>
        )}
        
        {/* Step 1: Microsoft Connection */}
        <div className={styles.setupStep}>
          <div className={styles.stepNumber}>1</div>
          <div className={styles.stepContent}>
            <h4>Microsoft Connection</h4>
            {msftConnections.length === 0 ? (
              // No connections - show connect button
              <button 
                className={styles.primaryButton}
                onClick={handleConnect}
                disabled={isConnecting}
              >
                {isConnecting ? 'Connecting...' : 'Connect Microsoft Account'}
              </button>
            ) : msftConnections.length === 1 ? (
              // Single connection - show as connected
              <div className={styles.connectionStatus}>
                <span className={styles.connectedIcon}>✓</span>
                <span className={styles.connectedText}>
                  Connected as <strong>{msftConnections[0].accountName || 'Microsoft Account'}</strong>
                </span>
              </div>
            ) : (
              // Multiple connections - show dropdown
              <>
                <select
                  className={styles.folderSelect}
                  value={msftConnection?.id || ''}
                  onChange={(e) => {
                    const conn = msftConnections.find(c => c.id === e.target.value);
                    setMsftConnection(conn || null);
                    // Reset site/folder selection when connection changes
                    setSelectedSite(null);
                    setSiteOptions([]);
                    setFolderOptions([]);
                    setSelectedFolder('');
                  }}
                >
                  <option value="">Select a Microsoft account...</option>
                  {msftConnections.map((conn) => (
                    <option key={conn.id} value={conn.id}>
                      {conn.accountName || conn.id}
                    </option>
                  ))}
                </select>
                <button 
                  className={styles.secondaryButton}
                  onClick={handleConnect}
                  disabled={isConnecting}
                  style={{ marginTop: '0.5rem' }}
                >
                  {isConnecting ? 'Connecting...' : 'Add another account'}
                </button>
              </>
            )}
          </div>
        </div>
        
        {/* Step 2: SharePoint Site Selection */}
        {msftConnection && (
          <div className={styles.setupStep}>
            <div className={styles.stepNumber}>2</div>
            <div className={styles.stepContent}>
              <h4>SharePoint Site</h4>
              {isLoadingSites ? (
                <div className={styles.loadingText}>Loading sites...</div>
              ) : (
                <select
                  className={styles.folderSelect}
                  value={selectedSite?.siteId || ''}
                  onChange={(e) => handleSiteChange(e.target.value)}
                >
                  <option value="">Select a site...</option>
                  {siteOptions.map((site) => (
                    <option key={site.siteId} value={site.siteId}>
                      {site.label}
                    </option>
                  ))}
                </select>
              )}
            </div>
          </div>
        )}
        
        {/* Step 3: Folder Selection */}
        {selectedSite && (
          <div className={styles.setupStep}>
            <div className={styles.stepNumber}>3</div>
            <div className={styles.stepContent}>
              <h4>Expense Folder</h4>
              <p className={styles.activateDescription}>
                Current path: <strong>{selectedSite.path}/{currentPath || '(root)'}</strong>
              </p>
              {isLoadingFolders ? (
                <div className={styles.loadingText}>Loading folders...</div>
              ) : (
                <div className={styles.folderBrowser}>
                  <div style={{ display: 'flex', gap: '0.5rem', marginBottom: '0.5rem' }}>
                    {currentPath && (
                      <button 
                        className={styles.secondaryButton}
                        onClick={handleGoUp}
                      >
                        ↑ Go Up
                      </button>
                    )}
                    <button 
                      className={styles.primaryButton}
                      onClick={() => {
                        // Select the current folder path
                        const fullPath = `${selectedSite?.path || ''}/${currentPath || ''}`.replace(/\/+$/, '');
                        setSelectedFolder(fullPath || selectedSite?.path || '');
                      }}
                    >
                      ✓ Select This Folder
                    </button>
                  </div>
                  <div className={styles.folderList}>
                    {folderOptions.map((folder) => (
                      <div key={folder.value} className={styles.folderItem}>
                        <span 
                          className={styles.folderName}
                          onClick={() => handleFolderNavigate(folder)}
                          style={{ cursor: 'pointer', flex: 1 }}
                        >
                          📁 {folder.label}
                        </span>
                        <button
                          className={styles.selectButton}
                          onClick={() => handleFolderSelect(folder)}
                        >
                          Select
                        </button>
                      </div>
                    ))}
                    {folderOptions.length === 0 && (
                      <div className={styles.emptyText}>No subfolders found</div>
                    )}
                  </div>
                  {selectedFolder && (
                    <p className={styles.selectedFolderText}>
                      Selected: <strong>{selectedFolder}</strong>
                    </p>
                  )}
                </div>
              )}
            </div>
          </div>
        )}
        
        {/* Step 4: Save & Activate */}
        {selectedFolder && (
          <div className={styles.setupStep}>
            <div className={styles.stepNumber}>4</div>
            <div className={styles.stepContent}>
              <h4>{existingAutomation ? 'Update Configuration' : 'Activate Daily Import'}</h4>
              <p className={styles.activateDescription}>
                PDF files in <strong>{selectedFolder}</strong> will be processed daily at 22:00.
                Successfully processed files will be moved to a "processed" subfolder.
              </p>
              <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
                <button
                  className={styles.primaryButton}
                  onClick={() => handleSave(true)}
                  disabled={isActivating}
                >
                  {isActivating ? 'Saving...' : (existingAutomation ? 'Save & Activate' : 'Activate Daily Import')}
                </button>
                {existingAutomation && existingAutomation.active && (
                  <button
                    className={styles.secondaryButton}
                    onClick={handleDeactivate}
                    disabled={isActivating}
                  >
                    Deactivate
                  </button>
                )}
              </div>
            </div>
          </div>
        )}
        
      </div>
    </div>
  );
};

export default TrusteeExpenseImportView;
