import { PPTElementShadow, PPTTextElement } from '@/types/slides';
import HtmlUtil from '../htmlutil';

export const ResolveText = (item: any, index: number,offsetLeft:number,offsetTop:number,groupId:string =''): PPTTextElement => {

    let domLeft = item.layer.left-offsetLeft
    let domwidth = item.layer.width
    let domTop = item.layer.top-offsetTop
    let domheight = item.layer.height
    let transformRotate = 0
    let clip = false
    let stroke = ''
    const opacity = (parseFloat(item.layer.opacity) / 255.0)

    let f = item.layer.typeTool().export()
    
    const { left, top, width, height, value, font, transform } = f
    const { colors, styles, alignment, sizes, names, weights,textDecoration } = font
    let fontSize = 24.0
    let newSizes = sizes?sizes:[12]
    //if(value=='12980') console.log(newSizes,transform,extractScale(transform))
    if (newSizes && newSizes[0]) {
        if (transform) {
            fontSize = Math.round(newSizes[0] * extractScale(transform))
        } else {
            fontSize = newSizes[0]
        }
    }
    if(transform){
        transformRotate = extractRotation(transform)
    }
    
    const StyleSheet = item.layer.adjustments.typeTool.obj.engineData.EngineDict.StyleRun.RunArray[0].StyleSheet || {}
    
    const { StyleSheetData } = StyleSheet
    const tracking = fontSize * (StyleSheetData.Tracking / 1000)
    const lineHeight = StyleSheetData.Leading
    let leading = sizes?(Math.round((lineHeight * transform.yy) * 100) * 0.01) / fontSize:1
    let objectEFFFects = item.layer.objectEffects ? item.layer.objectEffects() : null
    
    let color = `rgba(${colors[0][0]},${colors[0][1]},${colors[0][2]},${(parseFloat(colors[0][3]) / 255.0).toFixed(2)})`

    let styleArray:string[] = []
    const lineCount = value.split('\r').length
    for (let i = 0; i < lineCount; i++) {
        const align = alignment.length>i?alignment[i]:alignment[alignment.length-1]
        const sizestyle = newSizes.length>i?newSizes[i]:newSizes[newSizes.length-1]
        const weight = weights.length>i?weights[i]:weights[weights.length-1]
        const decoration = textDecoration?textDecoration[i]:textDecoration[textDecoration.length-1]
        let fz = 24.0
        if (transform) {
            fz = Math.round(sizestyle * extractScale(transform))
        } else {
            fz = sizestyle
        }  
        let style = `text-align:${align}; font-size:${fz-2}px; font-weight:${weight};`
        if (decoration || StyleSheetData.Strikethrough) {
            style += `text-decoration:${decoration} ${StyleSheetData.Strikethrough ? ' line-through' : ''};`
        }
        if (StyleSheetData.FauxItalic){
            style += `font-style:italic;`
        }
        styleArray.push(style)
    }

    
    let textShadow: any = null
    if (objectEFFFects && objectEFFFects.data?.DrSh?.enab) {
        textShadow = getShadows(objectEFFFects)
    }
    let background = ''
    if (objectEFFFects && objectEFFFects.data?.GrFl?.enab) {
        background += `rgba(${colors[0][0]},${colors[0][1]},${colors[0][2]},${(parseFloat(colors[0][3]) / 255.0).toFixed(2)})`
        background += " "+getGradient(objectEFFFects)
        background += " no-repeat"
        background += " fixed"
        background += " center center"
        // div.style.backgroundPositionX = objectEFFFects.data.GrFl.Ofst.Hrzn.value+"px"
        // div.style.backgroundPositionY = objectEFFFects.data.GrFl.Ofst.Vrtc.value+"px"
        color = 'transparent',
        textShadow = null
        clip=true
        styleArray.forEach((s:string) => {
            s += `background:${background} !important;-webkit-background-clip: text !important;`
        });
        
    }
    if(objectEFFFects && objectEFFFects.data?.FrFX?.enab){
        stroke = getStrokeHandler(objectEFFFects)
    }
    const valuesStr = value.split('\r')
    let content = ''
    valuesStr.forEach((x: any,si:number) => {
        if(x!='')
        content += `<p><span  style="${styleArray[si]}">${HtmlUtil.htmlEncodeByRegExp(x)}</span></p>`
    })
    
    const isVertical = item.layer.adjustments.typeTool.obj.textData.Ornt.value != 'Hrzn'
    if(isVertical) {
        let checkWord = value[0]+value[value.length-1]
        if(checkWord){
            let words = checkWord.match(/[\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/g)
            if(words&&words.length>0){
                domheight += fontSize*words.length*1.4
                domTop -= fontSize/2
            
            }else{
                domheight += fontSize*1.4
            }
        }
    }
    else {
        domwidth += fontSize+(value[value.length-1]=='】'?fontSize:0)
    }
    domTop -= 10+ (/[\u4e00-\u9fff]/.test(value)||/[A-Z]/.test(value)?0:fontSize*0.15) //+((leading-1)*fontSize/2)
    domLeft -= 10 //+((leading-1)*fontSize/2)

    let fontName = names.filter((x:any)=>x.indexOf('Adobe')==-1)
    if(fontName && fontName.length>0){
        for (let i = 0; i < fontName.length; i++) {
            let x = fontName[i];
            if(/^\d+/.test(x)){
                x=x.replace(/[0-9]/ig,"")
                x=x.replace('-','')
            }
            fontName[i]=x
        }
    }
    let element: PPTTextElement = {
        id: "text_" + index,
        type: 'text',
        left:domLeft,
        width:domwidth,
        top:domTop,
        height:domheight,
        rotate: transformRotate,
        opacity,
        content,
        defaultFontName: fontName && fontName.length>0 ? fontName[0]:'',
        defaultColor: color,
        fill: background,
        lineHeight: leading<1?1:leading,
        wordSpace: tracking,
        vertical: isVertical,
        contentStr: value,
        layerName:item.layer.name,
        groupId :groupId,
        clip,
        stroke
    }
    if (textShadow) element.shadow = textShadow

    return element
}

const extractScale = (matrix:any) => {
    const scaleX = Math.sqrt(matrix.xx * matrix.xx + matrix.xy * matrix.xy);
    const scaleY = Math.sqrt(matrix.yx * matrix.yx + matrix.yy * matrix.yy);
  
    return scaleY>scaleX?scaleY:scaleX;
}
const extractRotation = (matrix:any) => {
    const a = matrix.xx;
    const b = matrix.yx;
    const c = matrix.xy;
    const d = matrix.yy;
  
    // Calculate rotation in radians
    const rotationRadians = Math.atan2(b, a);
  
    // Convert to degrees
    const rotationDegrees = rotationRadians * (180 / Math.PI);
  
    return -rotationDegrees;
}
const getGradient = (obj: any) => {
    const { GrFl } = obj.data
    const angle = GrFl.Angl.value - 90
    let linear = `linear-gradient(${angle}deg `
    let intr = GrFl.Grad.Intr
    GrFl.Grad.Clrs.forEach((x: any, i: number) => {
        const clrStr = JSON.stringify(x['Clr ']).split(',')
        let r: string = '0'
        let g: string = '0'
        let b: string = '0'
        clrStr.forEach(item => {
            if (item.indexOf('Rd') !== -1) {
                r = item.replace('"Rd  ":', '')
            } else if (item.indexOf('Bl') !== -1) {
                b = item.replace('"Bl  ":', '').replace('}', '')
            } else if (item.indexOf('Grn') !== -1) {
                g = item.replace('"Grn ":', '')
            }
        })
        const color =
            linear += `, rgba(${parseInt(r)},${parseInt(g)},${parseInt(b)},${GrFl.Opct.value / 100})`
        //linear-gradient(90deg, #FFF 0%, 18% ,#e5b8a4 36%, 68%, #FFF)
        let cent = "", posi = ""
        if (i < GrFl.Grad.Clrs.length - 1) {
            posi = Math.ceil(x.Lctn * 100 / intr) + "%"
            cent = Math.ceil((x.Lctn + ((GrFl.Grad.Clrs[i + 1].Lctn - x.Lctn) * x.Mdpn / 100)) * 100 / intr) + "%"
            linear += ` ${posi}, ${cent}`
        }
    })
    linear += ")"

    return linear;
}

const getStrokeHandler =(obj: any) => {
    const { FrFX } = obj.data
    const clrStr = JSON.stringify(FrFX['Clr ']).split(',')
    let r: string = '0'
    let g: string = '0'
    let b: string = '0'
    clrStr.forEach(item => {
        if (item.indexOf('Rd') !== -1) {
            r = item.replace('"Rd  ":', '')
        } else if (item.indexOf('Bl') !== -1) {
            b = item.replace('"Bl  ":', '').replace('}', '')
        } else if (item.indexOf('Grn') !== -1) {
            g = item.replace('"Grn ":', '')
        }
    })
    // let temp = JSON.stringify(FrFX)
    // var regex = /(?<="Sc ":).*?(?=})/g  
    // console.log(FrFX,temp)
    const color = `rgba(${parseInt(r)},${parseInt(g)},${parseInt(b)},${FrFX.Opct.value / 100})`
    const size = FrFX['Sz  '].value+"px"
    return `${size} ${color}`
}

const getShadows = (drsh: any) => {
    const { DrSh } = drsh.data

    const clrStr = JSON.stringify(DrSh['Clr ']).split(',')
    let r: string = '0'
    let g: string = '0'
    let b: string = '0'
    clrStr.forEach(item => {
        if (item.indexOf('Rd') !== -1) {
            r = item.replace('"Rd  ":', '')
        } else if (item.indexOf('Bl') !== -1) {
            b = item.replace('"Bl  ":', '').replace('}', '')
        } else if (item.indexOf('Grn') !== -1) {
            g = item.replace('"Grn ":', '')
        }
    })
    const angle = DrSh.lagl.value
    const distance = DrSh.Dstn.value
    var angleInRadians = angle * Math.PI / 180;
    const shadowColor = `rgba(${parseInt(r)},${parseInt(g)},${parseInt(b)},${DrSh.Opct.value / 100})`
    const x = Math.round(distance * Math.cos(angleInRadians));
    const y = Math.round(distance * Math.sin(angleInRadians));

    let result: PPTElementShadow = {
        v: x,
        h: y,
        blur: DrSh.blur.value,
        color: shadowColor
    }
    return result;
}