import express from 'express';
import mysql from 'mysql2/promise';
import cors from 'cors';
import dotenv from 'dotenv';

dotenv.config();

const app = express();
const PORT = process.env.PORT || 3000;

app.use(cors());
app.use(express.json({ limit: '50mb' }));

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASS,
  database: process.env.DB_NAME,
  port: parseInt(process.env.DB_PORT || '3306'),
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

// 테이블 존재 여부 확인 및 자동 생성
async function ensureTables() {
  const connection = await pool.getConnection();
  try {
    await connection.query(`
      CREATE TABLE IF NOT EXISTS cloud_assets (
        id VARCHAR(50) PRIMARY KEY,
        platform_name VARCHAR(100),
        corp VARCHAR(100),
        dept VARCHAR(100),
        product_name VARCHAR(255),
        account_name VARCHAR(255),
        pay_method VARCHAR(100),
        pay_day VARCHAR(50),
        card_num VARCHAR(100),
        monthly_fee VARCHAR(100),
        remarks TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);
    await connection.query(`
      CREATE TABLE IF NOT EXISTS asset_logs (
        id INT AUTO_INCREMENT PRIMARY KEY, asset_id VARCHAR(50), log_date VARCHAR(50),
        log_user VARCHAR(100), details TEXT, cost DECIMAL(15,2) DEFAULT 0
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);
    await connection.query(`
      CREATE TABLE IF NOT EXISTS pc_assets (
        id VARCHAR(50) PRIMARY KEY, corp VARCHAR(100), asset_code VARCHAR(100), purchase_date VARCHAR(50), 
        type VARCHAR(50), detail_purpose VARCHAR(100), purpose VARCHAR(255), details TEXT,
        current_org VARCHAR(100), prev_org VARCHAR(100), location VARCHAR(255), 
        manager_main VARCHAR(100), manager_sub VARCHAR(100), ip_address VARCHAR(50),
        remote_tool VARCHAR(100), server_id VARCHAR(100), server_pw VARCHAR(100), 
        model_name VARCHAR(255), mainboard VARCHAR(255), os VARCHAR(100), cpu VARCHAR(100), ram VARCHAR(100), gpu VARCHAR(100),
        storage1 VARCHAR(100), storage2 VARCHAR(100), storage3 VARCHAR(100), monitoring VARCHAR(100), price VARCHAR(100), remarks TEXT,
        storage_location VARCHAR(255), status VARCHAR(50)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);
    // 다른 하드웨어 테이블들도 동일한 스키마로 생성 (서버, 스토리지, 비품, 모바일)
    for (const table of ['server_assets', 'storage_assets', 'equip_assets', 'mobile_assets']) {
      await connection.query(`CREATE TABLE IF NOT EXISTS ${table} LIKE pc_assets`);
    }

    await connection.query(`
      CREATE TABLE IF NOT EXISTS sw_sub_assets (
        id VARCHAR(50) PRIMARY KEY, corp VARCHAR(100), 
        category VARCHAR(100), dept VARCHAR(100), product_name VARCHAR(255),
        license_type VARCHAR(100), quantity INT, price VARCHAR(100), purchase_date VARCHAR(50), 
        start_date VARCHAR(50), expiry_date VARCHAR(50), vendor VARCHAR(100), remarks TEXT
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);
    await connection.query(`
      CREATE TABLE IF NOT EXISTS sw_perm_assets (
        id VARCHAR(50) PRIMARY KEY, corp VARCHAR(100), 
        category VARCHAR(100), dept VARCHAR(100), product_name VARCHAR(255),
        license_key VARCHAR(255), quantity INT, price VARCHAR(100), purchase_date VARCHAR(50), 
        start_date VARCHAR(50), expiry_date VARCHAR(50), vendor VARCHAR(100), remarks TEXT
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);
    await connection.query(`
      CREATE TABLE IF NOT EXISTS asset_logs (
        id INT AUTO_INCREMENT PRIMARY KEY, asset_id VARCHAR(50), log_date VARCHAR(50),
        log_user VARCHAR(100), details TEXT, cost DECIMAL(15,2) DEFAULT 0
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);
    await connection.query(`
      CREATE TABLE IF NOT EXISTS sw_users (
        id INT AUTO_INCREMENT PRIMARY KEY, sw_id VARCHAR(50), corp VARCHAR(100), dept VARCHAR(100),
        position VARCHAR(100), user_name VARCHAR(100), usage_period VARCHAR(255), doc_name VARCHAR(255)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);
    await connection.query(`
      CREATE TABLE IF NOT EXISTS ops_domain_assets (
        id VARCHAR(50) PRIMARY KEY, type VARCHAR(50), corp VARCHAR(100), 
        service_name VARCHAR(255), domain_name VARCHAR(255), start_date VARCHAR(50), 
        expiry_date VARCHAR(50), price VARCHAR(100), manager_main VARCHAR(100), 
        manager_sub VARCHAR(100), remarks TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `);

    console.log('✅ All ITAM tables ensured.');
  } finally {
    connection.release();
  }
}

// 공통 배치 저장 로직
async function batchSave(tableName, assets, getQuery) {
  const connection = await pool.getConnection();
  try {
    await connection.beginTransaction();
    await connection.query(`DELETE FROM ${tableName}`);
    if (assets.length > 0) {
      const { sql, values } = getQuery(assets);
      await connection.query(sql, [values]);
    }
    await connection.commit();
    return { success: true, count: assets.length };
  } catch (err) {
    await connection.rollback();
    throw err;
  } finally {
    connection.release();
  }
}

// 하드웨어 쿼리 헬퍼
const hardwareInsertSQL = (table) => `
  INSERT INTO ${table} (
    id, corp, asset_code, purchase_date, type, detail_purpose, purpose, details,
    current_org, prev_org, location, manager_main, manager_sub, ip_address,
    remote_tool, server_id, server_pw, model_name, mainboard, os, cpu, ram, gpu,
    storage1, storage2, storage3, monitoring, price, remarks,
    storage_location, status
  ) VALUES ?
`;

const getHardwareValues = (a) => [
  a.id, a.법인||'', a.자산코드||'', a.구매연월||'', a.type||'', a.상세용도||'', a.용도||'', a.상세||'',
  a.현사용조직||'', a.이전사용조직||'', a.위치||'', a.담당자_정||'', a.담당자_부||'', a.IP주소||'',
  a.원격접속||'', a.서버ID||'', a.서버PW||'', a.모델명||'', a.메인보드||'', a.OS||'', a.CPU||'', a.RAM||'', a.GPU||'',
  a.SSD1||'', a.SSD2||'', a.HDD1||'', a.모니터링||'', a.금액||'', a.비고||'',
  a.보관위치||'', a.현재상태||''
];

const mapHardware = (r, defaultType) => {
  const type = r.type || defaultType;
  return {
    id: r.id, 
    법인: r.corp, 
    자산코드: r.asset_code, 
    구매연월: r.purchase_date, 
    구매일: r.purchase_date,
    type: type,
    상세용도: (type !== '개인PC' && !r.detail_purpose) ? type : r.detail_purpose,
    용도: r.purpose, 
    상세: r.details, 
    현사용조직: r.current_org,
    이전사용조직: r.prev_org, 
    위치: r.location, 
    담당자_정: r.manager_main, 
    담당자_부: r.manager_sub,
    IP주소: r.ip_address, 
    원격접속: r.remote_tool, 
    서버ID: r.server_id, 
    서버PW: r.server_pw,
    모델명: r.model_name, 
    메인보드: r.mainboard,
    OS: r.os, 
    CPU: r.cpu, 
    RAM: r.ram, 
    GPU: r.gpu, 
    SSD1: r.storage1,
    SSD2: r.storage2, 
    HDD1: r.storage3, 
    모니터링: r.monitoring, 
    금액: r.price, 
    비고: r.remarks,
    보관위치: r.storage_location, 
    현재상태: r.status
  };
};

// --- API 라우트 정의 ---

// PC API
app.get('/api/pc', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM pc_assets');
    console.log('🔍 DB Raw Rows (PC):', rows.length, 'items found.');
    if (rows.length > 0) console.log('🔍 First row sample:', rows[0]);
    res.json(rows.map(r => mapHardware(r, '개인PC')));
  } catch (err) { 
    console.error('❌ DB Query Error (PC):', err.message);
    res.status(500).json({ error: err.message }); 
  }
});

app.post('/api/pc/batch', async (req, res) => {
  try {
    const result = await batchSave('pc_assets', req.body, (assets) => ({
      sql: hardwareInsertSQL('pc_assets'),
      values: assets.map(getHardwareValues)
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 서버 API
app.get('/api/server', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM server_assets');
    res.json(rows.map(r => mapHardware(r, '서버')));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/server/batch', async (req, res) => {
  try {
    const result = await batchSave('server_assets', req.body, (assets) => ({
      sql: hardwareInsertSQL('server_assets'),
      values: assets.map(getHardwareValues)
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 스토리지 API
app.get('/api/storage', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM storage_assets');
    res.json(rows.map(r => mapHardware(r, '스토리지')));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/storage/batch', async (req, res) => {
  try {
    const result = await batchSave('storage_assets', req.body, (assets) => ({
      sql: hardwareInsertSQL('storage_assets'),
      values: assets.map(getHardwareValues)
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 전산비품 API
app.get('/api/equip', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM equip_assets');
    res.json(rows.map(r => mapHardware(r, '전산비품')));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/equip/batch', async (req, res) => {
  try {
    const result = await batchSave('equip_assets', req.body, (assets) => ({
      sql: hardwareInsertSQL('equip_assets'),
      values: assets.map(getHardwareValues)
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 모바일 API
app.get('/api/mobile', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM mobile_assets');
    res.json(rows.map(r => mapHardware(r, '모바일기기')));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/mobile/batch', async (req, res) => {
  try {
    const result = await batchSave('mobile_assets', req.body, (assets) => ({
      sql: hardwareInsertSQL('mobile_assets'),
      values: assets.map(getHardwareValues)
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 구독 SW API
app.get('/api/sw/sub', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM sw_sub_assets');
    res.json(rows.map(r => ({
      id: r.id, type: '구독SW', 법인: r.corp, 
      분야: r.category, 부서: r.dept, 제품명: r.product_name,
      라이선스유형: r.license_type, 수량: r.quantity, 금액: r.price, 
      구매일: r.purchase_date, 시작일: r.start_date, 만료일: r.expiry_date, 
      납품업체: r.vendor, 비고: r.remarks
    })));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/sw/sub/batch', async (req, res) => {
  try {
    const result = await batchSave('sw_sub_assets', req.body, (assets) => ({
      sql: `INSERT INTO sw_sub_assets (id, corp, category, dept, product_name, license_type, quantity, price, purchase_date, start_date, expiry_date, vendor, remarks) VALUES ?`,
      values: assets.map(a => [
        a.id, a.법인||'', a.분야||'', a.부서||'', a.제품명||'', 
        a.라이선스유형||'', a.수량||0, a.금액||'', a.구매일||'', a.시작일||'', a.만료일||'', a.납품업체||'', a.비고||''
      ])
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 영구 SW API
app.get('/api/sw/perm', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM sw_perm_assets');
    res.json(rows.map(r => ({
      id: r.id, type: '영구SW', 법인: r.corp, 
      분야: r.category, 부서: r.dept, 제품명: r.product_name,
      라이선스키: r.license_key, 수량: r.quantity, 금액: r.price, 
      구매일: r.purchase_date, 시작일: r.start_date, 만료일: r.expiry_date,
      납품업체: r.vendor, 비고: r.remarks
    })));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/sw/perm/batch', async (req, res) => {
  try {
    console.log('📦 Permanent SW Batch Save Request:', req.body.length, 'items');
    if (req.body.length > 0) console.log('Sample:', req.body[0]);
    const result = await batchSave('sw_perm_assets', req.body, (assets) => ({
      sql: `INSERT INTO sw_perm_assets (id, corp, category, dept, product_name, license_key, quantity, price, purchase_date, start_date, expiry_date, vendor, remarks) VALUES ?`,
      values: assets.map(a => [
        a.id, a.법인||'', a.분야||'', a.부서||'', a.제품명||'', 
        a.라이선스키||'', a.수량||0, a.금액||'', a.구매일||'', a.시작일||'', a.만료일||'', a.납품업체||'', a.비고||''
      ])
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 클라우드 API
app.get('/api/cloud', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM cloud_assets');
    res.json(rows.map(r => ({
      id: r.id, type: '클라우드', 플랫폼명: r.platform_name, 법인: r.corp, 부서: r.dept,
      제품명: r.product_name, 계정명: r.account_name, 결제수단: r.pay_method,
      결제일: r.pay_day, 연결카드번호: r.card_num, 당월청구액: r.monthly_fee, 비고: r.remarks
    })));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/cloud/batch', async (req, res) => {
  try {
    const result = await batchSave('cloud_assets', req.body, (assets) => ({
      sql: `INSERT INTO cloud_assets (id, platform_name, corp, dept, product_name, account_name, pay_method, pay_day, card_num, monthly_fee, remarks) VALUES ?`,
      values: assets.map(a => [a.id, a.플랫폼명||'', a.법인||'', a.부서||'', a.제품명||'', a.계정명||'', a.결제수단||'', a.결제일||'', a.연결카드번호||'', a.당월청구액||'', a.비고||''])
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 로그 API
app.get('/api/logs', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM asset_logs ORDER BY log_date DESC');
    res.json(rows.map(r => ({
      id: r.id, assetId: r.asset_id, date: r.log_date, user: r.log_user, details: r.details, cost: r.cost
    })));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/logs/batch', async (req, res) => {
  try {
    const result = await batchSave('asset_logs', req.body, (logs) => ({
      sql: `INSERT INTO asset_logs (asset_id, log_date, log_user, details, cost) VALUES ?`,
      values: logs.map(l => [l.assetId, l.date, l.user, l.details, l.cost || 0])
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// SW 사용자 API
app.get('/api/sw-users', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM sw_users');
    const grouped = rows.reduce((acc, u) => {
      if (!acc[u.sw_id]) acc[u.sw_id] = [];
      acc[u.sw_id].push([u.corp, u.dept, u.position, u.user_name, u.usage_period, u.doc_name]);
      return acc;
    }, {});
    res.json(Object.keys(grouped).map(sw_id => ({ sw_id, userData: grouped[sw_id] })));
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/sw-users/batch', async (req, res) => {
  try {
    const connection = await pool.getConnection();
    await connection.beginTransaction();
    await connection.query('DELETE FROM sw_users');
    const allUsers = req.body;
    if (allUsers.length > 0) {
      const values = allUsers.flatMap(item => 
        (item.userData || []).map(u => [item.sw_id, u[0], u[1], u[2], u[3], u[4], u[5]])
      );
      if (values.length > 0) {
        await connection.query('INSERT INTO sw_users (sw_id, corp, dept, position, user_name, usage_period, doc_name) VALUES ?', [values]);
      }
    }
    await connection.commit();
    connection.release();
    res.json({ success: true });
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 도메인 관리 API
app.get('/api/ops/domain', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM ops_domain_assets ORDER BY created_at DESC');
    res.json(rows);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

app.post('/api/ops/domain/batch', async (req, res) => {
  try {
    const result = await batchSave('ops_domain_assets', req.body, (assets) => ({
      sql: `INSERT INTO ops_domain_assets (id, type, corp, service_name, domain_name, start_date, expiry_date, price, manager_main, manager_sub, remarks) VALUES ?`,
      values: assets.map(a => [a.id, a.type||'', a.corp||'', a.service_name||'', a.domain_name||'', a.start_date||'', a.expiry_date||'', a.price||'', a.manager_main||'', a.manager_sub||'', a.remarks||''])
    }));
    res.json(result);
  } catch (err) { res.status(500).json({ error: err.message }); }
});

// 자산번호 자동 생성 API
app.get('/api/generate-asset-code', async (req, res) => {
  const { prefix } = req.query;
  if (!prefix) return res.status(400).json({ error: 'Prefix is required' });

  try {
    const tables = ['pc_assets', 'server_assets', 'storage_assets', 'equip_assets', 'mobile_assets'];
    let maxNum = 0;

    for (const table of tables) {
      const [rows] = await pool.query(
        `SELECT asset_code FROM ${table} WHERE asset_code LIKE ?`,
        [`${prefix}%`]
      );
      rows.forEach(r => {
        const numPart = r.asset_code.replace(prefix, '');
        const num = parseInt(numPart);
        if (!isNaN(num) && num > maxNum) maxNum = num;
      });
    }

    const nextNum = (maxNum + 1).toString().padStart(4, '0');
    res.json({ nextCode: `${prefix}${nextNum}` });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// 초기화 및 서버 기동
ensureTables().then(() => {
  app.listen(PORT, () => {
    console.log(`📡 ITAM Dedicated API Server running on http://localhost:${PORT}`);
  });
}).catch(err => {
  console.error('❌ Failed to start server:', err);
});
