from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance, ImageChops
import random, math

SRC='/home/spazio/.hermes/cache/images/img_a260c53e39d2.jpg'
FONT='/home/spazio/.fonts/cl/Manrope.ttf'
SERIF='/home/spazio/.fonts/cl/PlayfairDisplay-Bold.ttf'
GOLD=(214,174,91,255); VIOLET=(156,82,235,255); YELLOW=(247,211,62,255); WHITE=(248,244,241,255)

def grade(src, shadow=(31,-9,43), color=.85, contrast=1.12, bright=.93):
    im=ImageEnhance.Color(src).enhance(color)
    im=ImageEnhance.Contrast(im).enhance(contrast)
    im=ImageEnhance.Brightness(im).enhance(bright)
    px=im.load(); W,H=im.size
    for y in range(H):
        for x in range(W):
            r,g,b=px[x,y]; lum=(r+g+b)/3
            s=max(0,min(1,(160-lum)/160))
            px[x,y]=(max(0,min(255,int(r+shadow[0]*s))),max(0,min(255,int(g+shadow[1]*s))),max(0,min(255,int(b+shadow[2]*s))))
    return im.convert('RGBA')

def vignette(im, strength=135):
    W,H=im.size; ov=Image.new('RGBA',(W,H),(0,0,0,0)); p=ov.load()
    cx,cy=W*.5,H*.46
    for y in range(H):
        for x in range(W):
            q=max(0,min(1,(((x-cx)/(W*.7))**2+((y-cy)/(H*.72))**2-.16)/.84))
            p[x,y]=(12,3,27,int(strength*q))
    return Image.alpha_composite(im,ov)

def pearl_mask(src):
    W,H=src.size; m=Image.new('L',(W,H),0); p=m.load(); sp=src.load()
    for y in range(int(H*.04),int(H*.57)):
        for x in range(int(W*.22),int(W*.78)):
            r,g,b=sp[x,y]
            if min(r,g,b)>140 and max(r,g,b)-min(r,g,b)<52:
                p[x,y]=min(255,int((min(r,g,b)-120)*3.1))
    return m.filter(ImageFilter.GaussianBlur(1.2))

def add_footer(im,label,index):
    W,H=im.size; d=ImageDraw.Draw(im)
    f=ImageFont.truetype(FONT,15); fb=ImageFont.truetype(FONT,17)
    d.line((34,H-66,W-34,H-66),fill=(214,174,91,120),width=1)
    d.text((34,H-46),f'{index}  /  {label}',font=fb,fill=GOLD)
    d.text((W-34,H-46),'COSMOS LUMINOSITY',font=f,fill=WHITE,anchor='ra')
    return im

def cosmic_couture(src):
    W,H=src.size
    im=vignette(grade(src, shadow=(28,-6,38), color=.76, contrast=1.08, bright=.96),115)
    mask=pearl_mask(src)
    # pearlescent mask: lavender + warm gold directional sheen
    pearl=Image.new('RGBA',(W,H),(205,187,243,0)); pearl.putalpha(mask.point(lambda v:int(v*.45)))
    im=Image.alpha_composite(im,pearl)
    glow=Image.new('RGBA',(W,H),(165,95,255,0)); glow.putalpha(mask.filter(ImageFilter.GaussianBlur(24)).point(lambda v:int(v*.24)))
    im=Image.alpha_composite(im,glow)
    fx=Image.new('RGBA',(W,H),(0,0,0,0)); d=ImageDraw.Draw(fx)
    # couture halos: asymmetrical, elegant metallic curves
    d.arc((W*.12,H*.00,W*.88,H*.70),198,342,fill=(213,176,97,215),width=3)
    d.arc((W*.17,H*.04,W*.83,H*.66),202,338,fill=(174,107,240,170),width=2)
    d.arc((W*.22,H*.08,W*.78,H*.62),206,334,fill=(249,218,106,105),width=1)
    # flowing liquid-gold ribbons outside face
    left=[(W*.10,H*.20),(W*.16,H*.33),(W*.10,H*.48),(W*.18,H*.66),(W*.11,H*.82)]
    right=[(W*.90,H*.18),(W*.84,H*.32),(W*.91,H*.47),(W*.82,H*.65),(W*.89,H*.83)]
    d.line(left,fill=(220,175,78,150),width=4,joint='curve')
    d.line(right,fill=(169,91,239,150),width=4,joint='curve')
    # couture gemstone nodes
    for x,y,c in [(W*.15,H*.34,GOLD),(W*.86,H*.31,VIOLET),(W*.17,H*.66,YELLOW),(W*.83,H*.64,GOLD)]:
        d.ellipse((x-6,y-6,x+6,y+6),fill=c)
        d.ellipse((x-15,y-15,x+15,y+15),outline=(255,255,255,80),width=1)
    # sparse stardust
    random.seed(9)
    for _ in range(26):
        x=random.randrange(35,W-35); y=random.randrange(70,H-90)
        if W*.28<x<W*.72 and H*.06<y<H*.60: continue
        r=random.choice([1,1,2]); d.ellipse((x-r,y-r,x+r,y+r),fill=random.choice([(214,174,91,130),(178,107,240,125),(255,240,190,110)]))
    blur=fx.filter(ImageFilter.GaussianBlur(10)); blur.putalpha(blur.getchannel('A').point(lambda a:int(a*.34)))
    im=Image.alpha_composite(im,blur); im=Image.alpha_composite(im,fx)
    # editorial title
    dd=ImageDraw.Draw(im); fs=ImageFont.truetype(SERIF,25)
    dd.text((34,34),'COSMIC COUTURE',font=fs,fill=GOLD)
    return add_footer(im,'PEARL / GOLD / FUTURE',2)

