/**
 * 작업 이력 관리 서비스
 */

import pool from '../database/db';
import {
  WorkHistory,
  CreateWorkHistoryDto,
  UpdateWorkHistoryDto,
  WorkHistoryFilters,
  WorkHistoryStats,
  MonthlyTrend,
  TopRoute,
} from '../types/workHistory';

/**
 * 작업 이력 목록 조회
 */
export async function getWorkHistories(filters?: WorkHistoryFilters): Promise<WorkHistory[]> {
  try {
    let query = `
      SELECT * FROM work_history
      WHERE deleted_at IS NULL
    `;
    const params: (string | Date)[] = [];
    let paramIndex = 1;

    // 필터 적용
    if (filters?.work_type) {
      query += ` AND work_type = $${paramIndex}`;
      params.push(filters.work_type);
      paramIndex++;
    }

    if (filters?.status) {
      query += ` AND status = $${paramIndex}`;
      params.push(filters.status);
      paramIndex++;
    }

    if (filters?.vehicle_number) {
      query += ` AND vehicle_number LIKE $${paramIndex}`;
      params.push(`%${filters.vehicle_number}%`);
      paramIndex++;
    }

    if (filters?.driver_name) {
      query += ` AND driver_name LIKE $${paramIndex}`;
      params.push(`%${filters.driver_name}%`);
      paramIndex++;
    }

    if (filters?.start_date) {
      query += ` AND work_date >= $${paramIndex}`;
      params.push(filters.start_date);
      paramIndex++;
    }

    if (filters?.end_date) {
      query += ` AND work_date <= $${paramIndex}`;
      params.push(filters.end_date);
      paramIndex++;
    }

    if (filters?.search) {
      query += ` AND (
        work_number LIKE $${paramIndex} OR
        vehicle_number LIKE $${paramIndex} OR
        driver_name LIKE $${paramIndex} OR
        cargo_name LIKE $${paramIndex}
      )`;
      params.push(`%${filters.search}%`);
      paramIndex++;
    }

    query += ` ORDER BY work_date DESC`;

    const result: any = await pool.query(query, params);
    return result.rows;
  } catch (error) {
    console.error('작업 이력 조회 실패:', error);
    throw error;
  }
}

/**
 * 작업 이력 단건 조회
 */
export async function getWorkHistoryById(id: number): Promise<WorkHistory | null> {
  try {
    const result: any = await pool.query(
      'SELECT * FROM work_history WHERE id = $1 AND deleted_at IS NULL',
      [id]
    );
    return result.rows[0] || null;
  } catch (error) {
    console.error('작업 이력 조회 실패:', error);
    throw error;
  }
}

/**
 * 작업 이력 생성
 */
export async function createWorkHistory(data: CreateWorkHistoryDto): Promise<WorkHistory> {
  try {
    const result: any = await pool.query(
      `INSERT INTO work_history (
        work_type, vehicle_number, driver_name, origin, destination,
        cargo_name, cargo_weight, cargo_unit, distance, distance_unit,
        status, scheduled_time, estimated_arrival, notes, created_by
      ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
      RETURNING *`,
      [
        data.work_type,
        data.vehicle_number,
        data.driver_name,
        data.origin,
        data.destination,
        data.cargo_name,
        data.cargo_weight,
        data.cargo_unit || 'ton',
        data.distance,
        data.distance_unit || 'km',
        data.status || 'pending',
        data.scheduled_time,
        data.estimated_arrival,
        data.notes,
        data.created_by,
      ]
    );
    return result.rows[0];
  } catch (error) {
    console.error('작업 이력 생성 실패:', error);
    throw error;
  }
}

/**
 * 작업 이력 수정
 */
export async function updateWorkHistory(id: number, data: UpdateWorkHistoryDto): Promise<WorkHistory> {
  try {
    const fields: string[] = [];
    const values: any[] = [];
    let paramIndex = 1;

    Object.entries(data).forEach(([key, value]) => {
      if (value !== undefined) {
        fields.push(`${key} = $${paramIndex}`);
        values.push(value);
        paramIndex++;
      }
    });

    if (fields.length === 0) {
      throw new Error('수정할 데이터가 없습니다');
    }

    values.push(id);
    const query = `
      UPDATE work_history
      SET ${fields.join(', ')}
      WHERE id = $${paramIndex} AND deleted_at IS NULL
      RETURNING *
    `;

    const result: any = await pool.query(query, values);
    if (result.rows.length === 0) {
      throw new Error('작업 이력을 찾을 수 없습니다');
    }
    return result.rows[0];
  } catch (error) {
    console.error('작업 이력 수정 실패:', error);
    throw error;
  }
}

/**
 * 작업 이력 삭제 (소프트 삭제)
 */
