import { defUploadFolder, FeedbackImagesFolderPath, ImageFolderPath } from "./constant";
import moment from 'moment';
import { Image } from "react-native";
import * as RNFS from 'react-native-fs';
import PhotoManipulator from 'react-native-photo-manipulator';
import ImageResizer from '@bam.tech/react-native-image-resizer';
import { toastError } from "./Toast";
import IMAGES from "./Images";

export async function CreateImageFolders() {
  console.log('CreateDirKPIimg:');
  await RNFS.mkdir(ImageFolderPath);
  await RNFS.mkdir(FeedbackImagesFolderPath);
}

export async function getImage(imgdata , userId , item) {
  console.log("item===", item); 
  if (typeof imgdata == 'object' && imgdata.errorCode === 'camera_unavailable') {
    console.log("camera not available");
    return null;
  }

  if (typeof imgdata == 'object' && imgdata.uri != null) {
    try {
      const imgurl = imgdata.uri.startsWith('file://') ? imgdata.uri : `file://${imgdata.uri}`;

      // 🔹 Get dynamic image width and height
      const { width: imgWidth, height: imgHeight } = await new Promise((resolve, reject) => {
        Image.getSize(imgurl, (width, height) => resolve({ width, height }), reject);
      });

      console.log("Image size ===", imgWidth, imgHeight);

      const picture_clickedd = new Date();
      const picture_clicked_time = moment(picture_clickedd).format('MM-DD-YYYY HH:mm:ss');
      const picture_clicked_time_for_pic_name = moment(picture_clickedd).format('MMDDYYYY_HHmmss');

      const filename =  userId + picture_clicked_time_for_pic_name + '.jpg';
      const mark_text1 = picture_clicked_time;
      const mark_text2 = `User Id: ${userId} | StoreName: ${item?.StoreName} | StoreId: ${item?.StoreId} | Date: ${picture_clicked_time}`;
      const imagePath = `${FeedbackImagesFolderPath}${filename}`;

      console.log("Copying image to:", imagePath);
      await RNFS.copyFile(imgurl.replace('file://', ''), imagePath);

      const restore_data = {
        destFilePath: imagePath,
        imgurl: imagePath,
        imgWidth,
        imgHeight,
        mark_text1,
        mark_text2,
      };

      const is_restored = await restore_ImageWithMetaData(restore_data, imgdata);
      console.log("Image restored:", is_restored);
      console.log("Image imagePath:", imagePath);

      return { finalPath: imagePath };
    } catch (err) {
      console.log('❌ ERROR in getImage:', err);
      return null;
    }
  }

  return null;
}

// const waterMarkText = async (text = '', imgurl = '', text2 = '', imgWidth = 0, imgHeight = 0) => {

//   const wrapText = (text2, maxCharsPerLine) => {
//     const words = text2.split(' ');
//     const lines = [];
//     let currentLine = '';

//     for (let word of words) {
//       if ((currentLine + word).length <= maxCharsPerLine) {
//         currentLine += (currentLine ? ' ' : '') + word;
//       } else {
//         lines.push(currentLine);
//         currentLine = word;
//       }
//     }
//     console.log('currentLine====>', currentLine);

//     if (currentLine) lines.push(currentLine);
//     return lines;
//   };



//   try {
//     if (!imgurl) throw new Error("Image URL is missing");

//     const cleanPath = imgurl.startsWith('file://') ? imgurl : `file://${imgurl}`;
//     const stripHeight = 250;

//     // ✅ Copy from Android assets folder to filesystem
//     const destPath = `${RNFS.CachesDirectoryPath}/white.png`;
//     const exists = await RNFS.exists(destPath);

//     if (!exists) {
//       await RNFS.copyFileAssets('white.png', destPath); // white.png is in android/app/src/main/assets
//     }

//     const stripFilePath = `file://${destPath}`;

//     // ✅ Step 2: Overlay strip
//     const imageWithStrip = await PhotoManipulator.overlayImage(
//       cleanPath,
//       stripFilePath,
//       { x: 0, y: imgHeight - stripHeight },
//       'image/jpeg'
//     );

//     // ✅ Step 3: Add text
//     const lines = wrapText(text2, 80); // You can adjust 25 depending on font size / image width

//     const texts = [
//       {
//         position: { x: 30, y: 50 },
//         text: text,
//         textSize: 80,
//         color: '#FF0000',
//       },
//       ...lines.map((line, i) => ({
//         position: { x: 30, y: imgHeight - 120 + i * 90 }, // 90 = line height
//         text: line,
//         textSize: 80,
//         color: '#000000',
//       })),
//     ];

//     const finalImagePath = await PhotoManipulator.printText(imageWithStrip, texts, 'image/jpeg');
//     const uri = finalImagePath.startsWith('file://') ? finalImagePath : `file://${finalImagePath}`;

//     return { success: true, uri };
//   } catch (error) {
//     console.error("❌ Error in waterMarkText:", error);
//     return { success: false, error: error.message };
//   }
// };

