import { NextRequest, NextResponse } from 'next/server';
import { Pool } from 'pg';
import { getAddigyClient } from '@/lib/services/addigy-factory';
import { AddigyOrgMapping } from '@/lib/types/addigy';

const pool = new Pool({
  host: process.env.POSTGRES_HOST,
  port: parseInt(process.env.POSTGRES_PORT || '5432'),
  database: process.env.POSTGRES_DB,
  user: process.env.POSTGRES_USER,
  password: process.env.POSTGRES_PASSWORD,
});

export async function GET(request: NextRequest) {
  try {
    const searchParams = request.nextUrl.searchParams;
    const includeUnmapped = searchParams.get('includeUnmapped') === 'true';

    // Get all mappings from database
    const result = await pool.query<{
      id: number;
      addigy_org_id: string;
      addigy_org_name: string;
      autotask_company_id: number;
      autotask_company_name: string;
      created_at: string;
      updated_at: string;
    }>('SELECT * FROM addigy_org_mappings ORDER BY addigy_org_name');

    const mappings: AddigyOrgMapping[] = result.rows.map((row) => ({
      id: row.id,
      addigyOrgId: row.addigy_org_id,
      addigyOrgName: row.addigy_org_name,
      autotaskCompanyId: row.autotask_company_id,
      autotaskCompanyName: row.autotask_company_name,
      createdAt: row.created_at,
      updatedAt: row.updated_at,
    }));

    // If includeUnmapped is true, fetch all Addigy policies (which act as organizations/sites) and merge
    if (includeUnmapped) {
      try {
        const addigyClient = getAddigyClient();
        // In Addigy, policies are the grouping mechanism (like sites/organizations)
        const allPolicies = await addigyClient.getAllPolicies();
        
        const mappedOrgIds = new Set(mappings.map((m) => m.addigyOrgId));
        
        const unmappedOrgs = allPolicies
          .filter((policy) => !mappedOrgIds.has(policy.policyId))
          .map((policy) => ({
            id: 0, // Temporary ID for unmapped
            addigyOrgId: policy.policyId,
            addigyOrgName: policy.name,
            autotaskCompanyId: 0,
            autotaskCompanyName: '',
            createdAt: '',
            updatedAt: '',
          }));

        return NextResponse.json({
          mappings: [...mappings, ...unmappedOrgs],
          totalMapped: mappings.length,
          totalUnmapped: unmappedOrgs.length,
        });
      } catch (addigyError) {
        // If Addigy API fails, just return the mapped organizations
        console.warn('Failed to fetch unmapped Addigy policies:', addigyError);
        return NextResponse.json({
          mappings: mappings,
          totalMapped: mappings.length,
          totalUnmapped: 0,
          warning: 'Could not fetch unmapped policies from Addigy API. Check API configuration.',
        });
      }
    }

    return NextResponse.json({ mappings });
  } catch (error) {
    console.error('Error fetching Addigy org mappings:', error);
    return NextResponse.json(
      { error: 'Failed to fetch Addigy org mappings' },
      { status: 500 }
    );
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const {
      addigyOrgId,
      addigyOrgName,
      autotaskCompanyId,
      autotaskCompanyName,
    } = body;

    if (!addigyOrgId || !autotaskCompanyId) {
      return NextResponse.json(
        { error: 'Missing required fields' },
        { status: 400 }
      );
    }

    // Insert or update mapping
    const result = await pool.query<{
      id: number;
      addigy_org_id: string;
      addigy_org_name: string;
      autotask_company_id: number;
      autotask_company_name: string;
      created_at: string;
      updated_at: string;
    }>(
      `INSERT INTO addigy_org_mappings 
        (addigy_org_id, addigy_org_name, autotask_company_id, autotask_company_name)
       VALUES ($1, $2, $3, $4)
       ON CONFLICT (addigy_org_id) 
       DO UPDATE SET 
         autotask_company_id = EXCLUDED.autotask_company_id,
         autotask_company_name = EXCLUDED.autotask_company_name,
         updated_at = CURRENT_TIMESTAMP
       RETURNING *`,
      [addigyOrgId, addigyOrgName, autotaskCompanyId, autotaskCompanyName]
    );

    const mapping: AddigyOrgMapping = {
      id: result.rows[0].id,
      addigyOrgId: result.rows[0].addigy_org_id,
      addigyOrgName: result.rows[0].addigy_org_name,
      autotaskCompanyId: result.rows[0].autotask_company_id,
      autotaskCompanyName: result.rows[0].autotask_company_name,
      createdAt: result.rows[0].created_at,
      updatedAt: result.rows[0].updated_at,
    };

    return NextResponse.json({ mapping });
  } catch (error) {
    console.error('Error creating Addigy org mapping:', error);
    return NextResponse.json(
      { error: 'Failed to create Addigy org mapping' },
      { status: 500 }
    );
  }
}

export async function DELETE(request: NextRequest) {
  try {
    const searchParams = request.nextUrl.searchParams;
    const id = searchParams.get('id');

    if (!id) {
      return NextResponse.json(
        { error: 'Missing mapping ID' },
        { status: 400 }
      );
    }

    await pool.query('DELETE FROM addigy_org_mappings WHERE id = $1', [
      parseInt(id),
    ]);

    return NextResponse.json({ success: true });
  } catch (error) {
    console.error('Error deleting Addigy org mapping:', error);
    return NextResponse.json(
      { error: 'Failed to delete Addigy org mapping' },
      { status: 500 }
    );
  }
}