def reality_glitch(src):
    W,H=src.size
    im=vignette(grade(src, shadow=(18,-12,50), color=.72, contrast=1.18, bright=.90),145)
    # chromatic channel displacement, clipped softly
    rgb=im.convert('RGB'); r,g,b=rgb.split()
    r=ImageChops.offset(r,7,0); b=ImageChops.offset(b,-7,0)
    shifted=Image.merge('RGB',(r,g,b)).convert('RGBA')
    im=Image.blend(im,shifted,.22)
    # fragmented reality slices: duplicate local strips with restrained offsets
    random.seed(18)
    for y,h,dx,opacity in [(238,34,22,135),(391,17,-28,120),(548,27,32,130),(755,14,-18,105),(927,24,25,95)]:
        strip=im.crop((0,y,W,min(H,y+h)))
        alpha=Image.new('L',strip.size,opacity)
        strip.putalpha(alpha)
        layer=Image.new('RGBA',(W,H),(0,0,0,0)); layer.paste(strip,(dx,y),strip)
        im=Image.alpha_composite(im,layer)
    fx=Image.new('RGBA',(W,H),(0,0,0,0)); d=ImageDraw.Draw(fx)
    # broken portal ellipses and version frames, avoiding eyes/lips
    d.arc((W*.12,H*.01,W*.88,H*.70),195,258,fill=(164,83,241,210),width=3)
    d.arc((W*.12,H*.01,W*.88,H*.70),282,344,fill=(247,211,62,215),width=3)
    d.arc((W*.18,H*.06,W*.82,H*.65),202,245,fill=(230,181,89,160),width=1)
    d.arc((W*.18,H*.06,W*.82,H*.65),294,336,fill=(230,181,89,160),width=1)
    # geometric reality windows at sides
    for i,(x,y,w,h,c) in enumerate([(32,330,112,210,VIOLET),(W-144,245,112,176,YELLOW),(47,720,92,130,GOLD),(W-129,690,84,145,VIOLET)]):
        d.rectangle((x,y,x+w,y+h),outline=c,width=2)
        d.line((x,y+18,x+w,y+18),fill=c,width=1)
        d.text((x+7,y+2),f'V.{i+1}',font=ImageFont.truetype(FONT,11),fill=c)
    # clean horizontal data strokes
    for yy,col in [(H*.18,VIOLET),(H*.50,GOLD),(H*.79,YELLOW)]:
        d.line((28,yy,145,yy),fill=col,width=2)
        d.line((W-145,yy,W-28,yy),fill=col,width=2)
    dd=ImageDraw.Draw(fx); fs=ImageFont.truetype(SERIF,25)
    dd.text((34,34),'REALITY GLITCH',font=fs,fill=YELLOW)
    soft=fx.filter(ImageFilter.GaussianBlur(7)); soft.putalpha(soft.getchannel('A').point(lambda a:int(a*.28)))
    im=Image.alpha_composite(im,soft); im=Image.alpha_composite(im,fx)
    return add_footer(im,'MULTIPLE VERSIONS ONLINE',3)

src=Image.open(SRC).convert('RGB')
cc=cosmic_couture(src); rg=reality_glitch(src)
cc.convert('RGB').save('/home/spazio/cosmos_luminosity_cosmic_couture.jpg',quality=96,subsampling=0)
rg.convert('RGB').save('/home/spazio/cosmos_luminosity_reality_glitch.jpg',quality=96,subsampling=0)

# comparison sheet, keeping all three full frames
bio=Image.open('/home/spazio/cosmos_luminosity_futuristic_mask_v1.jpg').convert('RGB')
items=[bio,cc.convert('RGB'),rg.convert('RGB')]
tw=360; th=480
sheet=Image.new('RGB',(tw*3,th+60),(13,7,22))
labels=['01 BIOINTERFACE','02 COSMIC COUTURE','03 REALITY GLITCH']
fd=ImageFont.truetype(FONT,18); sd=ImageDraw.Draw(sheet)
for i,(pic,label) in enumerate(zip(items,labels)):
    thumb=pic.resize((tw,th),Image.Resampling.LANCZOS)
    sheet.paste(thumb,(i*tw,0)); sd.text((i*tw+tw//2,th+26),label,font=fd,fill=(240,231,244),anchor='mm')
sheet.save('/home/spazio/cosmos_luminosity_three_styles.jpg',quality=95,subsampling=0)
print('created 3 outputs')