const waterMarkText = async (text = '', imgurl = '', text2 = '', imgWidth = 0, imgHeight = 0) => {
  const wrapTextByImageWidth = (text, imgWidth, fontSize = 80, padding = 60) => {
    const avgCharWidth = fontSize * 0.6; // Conservative estimate
    const maxChars = Math.floor((imgWidth - padding) / avgCharWidth);
    
    const words = text.split(' ');
    const lines = [];
    let currentLine = '';

    for (let word of words) {
      if ((currentLine + ' ' + word).trim().length <= maxChars) {
        currentLine += (currentLine ? ' ' : '') + word;
      } else {
        lines.push(currentLine);
        currentLine = word;
      }
    }
    if (currentLine) lines.push(currentLine);

    return lines;
  };

  try {
    if (!imgurl) throw new Error("Image URL is missing");

    const cleanPath = imgurl.startsWith('file://') ? imgurl : `file://${imgurl}`;
    const stripHeight = 250;

    // ✅ White strip setup
    const destPath = `${RNFS.CachesDirectoryPath}/white.png`;
    const exists = await RNFS.exists(destPath);
    if (!exists) {
      await RNFS.copyFileAssets('white.png', destPath);
    }

    const stripFilePath = `file://${destPath}`;

    // ✅ Overlay strip at bottom
    const imageWithStrip = await PhotoManipulator.overlayImage(
      cleanPath,
      stripFilePath,
      { x: 0, y: imgHeight - stripHeight },
      'image/jpeg'
    );

    // ✅ Wrap text2 according to image width
    const fontSize = 80;
    const lineHeight = 90;
    const padding = 60;
    const lines = wrapTextByImageWidth(text2, imgWidth, fontSize, padding);

    const startY = imgHeight - stripHeight + 40; // Add top padding inside strip

    // ✅ Build text objects
    const texts = [
      {
        position: { x: 30, y: 50 },
        text: text,
        textSize: fontSize,
        color: '#FF0000',
      },
      ...lines.map((line, index) => ({
        position: { x: 30, y: startY + index * lineHeight },
        text: line,
        textSize: fontSize,
        color: '#000000',
      })),
    ];

    const finalImagePath = await PhotoManipulator.printText(imageWithStrip, texts, 'image/jpeg');
    const uri = finalImagePath.startsWith('file://') ? finalImagePath : `file://${finalImagePath}`;

    return { success: true, uri };
  } catch (error) {
    console.error("❌ Error in waterMarkText:", error);
    return { success: false, error: error.message };
  }
};



export async function restore_ImageWithMetaData(data, imgdata) {
  let { destFilePath, imgurl, imgWidth, imgHeight, mark_text1, mark_text2 } = data;

  try {
    const cleanImgUrl = imgurl.startsWith('file://') ? imgurl : `file://${imgurl}`;
    const rawPath = cleanImgUrl.replace('file://', '');

    // Fallback to imgdata values
    if (!imgWidth && imgdata?.width) imgWidth = imgdata.width;
    if (!imgHeight && imgdata?.height) imgHeight = imgdata.height;

    if (!imgWidth || !imgHeight || !rawPath) {
      console.log('❌ Invalid resize parameters', { imgWidth, imgHeight, imgurl });
      return false;
    }

    const fileExists = await RNFS.exists(rawPath);
    if (!fileExists) {
      console.log('❌ Image file not found at:', rawPath);
      return false;
    }

    // Step 1: Resize (only if dimensions are large)
    const resized = await resizeImage(cleanImgUrl, imgWidth, imgHeight);
    if (!resized.success) {
      console.log("❌ Resize failed:", resized.error);
      return false;
    }

    const resizedUrl = resized.uri;
    const resizedData = resized.imgData;
    const resizedWidth = parseInt(resizedData.width);
    const resizedHeight = parseInt(resizedData.height);

    // Step 2: Watermark
    const marked = await waterMarkText(mark_text1, resizedUrl, mark_text2, resizedWidth, resizedHeight);
    if (!marked.success || !marked.uri) {
      console.log("❌ Watermark failed:", marked.error);
      return false;
    }

    const markedUrl = marked.uri;

    // Step 3: Reduce pixels (if needed)
    const reduced = await reducePixels(markedUrl, resizedWidth, resizedHeight);
    if (!reduced.success) {
      console.error("❌ Pixel reduction failed:", reduced.error);
      return false;
    }

    const finalUri = reduced.uri;

    // Step 4: Copy to destination
    const exists = await RNFS.exists(destFilePath);
    if (exists) await RNFS.unlink(destFilePath);

    await RNFS.copyFile(finalUri, destFilePath);
    console.log("✅ Image with metadata saved at:", destFilePath);

    // Step 5: DO NOT delete destFilePath — it's the one used in UI!
    // Optional: Clean up temp files
    const filesToDelete = [rawPath, resizedUrl, markedUrl]
      .map(f => f.replace('file://', ''))
      .filter(f => f !== destFilePath); // protect final image

    await Promise.all(
      filesToDelete.map(f => RNFS.unlink(f).catch(() => {}))
    );

    return true;
  } catch (err) {
    console.log("❌ restore_ImageWithMetaData failed:", err);
    return false;
  }
}


