/**
 * QM Filings Actions - Fetch and update SEC filings
 */

import type { ExecutionContext } from '@stock-bot/handlers';
import type { QMHandler } from '../qm.handler';
import { QM_CONFIG, QM_SESSION_IDS } from '../shared/config';
import { QMSessionManager } from '../shared/session-manager';

/**
 * Update filings for a single symbol
 */
export async function updateFilings(
  this: QMHandler,
  input: {
    symbol: string;
    exchange: string;
    lastRecordDate?: Date | null;
    qmSearchCode: string;
    page: number;
    totalPages?: number;
  },
  _context?: ExecutionContext
): Promise<{
  success: boolean;
  symbol: string;
  message: string;
  data?: any;
}> {
  const { qmSearchCode, page, symbol, exchange, lastRecordDate, totalPages } = input;
  
  this.logger.info(`Fetching filings ${qmSearchCode} - ${page}/${totalPages}`, { qmSearchCode, page });

  const sessionManager = QMSessionManager.getInstance();
  await sessionManager.initialize(this.cache, this.logger);

  // Get a session - you'll need to add the appropriate session ID for filings
  const sessionId = QM_SESSION_IDS.LOOKUP; // TODO: Update with correct session ID
  const session = await sessionManager.getSession(sessionId);
  
  if (!session || !session.uuid) {
    throw new Error(`No active session found for QM filings`);
  }

  try {
    // Build API request for filings
    const searchParams = new URLSearchParams({
      // symbol: qmSearchCode,
      // webmasterId: "500",
      // page: page ? page.toString() : "1",
      // xbrlSubDoc: "true",
      // inclIxbrl: "true",
      // inclXbrl: "true",
      // resultsPerPage: "25",
      webmasterId: "500",
      token: session.headers['Datatool-Token'] || '',
    });

    delete session?.headers?.["Datatool-Token"]
    
    const formData = new FormData();
    formData.append('symbol', qmSearchCode);
    formData.append('inclXbrl', 'true');
    formData.append('inclIxbrl', 'true');
    formData.append('oldestFilingYear', 'true');
    formData.append('resultsPerPage', '25');
    formData.append('page', page ? page.toString() : '1');
    formData.append('xbrlSubDoc', 'true');

    // https://app.quotemedia.com/data/getCompanyFilings.json?page=1&webmasterId=500&symbol=AAPL&xbrlSubDoc=true&inclIxbrl=true&inclXbrl=true&resultsPerPage=25
    
    // TODO: Update with correct filings endpoint
    const apiUrl = `${QM_CONFIG.FILING_URL}?${searchParams.toString()}`;

    console.log('Fetching filings from:', apiUrl, formData, session.headers);

    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: session.headers,
      proxy: session.proxy,
      body: formData,
    });

    if (!response.ok) {
      throw new Error(`QM API request failed: ${response.status} ${response.statusText}`);
    }

    const filingsData = await response.json();

    if( parseInt(filingsData.results.pagenumber) * filingsData.results.count >= filingsData.results.totalCount) {
      await this.scheduleOperation('update-filings', {
        symbol: symbol,
        exchange: exchange,
        qmSearchCode: qmSearchCode,
        lastRecordDate: lastRecordDate || null,
        page: parseInt(filingsData.results.pagenumber) + 1,
        totalPages: (filingsData.results.totalCount / filingsData.results.count) + 1
      }, {
        priority: 5, // Lower priority than financial data
      });
    }
    
    // Update session success stats
    await sessionManager.incrementSuccessfulCalls(sessionId, session.uuid);

    // Process and store filings data
    if (filingsData?.results?.filings?.filing[0] && filingsData.results.filings.filing[0] > 0) {
      // Store filings in a separate collection
      await this.mongodb.batchUpsert(
        'qmFilings',
        filingsData.results.filings.filing[0].map((filing: any) => ({
          ...filing,
          symbol,
          exchange,
        })),
        ['qmSearchCode', 'filingId'] // Unique keys
      );

      // Update symbol to track last filings update
      await this.operationRegistry.updateOperation('qm', qmSearchCode, 'filings_update', {
        status: 'success',
        lastRecordDate: new Date(),
        recordCount: filingsData.length
      });

      this.logger.info(`Filings updated successfully ${qmSearchCode} - ${page}/${totalPages}`, { 
        qmSearchCode,
        page,
        totalPages,
        filingsCount: filingsData.length
      });

      return {
        success: true,
        symbol,
        message: `Filings updated for ${symbol}`,
        data: { count: filingsData.length }
      };
    } else {
      // Some symbols may not have filings (non-US companies, etc)
      await this.operationRegistry.updateOperation('qm', qmSearchCode, 'filings_update', {
        status: 'success',
        lastRecordDate: new Date(),
        recordCount: 0
      });

      this.logger.info('No filings found for symbol', { symbol });
      return {
        success: true,
        symbol,
        message: `No filings found for ${symbol}`,
        data: { count: 0 }
      };
    }

  } catch (error) {
    // Update session failure stats
    if (session.uuid) {
      await sessionManager.incrementFailedCalls(sessionId, session.uuid);
    }

    this.logger.error('Error fetching filings', { 
      symbol,
      error: error instanceof Error ? error.message : 'Unknown error'
    });
    
    // Track failure
    await this.operationRegistry.updateOperation('qm', qmSearchCode, 'filings_update', {
      status: 'failure'
    });
    
    return {
      success: false,
      symbol,
      message: `Failed to fetch filings: ${error instanceof Error ? error.message : 'Unknown error'}`
    };
  }
}

