// routes/manageBrands.js
const express = require('express');
const axios = require('axios');
const { v4: uuid } = require('uuid');
const { getToken } = require('../tokenStore');
const { log } = require('../logger');

const router = express.Router();
const processes = {};
async function fetchAllCollections(shop, accessToken) {
  const adminUrl = `https://${shop}/admin/api/2025-10/graphql.json`;
  const headers = {
    'X-Shopify-Access-Token': accessToken,
    'Content-Type': 'application/json',
  };

  let allCollections = [];
  let hasNextPage = true;
  let endCursor = null;
  const pageSize = 100;

  while (hasNextPage) {
    const fetchQuery = `
      query GetCollections {
        collections(first: ${pageSize}${endCursor ? `, after: "${endCursor}"` : ''}) {
          edges {
            node {
              id
              title
            }
            cursor
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
    `;

    const fetchResp = await axios.post(adminUrl, { query: fetchQuery }, { headers });
    const collections = fetchResp.data.data.collections.edges.map(e => e.node);
    allCollections = allCollections.concat(collections);

    hasNextPage = fetchResp.data.data.collections.pageInfo.hasNextPage;
    endCursor = fetchResp.data.data.collections.pageInfo.endCursor;
  }

  console.log(`Fetched ${allCollections.length} collections from ${shop}`);
  return allCollections;
}



router.post('/', async (req, res) => {
  const { shop, selectedBrands, selectedOldBrands } = req.body;
  const selectedBrandsToUpdateMetaField = selectedBrands
  console.log(`Selected brands: ${JSON.stringify(selectedBrandsToUpdateMetaField)}`);
  const procId = uuid();
  processes[procId] = { status: 'started', detail: null };
  log(shop, `🔔 [${procId}] ManageBrands initiated for ${selectedBrands.length} new brands and ${selectedOldBrands.length} old brands`);
  res.json({ processId: procId, status: 'started' });

  (async () => {
    try {
      log(shop, `🔔 [${procId}] ManageBrands started`);
      processes[procId].status = 'fetching_collections';

      // 1. Get token
      const tokenRecord = getToken(shop);
      if (!tokenRecord) throw new Error('No token for shop');

      const adminUrl = `https://${shop}/admin/api/2025-10/graphql.json`;
      const headers = {
        'X-Shopify-Access-Token': tokenRecord.accessToken,
        'Content-Type': 'application/json',
      };
      console.log(`🔑 [${procId}] Using access token for shop ${shop} ${adminUrl} ${tokenRecord.accessToken}`);

      const allCollections = await fetchAllCollections(shop, tokenRecord.accessToken);
      log(shop, `🔍 [${procId}] Fetchedd ${allCollections.length} existing collections`);


      // 3. Delete unselected
      processes[procId].status = 'deleting';
      // const toDelete = allCollections.filter(c => {
      //   return !selectedBrands.find(b => b.name.toLowerCase() === c.title.toLowerCase());
      // });

      // const toDelete = selectedOldBrands.filter(c => {
      //   return !selectedBrands.find(b => b.name.toLowerCase() === c.name.toLowerCase());
      // });
      // for (let i = 0; i < toDelete.length; i++) {
      //   const col = toDelete[i];
      //   processes[procId].detail = `deleting ${i + 1}/${toDelete.length}`;
      //   await axios.post(adminUrl, {
      //     query: `
      //       mutation { collectionDelete(input:{id:"${col.id}"}) { deletedCollectionId } }
      //     `
      //   }, { headers });
      //   log(shop, `🗑️ [${procId}] Deleted collection ${col.title}`);
      // }

      // 4. Create new
      processes[procId].status = 'creating';
      const existingTitles = allCollections.map(c => c.title.toLowerCase());
      const toCreate = selectedBrands.filter(b => !existingTitles.includes(b.name.toLowerCase()));
      for (let i = 0; i < toCreate.length; i++) {
        const b = toCreate[i];
        processes[procId].detail = `creating ${i + 1}/${toCreate.length}`;
        const name = b.name.replace(/"/g, '\\"');
        const logo = b.logo || '';
        await axios.post(adminUrl, {
          query: `
            mutation {
              collectionCreate(input:{
                title:"${name}",
                descriptionHtml:"Products from ${name}",
                image:{altText:"${name} Logo",src:"${logo}"}
              }) { collection { id } }
            }
          `
        }, { headers });
        log(shop, `➕ [${procId}] Created collection ${b.name}`);
      }

      // 5. Update metafield

      console.log(`Updating metafield with ${selectedBrands.length} entries`);
      console.log(`Updating metafield with ${selectedBrands} entries`);
      console.log(`Updating metafield with ${selectedBrandsToUpdateMetaField} entries`);
      processes[procId].status = 'updating_metafield';
      const shopIdQuery = `{ shop { id } }`;
      const shopIdResp = await axios.post(adminUrl, { query: shopIdQuery }, { headers });
      const shopId = shopIdResp.data.data.shop.id;
      const mfValue = JSON.stringify(selectedBrandsToUpdateMetaField);
      await axios.post(adminUrl, {
        query: `
          mutation {
            metafieldsSet(metafields:[{
              namespace:"turn14",key:"selected_brands",type:"json",
              ownerId:"${shopId}",value:${JSON.stringify(mfValue)}
            }]) { metafields { id } }
          }
        `
      }, { headers });
      log(shop, `💾 [${procId}] Updated metafield with ${selectedBrands.length} entries`);

      processes[procId].status = 'done';
      processes[procId].detail = null;
      log(shop, `✅ [${procId}] ManageBrands complete`);
    } catch (err) {
      processes[procId].status = 'error';
      processes[procId].detail = err.message;
      log(shop, `❌ [${procId}] Error: ${err.message}`);
    }
  })();
});

router.get('/status/:processId', (req, res) => {
  const info = processes[req.params.processId];
  if (!info) return res.status(404).json({ error: 'Not found' });
  res.json(info);
});

module.exports = router;