export function bytesToSize(bytes) {
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  if (bytes === 0) return '0 Byte';
  const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
  return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}

export const resizeImage = async (imgurl = '', imgWidth, imgHeight) => {
  if (!imgurl || !imgWidth || !imgHeight || isNaN(imgWidth) || isNaN(imgHeight)) {
    console.log("❌ resizeImage: Invalid parameters", { imgurl, imgWidth, imgHeight });
    return { success: false, error: 'Invalid resize parameters' };
  }

  try {
    const response = await ImageResizer.createResizedImage(
      imgurl, imgWidth, imgHeight, 'JPEG', 100, 0, null, false, { onlyScaleDown: true }
    );
    let size = bytesToSize(response.size);
    console.log('✅ resizeImage: reduced filesize:', size);
    return { success: true, uri: response.uri, imgData: response };
  } catch (err) {
    console.log("❌ resizeImage error:", err);
    return { success: false, error: err };
  }
};

export const reducePixels = async (imgurl = '', imgWidth, imgHeight) => {
  if (!imgurl || !imgWidth || !imgHeight || isNaN(imgWidth) || isNaN(imgHeight)) {
    console.log("❌ reducePixels: Invalid parameters", { imgurl, imgWidth, imgHeight });
    return { success: false, error: 'Invalid pixel reduction parameters' };
  }

  // Resize only if image is large
  if (imgWidth > 1100 || imgHeight > 1100) {
    try {
      const response = await ImageResizer.createResizedImage(
        imgurl, 1100, 1100, 'JPEG', 40, 0, null, false,
        { onlyScaleDown: true, mode: 'contain' }
      );
      let size = bytesToSize(response.size);
      console.log('✅ reducePixels: reduced size to', size, '→', response.width, 'x', response.height);
      return { success: true, uri: response.uri };
    } catch (err) {
      console.log("❌ reducePixels error:", err);
      return { success: false, error: err };
    }
  }

  // No resizing needed
  return { success: true, uri: imgurl };
};


// end image resize and reduce pixel function


export async function getAllFileForAFolder(path, Up_Foldername, KPIName = '') {

  let subFolPath = path;
  const ImgFiles = await RNFS.readDir(subFolPath);
  Up_Foldername = Up_Foldername != null && Up_Foldername != '' ? Up_Foldername : defUploadFolder;

  console.log("ImgFiles in ", subFolPath, ' are:', ImgFiles.length);
  let allKPIfiles = [];
  return new Promise.all(
    ImgFiles.map(async sfile => {
      if (sfile.isFile() && (sfile.name.includes('jpg') || sfile.name.includes('jpeg') || sfile.name.includes('png'))) {

        let file = {
          uri: sfile.path,
          type: 'image/jpeg',
          name: sfile.name,
          filetype: 'image',
          folderName: Up_Foldername,
        }
        allKPIfiles.push(file);
        return file;
      }
      else if (sfile.isDirectory() && sfile.name == 'Recordings') {
        let recordingsPath = sfile.path;
        let recordingFiles = await RNFS.readDir(recordingsPath);
        let VoiceUp_FolderPath = KPIName != null && KPIName != '' ? FolderForREC[KPIName] : defUploadFolder;
        return new Promise.all(
          recordingFiles.map(async rfile => {

            if (rfile.isFile() && (rfile.name.includes('m4a') || rfile.name.includes('mp3'))) {

              let file = {
                uri: rfile.path,
                type: (Platform.OS == 'ios' ? 'audio/m4a' : 'audio/mp3'),
                name: rfile.name,
                filetype: 'audio',
                folderName: VoiceUp_FolderPath,
              }
              allKPIfiles.push(file);
              return file;
            }
            else {
              return '';
            }

          })
        ).then((val2) => {
          return val2;
        });
      }
      else {
        return '';
      }
    })
  ).then((val1) => {
    console.log('getAllFileForAFolder', val1);
    return allKPIfiles;
  }).catch((err) => {
    console.log('error in getAllFileForAFolder', err);
    return allKPIfiles;
  })

}



/// download 


export async function getDownloadJson(url, indata) {
  let postdata = {
    Downloadtype: indata.Downloadtype,
    Username: indata.username,
    Param1: '',
    Param2: '',
  };
  console.log(postdata);
  return await fetch(url, {
    method: 'post',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(postdata),
  })
    .then(response => {
      return response.json();
    })
    .then((res) => {
      // console.log('res',res);
      let resd = JSON.parse(res);
      return resd;
    })
    .catch(err => {
      console.log('getdashboard error', err);
      return { success: false };
    });
}