/**
 * Schedule filings updates for symbols that need refreshing
 */
export async function scheduleFilingsUpdates(
  this: QMHandler,
  input: {
    limit?: number;
    forceUpdate?: boolean;
  } = {},
  _context?: ExecutionContext
): Promise<{
  message: string;
  symbolsQueued: number;
  errors: number;
}> {
  const { limit = 1, forceUpdate = false } = input;
  
  this.logger.info('Scheduling filings updates', { limit, forceUpdate });

  try {
    // Get symbols that need updating
    // const staleSymbols = await this.operationRegistry.getStaleSymbols('qm', 'filings_update', {
    //   minHoursSinceRun: forceUpdate ? 0 : 24, // Daily for filings
    //   limit
    // });

    const staleSymbols = ['AAPL']

    if (staleSymbols.length === 0) {
      this.logger.info('No symbols need filings updates');
      return {
        message: 'No symbols need filings updates',
        symbolsQueued: 0,
        errors: 0
      };
    }

    this.logger.info(`Found ${staleSymbols.length} symbols needing filings updates`);

    // Get full symbol data to include symbolId
    const symbolDocs = await this.mongodb.find('qmSymbols', {
      qmSearchCode: { $in: staleSymbols }
    }, {
      projection: { qmSearchCode: 1, operations: 1, symbol: 1, exchange: 1 }
    });

    let queued = 0;
    let errors = 0;

    // Schedule individual update jobs for each symbol
    for (const doc of symbolDocs) {
      try {
        await this.scheduleOperation('update-filings', {
          symbol: doc.symbol,
          exchange: doc.exchange,
          qmSearchCode: doc.qmSearchCode,
          lastRecordDate: doc.operations?.filings_update?.lastRecordDate || null,
        }, {
          priority: 5, // Lower priority than financial data
        });
        
        queued++;
      } catch (error) {
        this.logger.error(`Failed to schedule filings update for ${doc.symbol}`, { error });
        errors++;
      }
    }

    this.logger.info('Filings update scheduling completed', {
      symbolsQueued: queued,
      errors,
      total: staleSymbols.length
    });

    return {
      message: `Scheduled filings updates for ${queued} symbols`,
      symbolsQueued: queued,
      errors
    };
  } catch (error) {
    this.logger.error('Filings scheduling failed', { error });
    throw error;
  }
}