export async function deleteWorkHistory(id: number): Promise<void> {
  try {
    const result: any = await pool.query(
      'UPDATE work_history SET deleted_at = CURRENT_TIMESTAMP WHERE id = $1 AND deleted_at IS NULL',
      [id]
    );
    if (result.rowCount === 0) {
      throw new Error('작업 이력을 찾을 수 없습니다');
    }
  } catch (error) {
    console.error('작업 이력 삭제 실패:', error);
    throw error;
  }
}

/**
 * 작업 이력 통계 조회
 */
export async function getWorkHistoryStats(): Promise<WorkHistoryStats> {
  try {
    // 오늘 작업 통계
    const todayResult: any = await pool.query(`
      SELECT 
        COUNT(*) as today_total,
        COUNT(*) FILTER (WHERE status = 'completed') as today_completed
      FROM work_history
      WHERE DATE(work_date) = CURRENT_DATE AND deleted_at IS NULL
    `);

    // 총 운송량 및 거리
    const totalResult: any = await pool.query(`
      SELECT 
        COALESCE(SUM(cargo_weight), 0) as total_weight,
        COALESCE(SUM(distance), 0) as total_distance
      FROM work_history
      WHERE deleted_at IS NULL AND status = 'completed'
    `);

    // 정시 도착률
    const onTimeResult: any = await pool.query(`
      SELECT 
        COUNT(*) FILTER (WHERE is_on_time = true) * 100.0 / NULLIF(COUNT(*), 0) as on_time_rate
      FROM work_history
      WHERE deleted_at IS NULL 
        AND status = 'completed' 
        AND is_on_time IS NOT NULL
    `);

    // 작업 유형별 분포
    const typeResult: any = await pool.query(`
      SELECT 
        work_type,
        COUNT(*) as count
      FROM work_history
      WHERE deleted_at IS NULL
      GROUP BY work_type
    `);

    const typeDistribution = {
      inbound: 0,
      outbound: 0,
      transfer: 0,
      maintenance: 0,
    };

    typeResult.rows.forEach((row: any) => {
      typeDistribution[row.work_type as keyof typeof typeDistribution] = parseInt(row.count);
    });

    return {
      today_total: parseInt(todayResult.rows[0].today_total),
      today_completed: parseInt(todayResult.rows[0].today_completed),
      total_weight: parseFloat(totalResult.rows[0].total_weight),
      total_distance: parseFloat(totalResult.rows[0].total_distance),
      on_time_rate: parseFloat(onTimeResult.rows[0]?.on_time_rate || '0'),
      type_distribution: typeDistribution,
    };
  } catch (error) {
    console.error('작업 이력 통계 조회 실패:', error);
    throw error;
  }
}

/**
 * 월별 추이 조회
 */
export async function getMonthlyTrend(months: number = 6): Promise<MonthlyTrend[]> {
  try {
    const result: any = await pool.query(
      `
      SELECT 
        TO_CHAR(work_date, 'YYYY-MM') as month,
        COUNT(*) as total,
        COUNT(*) FILTER (WHERE status = 'completed') as completed,
        COALESCE(SUM(cargo_weight), 0) as weight,
        COALESCE(SUM(distance), 0) as distance
      FROM work_history
      WHERE deleted_at IS NULL
        AND work_date >= CURRENT_DATE - INTERVAL '${months} months'
      GROUP BY TO_CHAR(work_date, 'YYYY-MM')
      ORDER BY month DESC
      `,
      []
    );

    return result.rows.map((row: any) => ({
      month: row.month,
      total: parseInt(row.total),
      completed: parseInt(row.completed),
      weight: parseFloat(row.weight),
      distance: parseFloat(row.distance),
    }));
  } catch (error) {
    console.error('월별 추이 조회 실패:', error);
    throw error;
  }
}

/**
 * 주요 운송 경로 조회
 */
export async function getTopRoutes(limit: number = 5): Promise<TopRoute[]> {
  try {
    const result: any = await pool.query(
      `
      SELECT 
        origin,
        destination,
        COUNT(*) as count,
        COALESCE(SUM(cargo_weight), 0) as total_weight
      FROM work_history
      WHERE deleted_at IS NULL
        AND origin IS NOT NULL
        AND destination IS NOT NULL
        AND work_type IN ('inbound', 'outbound', 'transfer')
      GROUP BY origin, destination
      ORDER BY count DESC
      LIMIT $1
      `,
      [limit]
    );

    return result.rows.map((row: any) => ({
      origin: row.origin,
      destination: row.destination,
      count: parseInt(row.count),
      total_weight: parseFloat(row.total_weight),
    }));
  } catch (error) {
    console.error('주요 운송 경로 조회 실패:', error);
    throw error;
  }
}

