/**
 * 店小秘全自动登录 + 后台探索 + 导出
 * - OCR: ddddocr (Python)
 * - 每次尝试用新 Context 避免安全机制
 * - 通过 API 响应判断登录结果（非 JSON = 成功跳转）
 */
import { chromium } from 'playwright';
import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';
import { execSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const COOKIE_FILE = path.join(__dirname, 'cookies.json');
const SCREENSHOTS_DIR = path.join(__dirname, 'screenshots');
const DOWNLOAD_DIR = path.join(__dirname, 'downloads');
const OCR_SCRIPT = path.join(__dirname, 'ocr_captcha.py');
const MAX_RETRIES = 20;
const BASE_URL = 'https://www.dianxiaomi.com';

mkdirSync(SCREENSHOTS_DIR, { recursive: true });
mkdirSync(DOWNLOAD_DIR, { recursive: true });

function ocrCaptcha(imagePath) {
  try {
    return execSync(`python3 "${OCR_SCRIPT}" "${imagePath}"`, {
      encoding: 'utf-8', timeout: 30000,
    }).trim() || null;
  } catch { return null; }
}

function timestamp() {
  return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
}

// ====== 登录 ======
async function doLogin(browser) {
  console.log(`[${timestamp()}] 开始登录...\n`);

  // 先试 Cookie
  if (existsSync(COOKIE_FILE)) {
    console.log('>> 尝试复用 Cookie...');
    const ctx = await browser.newContext({
      viewport: { width: 1920, height: 1080 }, locale: 'zh-CN',
      userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
    });
    const pg = await ctx.newPage();
    const cookies = JSON.parse(readFileSync(COOKIE_FILE, 'utf-8'));
    await ctx.addCookies(cookies);

    // 用 AJAX 请求一个需要登录的接口检查 Cookie 是否有效
    try {
      await pg.goto(`${BASE_URL}/home.htm`, { waitUntil: 'load', timeout: 20000 });
      const checkResult = await pg.evaluate(async () => {
        try {
          const resp = await fetch('/saleManage/searchSale.json', { method: 'POST' });
          const text = await resp.text();
          // 如果返回 JSON 数据（不是登录页 HTML），说明 Cookie 有效
          return { status: resp.status, isJson: text.startsWith('{') || text.startsWith('['), preview: text.substring(0, 100) };
        } catch (e) {
          return { error: e.message };
        }
      });
      console.log('  Cookie 检查:', JSON.stringify(checkResult));
      if (checkResult.isJson && checkResult.status === 200) {
        console.log('>> Cookie 有效！\n');
        return { page: pg, context: ctx };
      }
    } catch {}
    console.log('>> Cookie 无效\n');
    await ctx.close();
  }

  // 循环尝试登录
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
    console.log(`>> 第 ${attempt}/${MAX_RETRIES} 次...`);

    const ctx = await browser.newContext({
      viewport: { width: 1920, height: 1080 }, locale: 'zh-CN',
      userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
    });
    const pg = await ctx.newPage();

    // 监听登录 API 响应
    let loginApiResult = null;
    pg.on('response', async (resp) => {
      if (resp.url().includes('userLoginNew2')) {
        try {
          loginApiResult = await resp.text();
        } catch {
          // 读取失败 = 页面已跳转 = 登录成功
          loginApiResult = '__REDIRECT__';
        }
      }
    });

    try {
      // 1) 加载
      await pg.goto(`${BASE_URL}/home.htm`, { waitUntil: 'load', timeout: 30000 });
      await pg.waitForSelector('#exampleInputName', { timeout: 10000 });
      await pg.waitForFunction(() => typeof window.login === 'function', { timeout: 10000 });
      await pg.waitForFunction(() => document.getElementById('verifyImgCode')?.complete === true, { timeout: 5000 }).catch(() => {});
      await pg.waitForTimeout(1000);

      // 2) OCR
      const captchaEl = await pg.$('#verifyImgCode');
      if (!captchaEl) { await ctx.close(); continue; }
      const captchaPath = path.join(SCREENSHOTS_DIR, 'captcha_raw.png');
      await captchaEl.screenshot({ path: captchaPath });
      const code = ocrCaptcha(captchaPath);
      if (!code || code.length < 3) { console.log(`  OCR 失败: "${code}"`); await ctx.close(); continue; }
      console.log(`  验证码: "${code}"`);

      // 3) 填值
      await pg.evaluate((c) => {
        $('#exampleInputName').val('MiLe-kf01');
        $('#exampleInputPassword').val('Vxdas@302');
        $('#verifyCode').val(c);
      }, code);

      // 4) 调用 login()
      loginApiResult = null;
      const navPromise = pg.waitForNavigation({ timeout: 15000, waitUntil: 'load' }).catch(() => null);
      await pg.evaluate(() => { login(); });
      await navPromise;
      await pg.waitForTimeout(3000);

      const url = pg.url();
      console.log(`  URL: ${url}`);
      console.log(`  API: ${loginApiResult?.substring(0, 200)}`);

      // 5) 判断结果
      // 情况 A：API 返回 JSON 错误
      if (loginApiResult && loginApiResult !== '__REDIRECT__') {
        try {
          const data = JSON.parse(loginApiResult);
          if (data.code === -1) {
            console.log(`  ✗ ${data.error}`);
            if (data.error?.includes('密码') || data.error?.includes('锁定')) {
              await ctx.close(); return null;
            }
            await ctx.close(); continue;
          }
          if (data.code === 0) {
            console.log('\n>> ★★★ 登录成功(code=0)！★★★');
            if (data.url) {
              await pg.goto(`${BASE_URL}${data.url}`, { waitUntil: 'load', timeout: 20000 }).catch(() => {});
            }
            const cookies = await ctx.cookies();
            writeFileSync(COOKIE_FILE, JSON.stringify(cookies, null, 2));
            console.log(`>> Cookie 已保存（${cookies.length} 条）\n`);
            return { page: pg, context: ctx };
          }
        } catch {
          // JSON 解析失败 = 可能是 HTML 重定向 = 成功
        }
      }

      // 情况 B：API 响应读取失败（__REDIRECT__）= 页面跳转 = 成功
      if (loginApiResult === '__REDIRECT__' || !url.includes('/home.htm')) {
        console.log('\n>> ★★★ 登录成功(页面跳转)！★★★');
        const cookies = await ctx.cookies();
        writeFileSync(COOKIE_FILE, JSON.stringify(cookies, null, 2));
        console.log(`>> Cookie 已保存（${cookies.length} 条）\n`);
        return { page: pg, context: ctx };
      }

      // 情况 C：仍在登录页
      console.log('  仍在登录页，重试\n');
      await ctx.close();

    } catch (e) {
      console.log(`  异常: ${e.message}`);
      await ctx.close();
    }
  }

  console.log('>> 全部尝试失败');
  return null;
}

