const representAPI = require('../services/represent-api');
const nocoDB = require('../services/nocodb');

// Helper function to cache representatives
async function cacheRepresentatives(postalCode, representatives, representData) {
  try {
    // Cache the postal code info
    await nocoDB.storePostalCodeInfo({
      postal_code: postalCode,
      city: representData.city,
      province: representData.province
    });
    
    // Cache representatives using the existing method
    const result = await nocoDB.storeRepresentatives(postalCode, representatives);
    
    if (result.success) {
      console.log(`Successfully cached ${result.count} representatives for ${postalCode}`);
    } else {
      console.log(`Partial success caching representatives for ${postalCode}: ${result.error || 'unknown error'}`);
    }
  } catch (error) {
    console.log(`Failed to cache representatives for ${postalCode}:`, error.message);
    // Don't throw - caching is optional and should never break the main flow
  }
}

class RepresentativesController {
  async testConnection(req, res, next) {
    try {
      const result = await representAPI.testConnection();
      res.json(result);
    } catch (error) {
      console.error('Test connection error:', error);
      res.status(500).json({ 
        error: 'Failed to test connection',
        message: error.message 
      });
    }
  }

  async getByPostalCode(req, res, next) {
    try {
      const { postalCode } = req.params;
      const formattedPostalCode = postalCode.replace(/\s/g, '').toUpperCase();
      
      // Try to check cached data first, but don't fail if NocoDB is down
      let cachedData = [];
      try {
        cachedData = await nocoDB.getRepresentativesByPostalCode(formattedPostalCode);
        console.log(`Cache check for ${formattedPostalCode}: found ${cachedData.length} records`);
        
        if (cachedData && cachedData.length > 0) {
          return res.json({
            success: true,
            source: 'Local Cache',
            data: {
              postalCode: formattedPostalCode,
              location: {
                city: cachedData[0]?.city || 'Alberta',
                province: 'AB'
              },
              representatives: cachedData
            }
          });
        }
      } catch (cacheError) {
        console.log(`Cache unavailable for ${formattedPostalCode}, proceeding with API call:`, cacheError.message);
      }

          // If not in cache, fetch from Represent API
    console.log(`Fetching representatives from Represent API for ${postalCode}`);
    const representData = await representAPI.getRepresentativesByPostalCode(postalCode);
    
    if (!representData) {
      return res.json({
        success: false,
        message: 'No data found for this postal code',
        data: {
          postalCode,
          location: null,
          representatives: []
        }
      });
    }

    // Process representatives from both concordance and centroid
    let representatives = [];
    
    // Add concordance representatives (if any)
    if (representData.boundaries_concordance && representData.boundaries_concordance.length > 0) {
      representatives = representatives.concat(representData.boundaries_concordance);
    }
    
    // Add centroid representatives (if any) - these are the actual elected officials
    if (representData.representatives_centroid && representData.representatives_centroid.length > 0) {
      representatives = representatives.concat(representData.representatives_centroid);
    }

    // Representatives already include office information, no need for additional API calls
    console.log('Using representatives data with existing office information');
    
    console.log(`Representatives concordance count: ${representData.boundaries_concordance ? representData.boundaries_concordance.length : 0}`);
    console.log(`Representatives centroid count: ${representData.representatives_centroid ? representData.representatives_centroid.length : 0}`);
    console.log(`Total representatives found: ${representatives.length}`);
    
    if (representatives.length === 0) {
      return res.json({
        success: false,
        message: 'No representatives found for this postal code',
        data: {
          postalCode,
          location: {
            city: representData.city,
            province: representData.province
          },
          representatives: []
        }
      });
    }
    
    // Try to cache the results (will fail gracefully if NocoDB is down)
    console.log(`Attempting to cache ${representatives.length} representatives for ${postalCode}`);
    await cacheRepresentatives(postalCode, representatives, representData);
    
    res.json({
      success: true,
      source: 'Open North',
      data: {
        postalCode,
        location: {
          city: representData.city,
          province: representData.province
        },
        representatives
      }
    });
    } catch (error) {
      console.error('Get representatives error:', error);
      res.status(500).json({
        error: 'Failed to fetch representatives',
        message: error.message
      });
    }
  }

  async refreshPostalCode(req, res, next) {
    try {
      const { postalCode } = req.params;
      const formattedPostalCode = postalCode.replace(/\s/g, '').toUpperCase();

      // Clear cached data
      await nocoDB.clearRepresentativesByPostalCode(formattedPostalCode);
      
      // Fetch fresh data from API
      const representData = await representAPI.getRepresentativesByPostalCode(formattedPostalCode);
      
      if (!representData || !representData.representatives_concordance) {
        return res.status(404).json({
          error: 'No representatives found for this postal code',
          postalCode: formattedPostalCode
        });
      }

      // Cache the fresh results
      await nocoDB.storeRepresentatives(formattedPostalCode, representData.representatives_concordance);
      
      res.json({
        source: 'Open North',
        postalCode: formattedPostalCode,
        representatives: representData.representatives_concordance,
        city: representData.city,
        province: representData.province
      });
    } catch (error) {
      console.error('Refresh representatives error:', error);
      res.status(500).json({
        error: 'Failed to refresh representatives',
        message: error.message
      });
    }
  }

  async trackCall(req, res, next) {
    try {
      const {
        representativeName,
        representativeTitle,
        phoneNumber,
        officeType,
        userEmail,
        userName,
        postalCode
      } = req.body;

      // Validate required fields
      if (!representativeName || !phoneNumber) {
        return res.status(400).json({
          success: false,
          error: 'Representative name and phone number are required'
        });
      }

      // Log the call
      await nocoDB.logCall({
        representativeName,
        representativeTitle: representativeTitle || null,
        phoneNumber,
        officeType: officeType || null,
        callerName: userName || null,
        callerEmail: userEmail || null,
        postalCode: postalCode || null,
        campaignId: null,
        campaignSlug: null,
        callerIP: req.ip || req.connection?.remoteAddress || null,
        timestamp: new Date().toISOString()
      });

      res.json({
        success: true,
        message: 'Call tracked successfully'
      });
    } catch (error) {
      console.error('Track call error:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to track call',
        message: error.message
      });
    }
  }
}

module.exports = new RepresentativesController();