import { NextRequest, NextResponse } from 'next/server';
import { getAutotaskClient } from '@/lib/services/autotask-factory';
import { getDattoRMMClient } from '@/lib/services/datto-rmm-factory';
import { getAuvikClient } from '@/lib/services/auvik-factory';
import { ConfigurationItem } from '@/lib/types/autotask';
import { DattoRMMDevice } from '@/lib/types/datto-rmm';
import { AuvikDevice } from '@/lib/types/auvik';
import { postgresClient } from '@/lib/services/postgres-client';

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const { id } = await params;
    const searchParams = request.nextUrl.searchParams;
    const type = searchParams.get('type') || 'autotask';

    let autotaskDevice: ConfigurationItem | null = null;
    let rmmDevice: DattoRMMDevice | null = null;
    let auvikDevice: AuvikDevice | null = null;
    let companyName: string | null = null;

    if (type === 'autotask') {
      // Fetch Autotask configuration item
      const autotaskClient = getAutotaskClient();
      autotaskDevice = await autotaskClient.getConfigurationItemById(parseInt(id));
      
      if (autotaskDevice) {
        // Get company name
        const company = await autotaskClient.getCompanyById(autotaskDevice.companyID);
        companyName = company?.companyName || null;
        
        // Try to find matching RMM device
        console.log('Looking for RMM device for Autotask item:', {
          id: autotaskDevice.id,
          companyID: autotaskDevice.companyID,
          companyName: companyName,
          rmmDeviceUID: autotaskDevice.rmmDeviceUID,
          rmmDeviceID: autotaskDevice.rmmDeviceID,
          serialNumber: autotaskDevice.serialNumber,
          hostname: autotaskDevice.rmmDeviceAuditHostname
        });
        
        try {
          const rmmClient = getDattoRMMClient();
          const devices = await rmmClient.getAllDevices();
          console.log(`Fetched ${devices.length} RMM devices for matching`);
          
          // First priority: Match by RMM Device UID if available
          if (autotaskDevice?.rmmDeviceUID) {
            rmmDevice = devices.find(d => d.uid === autotaskDevice?.rmmDeviceUID) || null;
            if (rmmDevice) {
              console.log('Matched by RMM UID:', rmmDevice.uid);
            } else {
              console.log(`No match found for UID: ${autotaskDevice.rmmDeviceUID}`);
              // Check if device exists with similar UID
              const similarDevices = devices.filter(d => d.uid && d.uid.includes('3dfd7b06'));
              console.log(`Devices with similar UID:`, similarDevices.map(d => ({ uid: d.uid, hostname: d.hostname })));
            }
          }
          
          // Second priority: Match by serial number
          if (!rmmDevice && autotaskDevice?.serialNumber) {
            rmmDevice = devices.find(d => 
              d.serialNumber?.toLowerCase() === autotaskDevice?.serialNumber?.toLowerCase()
            ) || null;
            if (rmmDevice) {
              console.log('Matched by serial number:', rmmDevice.serialNumber);
            }
          }
          
          // Third priority: Match by hostname
          if (!rmmDevice && autotaskDevice?.rmmDeviceAuditHostname) {
            rmmDevice = devices.find(d => 
              d.hostname?.toLowerCase() === autotaskDevice?.rmmDeviceAuditHostname?.toLowerCase()
            ) || null;
            if (rmmDevice) console.log('Matched by hostname within company');
          }
          
          if (!rmmDevice) {
            console.log('No RMM device match found');
          } else {
            console.log('Found RMM device:', {
              id: rmmDevice.id,
              uid: rmmDevice.uid,
              hostname: rmmDevice.hostname,
              siteName: rmmDevice.siteName
            });
            
            // Try to get additional audit data for more detailed information
            try {
              const deviceWithAudit = await rmmClient.getDeviceWithAudit(rmmDevice.id);
              if (deviceWithAudit) {
                rmmDevice = deviceWithAudit;
                console.log('Enhanced device with audit data');
              }
            } catch (err) {
              console.log('Could not fetch audit data:', err);
            }
          }
        } catch (err) {
          console.error('Failed to fetch RMM device:', err);
        }

        // Try to find matching Auvik device using tenant mappings
        if (autotaskDevice && autotaskDevice.companyID) {
          try {
            const auvikClient = getAuvikClient();
            
            // First, check if there's a tenant mapping for this company
            const mappingQuery = `
              SELECT auvik_tenant_id, auvik_tenant_name 
              FROM auvik_tenant_mappings 
              WHERE autotask_company_id = $1
            `;
            const mappingResult = await postgresClient.query<{
              auvik_tenant_id: string;
              auvik_tenant_name: string;
            }>(mappingQuery, [autotaskDevice.companyID]);

            let auvikDevices: AuvikDevice[] = [];

            if (mappingResult.rows.length > 0) {
              // Use the mapped tenant
              const mapping = mappingResult.rows[0];
              console.log(`Found Auvik tenant mapping: ${mapping.auvik_tenant_name} for company ID: ${autotaskDevice.companyID}`);
              auvikDevices = await auvikClient.getDevicesByTenant(mapping.auvik_tenant_id);
            } else if (companyName) {
              // Fallback to name-based matching
              console.log(`No mapping found, trying name match for: ${companyName}`);
              const tenant = await auvikClient.findTenantByName(companyName);
              if (tenant) {
                console.log(`Found Auvik tenant by name: ${tenant.domainPrefix} for company: ${companyName}`);
                auvikDevices = await auvikClient.getDevicesByTenant(tenant.id);
              }
            }

            // Match Auvik device to Autotask configuration item
            if (auvikDevices.length > 0) {
              // Priority 1: Match by serial number
              if (autotaskDevice.serialNumber) {
                auvikDevice = auvikDevices.find(d => 
                  d.serialNumber?.toLowerCase() === autotaskDevice?.serialNumber?.toLowerCase()
                ) || null;
                if (auvikDevice) {
                  console.log('Matched Auvik device by serial number:', auvikDevice.serialNumber);
                }
              }

              // Priority 2: Match by hostname
              if (!auvikDevice && autotaskDevice.rmmDeviceAuditHostname) {
                auvikDevice = auvikDevices.find(d => 
                  d.deviceName?.toLowerCase().includes(autotaskDevice?.rmmDeviceAuditHostname?.toLowerCase() || '')
                ) || null;
                if (auvikDevice) {
                  console.log('Matched Auvik device by hostname:', auvikDevice.deviceName);
                }
              }

              // Priority 3: Match by IP address
              if (!auvikDevice && autotaskDevice.rmmDeviceAuditIPAddress) {
                auvikDevice = auvikDevices.find(d => 
                  d.ipAddresses?.includes(autotaskDevice?.rmmDeviceAuditIPAddress || '')
                ) || null;
                if (auvikDevice) {
                  console.log('Matched Auvik device by IP address:', auvikDevice.ipAddresses);
                }
              }

              if (!auvikDevice) {
                console.log('No Auvik device match found for configuration item');
              }
            }
          } catch (err) {
            console.error('Failed to fetch Auvik device:', err);
          }
        }
      }
    } else if (type === 'rmm') {
      // Fetch RMM device
      try {
        const rmmClient = getDattoRMMClient();
        rmmDevice = await rmmClient.getDeviceById(id);
        
        if (rmmDevice) {
          // Try to find matching Autotask device
          const autotaskClient = getAutotaskClient();
          const configItems = await autotaskClient.getAllConfigurationItems();
          autotaskDevice = configItems.find(ci => 
            ci.rmmDeviceUID === rmmDevice?.uid ||
            ci.serialNumber === rmmDevice?.serialNumber
          ) || null;
          
          if (autotaskDevice) {
            const company = await autotaskClient.getCompanyById(autotaskDevice.companyID);
            companyName = company?.companyName || null;
          }
        }
      } catch (err) {
        console.error('Failed to fetch RMM device:', err);
      }
    }

    return NextResponse.json({
      autotaskDevice,
      rmmDevice,
      auvikDevice,
      companyName
    });
  } catch (error) {
    console.error('Error fetching configuration item:', error);
    return NextResponse.json(
      { error: 'Failed to fetch configuration item details' },
      { status: 500 }
    );
  }
}

export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const { id } = await params;
    const body = await request.json();
    const idNum = parseInt(id);
    
    const autotaskClient = getAutotaskClient();
    const updatedItem = await autotaskClient.updateConfigurationItem(idNum, body);
    
    return NextResponse.json({
      configurationItem: updatedItem,
      message: 'Configuration item updated successfully'
    });
  } catch (error) {
    console.error('Error updating configuration item:', error);
    return NextResponse.json(
      { error: 'Failed to update configuration item' },
      { status: 500 }
    );
  }
}