// ====== 探索后台 ======
async function explore(pg) {
  console.log('>> ===== 探索后台 =====');
  console.log(`>> URL: ${pg.url()}`);

  await pg.screenshot({ path: path.join(SCREENSHOTS_DIR, 'after-login.png'), fullPage: true });

  // 当前页面内容
  const text = await pg.evaluate(() => document.body?.innerText?.substring(0, 5000));
  console.log('>> 页面文本（前2000字）:\n', text?.substring(0, 2000));

  // 尝试找到真正的后台入口
  // 从当前页面的所有链接中查找
  const links = await pg.$$eval('a', els =>
    els.map(el => ({ text: el.textContent.trim().replace(/\s+/g, ' ').substring(0, 60), href: el.href }))
    .filter(e => e.text && e.href?.includes('dianxiaomi'))
    .filter((e, i, arr) => arr.findIndex(a => a.href === e.href) === i)
  );

  console.log(`\n>> 页面链接（${links.length} 个）：`);
  for (const l of links) {
    console.log(`  [${l.text}] ${l.href}`);
  }

  // 用 AJAX 探测后台 API
  console.log('\n>> 探测后台 API...');
  const apis = [
    { name: '订单搜索', url: '/saleManage/searchSale.json', method: 'POST' },
    { name: '采购建议', url: '/purchaseManage/purchaseSuggestion.json', method: 'POST' },
    { name: '采购建议列表', url: '/purchaseManage/getSuggestionList.json', method: 'POST' },
    { name: '采购单', url: '/purchaseManage/purchaseOrderList.json', method: 'POST' },
    { name: '库存列表', url: '/stockManage/stockList.json', method: 'POST' },
    { name: '自营仓库', url: '/stockManage/selfWarehouse.json', method: 'POST' },
    { name: '仓库列表', url: '/warehouseManage/warehouseList.json', method: 'POST' },
    { name: '用户信息', url: '/user/getUserInfo.json', method: 'GET' },
    { name: '菜单', url: '/user/getMenuList.json', method: 'GET' },
    { name: '首页数据', url: '/index/getData.json', method: 'GET' },
  ];

  for (const api of apis) {
    const result = await pg.evaluate(async (a) => {
      try {
        const resp = await fetch(a.url, { method: a.method });
        const text = await resp.text();
        return { status: resp.status, ok: resp.ok, preview: text.substring(0, 300) };
      } catch (e) {
        return { error: e.message };
      }
    }, api);
    const isJson = result.preview?.startsWith('{') || result.preview?.startsWith('[');
    console.log(`  ${isJson ? '✓' : '✗'} ${api.name} (${api.url}) [${result.status}] ${result.preview?.substring(0, 150)}`);
  }

  // 尝试后台页面
  console.log('\n>> 尝试后台页面...');
  const pagePaths = [
    '/saleManage/index.htm',
    '/purchaseManage/purchaseSuggestion.htm',
    '/purchaseManage/purchaseOrder.htm',
    '/stockManage/stockList.htm',
    '/warehouseManage/index.htm',
    '/user/setting.htm',
    '/user/index.htm',
  ];

  for (const p of pagePaths) {
    try {
      await pg.goto(`${BASE_URL}${p}`, { waitUntil: 'load', timeout: 15000 });
      const t = await pg.title();
      const u = pg.url();
      const isError = t.includes('Error') || u.includes('/home.htm');
      console.log(`  ${isError ? '✗' : '✓'} ${p} [${t}] -> ${u}`);

      if (!isError) {
        await pg.screenshot({ path: path.join(SCREENSHOTS_DIR, `page${p.replace(/\//g, '_')}.png`), fullPage: true });
        const pageContent = await pg.evaluate(() => document.body?.innerText?.substring(0, 1000));
        console.log(`    内容: ${pageContent?.substring(0, 300)}`);
      }
    } catch { console.log(`  ✗ ${p} 超时`); }
  }
}

// ====== 主流程 ======
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });

const result = await doLogin(browser);
if (result) {
  await explore(result.page);
  await result.context.close();
}

await browser.close();
process.exit(result ? 0 : 1);
