// Sites table query functions - Direct PostgreSQL access

import { pool } from '@/lib/db';
import type { Site, FilterOptions, PaginationResult } from './types';
import { buildWhere, buildSearch, buildPagination, buildUpdateSet, getSingleResult, isValidUUID } from './utils';

/**
 * Get all sites with optional filtering and pagination
 */
export async function getSites(options: FilterOptions = {}): Promise<PaginationResult<Site>> {
    const { limit = 50, offset = 0, status, search } = options;

    let sql = 'SELECT * FROM sites WHERE 1=1';
    const params: any[] = [];
    let paramIndex = 1;

    // Add status filter
    if (status) {
        sql += ` AND status = $${paramIndex++}`;
        params.push(status);
    }

    // Add search filter
    if (search) {
        const [searchSql, searchParam] = buildSearch('domain', search, paramIndex++);
        sql += searchSql;
        params.push(searchParam);
    }

    // Add pagination
    const [paginationSql, safeLimit, safeOffset] = buildPagination(limit, offset, paramIndex);
    sql += ' ORDER BY created_at DESC' + paginationSql;
    params.push(safeLimit, safeOffset);

    // Execute query
    const { rows } = await pool.query<Site>(sql, params);

    // Get total count
    const countSql = 'SELECT COUNT(*) FROM sites WHERE 1=1' +
        (status ? ' AND status = $1' : '');
    const countParams = status ? [status] : [];
    const { rows: countRows } = await pool.query<{ count: string }>(countSql, countParams);
    const total = parseInt(countRows[0]?.count || '0');

    return {
        data: rows,
        total,
        limit: safeLimit,
        offset: safeOffset,
        hasMore: safeOffset + rows.length < total
    };
}

/**
 * Get single site by ID
 */
export async function getSiteById(id: string): Promise<Site | null> {
    if (!isValidUUID(id)) {
        throw new Error('Invalid site ID format');
    }

    const { rows } = await pool.query<Site>(
        'SELECT * FROM sites WHERE id = $1',
        [id]
    );
    return getSingleResult(rows);
}

/**
 * Get site by domain
 */
export async function getSiteByDomain(domain: string): Promise<Site | null> {
    const { rows } = await pool.query<Site>(
        'SELECT * FROM sites WHERE domain = $1',
        [domain]
    );
    return getSingleResult(rows);
}

/**
 * Create new site with Zod validation
 * Ensures data integrity and schema compliance
 */
export async function createSite(data: unknown): Promise<Site> {
    // Import here to avoid circular dependency
    const { SiteSchema, validateForCreate } = await import('./schemas');

    // 1. Validate input (throws error if invalid)
    const validatedData = validateForCreate(SiteSchema, data, 'Site');

    // 2. Execute SQL with clean, validated data
    const { rows } = await pool.query<Site>(
        `INSERT INTO sites (domain, status, site_url, site_wpjson)
     VALUES ($1, $2, $3, $4)
     RETURNING *`,
        [
            validatedData.domain,
            validatedData.status,
            validatedData.site_url || '',
            validatedData.site_wpjson || ''
        ]
    );

    if (rows.length === 0) {
        throw new Error('Failed to create site');
    }

    return rows[0];
}

/**
 * Update existing site with Zod validation
 * Validates partial updates before SQL execution
 */
export async function updateSite(id: string, data: unknown): Promise<Site> {
    if (!isValidUUID(id)) {
        throw new Error('Invalid site ID format');
    }

    // Import here to avoid circular dependency
    const { PartialSiteSchema, validateForUpdate } = await import('./schemas');

    // 1. Validate partial update data
    const validatedData = validateForUpdate(
        PartialSiteSchema,
        { ...(data as Record<string, any>), id },
        'Site'
    );

    // 2. Build UPDATE query from validated data
    const [setClause, values] = buildUpdateSet(validatedData);
    values.push(id);

    // 3. Execute SQL
    const { rows } = await pool.query<Site>(
        `UPDATE sites SET ${setClause}, updated_at = NOW()
     WHERE id = $${values.length}
     RETURNING *`,
        values
    );

    if (rows.length === 0) {
        throw new Error('Site not found');
    }

    return rows[0];
}

/**
 * Delete site
 */
export async function deleteSite(id: string): Promise<boolean> {
    if (!isValidUUID(id)) {
        throw new Error('Invalid site ID format');
    }

    const result = await pool.query('DELETE FROM sites WHERE id = $1', [id]);
    return result.rowCount ? result.rowCount > 0 : false;
}

/**
 * Get sites count by status
 */
export async function getSitesCountByStatus(): Promise<Record<string, number>> {
    const { rows } = await pool.query<{ status: string; count: string }>(
        'SELECT status, COUNT(*) as count FROM sites GROUP BY status'
    );

    return rows.reduce((acc, row) => {
        acc[row.status] = parseInt(row.count);
        return acc;
    }, {} as Record<string, number>);
}
