import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from comrad import *


from kivymd.uix.label import MDLabel
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import AsyncImage, Image
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.card import MDCard, MDSeparator
from kivy.uix.scrollview import ScrollView
from screens.base import ProtectedScreen,BaseScreen
from kivy.properties import ListProperty
import os,time
from datetime import datetime
from kivy.app import App
from threading import Thread
import asyncio
from misc import *
from kivy.core.window import Window
import logging
logger=logging.getLogger(__name__)



### POST CODE
class PostTitle(MDLabel): pass
class PostGridLayout(GridLayout): pass
class PostImage(AsyncImage): pass
# class PostImage(CoreImage)
class PostImageBytes(Image): pass

class PostContent(MDLabel): 
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.bind(width=lambda s, w: s.setter('text_size')(s, (w, None)))
        self.bind(texture_size=self.setter('size'))
        self.font_name='assets/overpass-mono-regular.otf'
    #pass

class PostAuthorLayout(MDBoxLayout):
    pass

class PostImageLayout(MDBoxLayout): pass


class PostAuthorLabel(MDLabel): 
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.bind(width=lambda s, w: s.setter('text_size')(s, (w, None)))
        self.bind(texture_size=self.setter('size'))
        self.font_name='assets/overpass-mono-regular.otf'
        #self.to_changeable=False

    # def on_touch_down(self,*x,**y):
    #     print('weeeeeee')
    #     stop

    #def on_touch_down(self, touch):
        # '''Receive a touch down event.
        # :Parameters:
        #     `touch`: :class:`~kivy.input.motionevent.MotionEvent` class
        #         Touch received. The touch is in parent coordinates. See
        #         :mod:`~kivy.uix.relativelayout` for a discussion on
        #         coordinate systems.
        # :Returns: bool
        #     If True, the dispatching of the touch event will stop.
        #     If False, the event will continue to be dispatched to the rest
        #     of the widget tree.
        # '''
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            # username=self.text.strip().split()[1][1:]
            app=App.get_running_app()
            app.view_profile(self.username)
            return True

    pass

class PostTimestampLabel(MDLabel): 
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.bind(width=lambda s, w: s.setter('text_size')(s, (w, None)))
        self.bind(texture_size=self.setter('size'))
        self.font_name='assets/overpass-mono-regular.otf'

class PostAuthorAvatar(AsyncImage):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            app=App.get_running_app()
            app.view_profile(self.username)
            return True
        # stop
    pass

class PostLayout(MDBoxLayout): pass

class PostScrollView(ScrollView): pass

class PostCard(MDCard):
    @property
    def app(self): return App.get_running_app()
    def log(self,*x,**y): self.app.log(*x)

    def __init__(self, data):
        super().__init__()
        # self.log('PostCard() got data: '+str(data))
        self.author = data.get('author','[Anonymous]')
        self.recipient = data.get('to_name','')
        self.post_data = data.get('post_data', {})
        self.screen=data.get('screen')
        self.post_id=data.get('post_id')
        if not self.recipient:
            self.recipient=self.app.channel

        # self.img_id = data.get('file_id','')
        # self.img_ext = data.get('file_ext','')
        # self.img_src=self.img_id[:3]+'/'+self.img_id[3:]+'.'+self.img_ext if self.img_id else ''
        # self.cache_img_src = os.path.join('cache',self.img_src) if self.img_src else ''
        
        self.cache_img_src = self.img_src = data.get('img_src','')
        self.img_loaded = self.img_src and os.path.exists(self.img_src)
        self.content = data.get('content','')
        self.timestamp = data.get('timestamp',None)
        # self.bind(minimum_height=self.setter('height'))

        author_prefix=data.get('author_prefix','Comrad @')
        author_label_font_size=data.get('author_label_font_size','24sp')
        recip_label_font_size=data.get('author_label_font_size','14sp')
        
        # minwidth = 400
        # maxwidth = 800
        # abouts = int(Window.size[0]/1.5)
        # if abouts < minwidth: self.width=f'{minwidth}sp'
        # if abouts > maxwidth: self.width=f'{maxwidth}sp'
        # self.width=f'{abouts}sp'
    

        # self.log('PostCard.img_id =',self.img_id)
        # self.log('PostCard.img_ext =',self.img_ext)
        # self.log('PostCard.img_src =',self.img_src)
        # self.log('PostCard.cache_img_src =',self.cache_img_src)

        # pieces
        self.author_section_layout = author_section_layout = PostAuthorLayout()
        self.author_label = author_label = PostAuthorLabel(text=author_prefix+self.author)
        self.author_label.font_name='assets/overpass-mono-semibold.otf'
        if self.recipient:
            recip=self.recipient
            recip='@'+recip if not recip.startswith('@') else recip #(recip if recip and recip[0].isalpha() else recip[1:])
            # recip=author_prefix+recip #(recip if recip and recip[0].isalpha() else recip[1:])
            self.author_label.text+=f'\n[size={recip_label_font_size}]to '+recip+'[/size]'
            self.author_label.markup=True
        self.author_label.font_size = author_label_font_size
        self.author_label.username=self.author

        avatar_img_src = os.path.join(PATH_AVATARS, f'{self.author}.png')
        if not os.path.exists(avatar_img_src):
            avatar_img_src = os.path.join(PATH_GUI_ASSETS, 'avatars', f'{self.author}.png')
        if not os.path.exists(avatar_img_src): 
            avatar_img_src=PATH_DEFAULT_AVATAR
        self.author_avatar = author_avatar = PostAuthorAvatar(source=avatar_img_src) #self.img_src)
        self.author_avatar.username=self.author
        self.author_section_layout.add_widget(author_avatar)
        self.author_section_layout.add_widget(author_label)
        # self.author_section_layout.add_widget(MDSeparator(height='1sp',size_hint=(None,None)))

        # self.recipient_label = author_label = PostAuthorLabel(text='--> @'+self.recipient)
        # self.recipient_label.font_size = '14sp'
        # self.author_label.add_widget(self.recipient_label)
        

        # timestamp
        timestr=''
        #log(self.timestamp)
        if self.timestamp:
            dt_object = datetime.fromtimestamp(self.timestamp)
            timestr = dt_object.strftime("%-d %b %Y %H:%M") 
            #log('timestr: '+timestr)
            self.timestamp_label=PostTimestampLabel(text=timestr)
            self.timestamp_label.font_size='14sp'
            author_section_layout.add_widget(self.timestamp_label)
        # author_section_layout.add_widget(author_avatar)
        # self.add_widget(author_section_layout)

        if self.cache_img_src:
            image_layout = PostImageLayout()
            self.image = image = PostImage(source=self.cache_img_src)
            image.height = '300sp'
            image_layout.add_widget(image)
            image_layout.height='300sp'
            # self.log(image.image_ratio)

        self.post_content = PostContent(text=self.content)
        self.post_content.font_size = '24sp'

        
        # post_layout = PostGridLayout()
        #content = PostContent()

        # add to screen
        # self.add_widget(title)
        # post_layout.add_widget(author_section_layout)
        # post_layout.add_widget(image_layout)
        # post_layout.add_widget(content)

        
        self.scroller = scroller = PostScrollView()
        self.add_widget(author_section_layout)
        # self.add_widget(MDLabel(text='hello'))
        #log('img_src ' + str(bool(self.img_src)))
        if self.img_src: self.add_widget(image_layout)

        def estimate_height(minlen=100,maxlen=600):
            num_chars = len(self.content)
            # num_lines = num_chars
            height = num_chars*1.1
            if height>maxlen: height=maxlen
            if height<minlen: height=minlen
            return height

        scroller.size = ('300sp','%ssp' % estimate_height())
        

        # scroller.bind(size=('300sp',scroller.setter('height'))
        scroller.add_widget(self.post_content)
        self.add_widget(scroller)
        # self.add_widget(post_layout)


        ### 
        # Any prompts?
        if self.post_data.get('type')=='prompt':

            if self.post_data.get('prompt_id')=='addcontact':
                def on_touch_down(touch):
                    if hasattr(self,'_touched') and self._touched: return
                    if self.collide_point(*touch.pos):
                        asyncio.create_task(
                            self.app.prompt_addcontact(
                                self.post_data,
                                screen=self.screen,
                                post_id=self.post_id,
                                post_card=self,
                            )
                        )
                        # self._touched=True
                self.on_touch_down=on_touch_down








        # self.log('?????',self.cache_img_src, os.path.exists(self.cache_img_src), os.stat(self.cache_img_src).st_size)
        if self.cache_img_src and (not os.path.exists(self.cache_img_src) or not os.stat(self.cache_img_src).st_size):
            async def do_download_later():
                self.log('downloading...')
                await self.app.download(self.img_id, self.cache_img_src)
                self.image.reload()
                return True

            #self.open_dialog('posting')
            #Thread(target=do_download).start()
            asyncio.create_task(do_download_later())


    @property
    def app(self):
        return App.get_running_app()

    def load_image(self):
        if not self.img_src: return
        if self.img_loaded: return
        
        # otherwise load image...
        self.app.get_image(self.img_src)
        self.log('done getting image!')
        self.image.reload()
        self.img_loaded=True

#####


class PostCardPopup(PostCard):
    def __init__(self,*x,msg_dialog=None,**y):
        super().__init__(*x,**y)
        self.ok_to_continue=False
        self.msg_dialog=msg_dialog
    
    def on_touch_down(self,touch):
        # if self.collide_point(*touch.pos):# and not self.ok_to_continue:
            # logger.info('ouch!!!')
            # The touch has occurred inside the widgets area. Do stuff!
        self.ok_to_continue=True
        if self.msg_dialog: self.msg_dialog.ok_to_continue=True
        return True

class PostCardInputPopup(PostCardPopup):
    def on_touch_down(self,touch):
        pass




class FeedScreen(ProtectedScreen):
    posts = ListProperty()
    updated = None

    def on_pre_enter(self):
        if not super().on_pre_enter(): return
        if self.updated:
            if False: # @HACK!!!
            # if not self.app.comrad.updated or self.updated>=self.app.comrad.updated:
                self.log('NOT UPDATING!')
                return
        # self.root.clear_widgets()
        self.log('UPDATING!')
        if self.app.map:
            self.app.map.dismiss()
            self.root.remove_widget(self.app.map)
        if not hasattr(self,'get_posts'): self.get_posts=self.app.comrad.posts
        
        self.carousel = self.ids.post_carousel
        for post in self.posts:
            self.ids.post_carousel.remove_widget(post)
        
        i=0
        lim=25

        async def go():
            # do not get updates! leave that to refresh button!
            # await self.app.get_updates()
            
            posts=self.get_posts()
            for i,post in enumerate(posts):
                if i>lim: break
                data = {
                    'author':post.from_name,
                    'to_name':post.to_name,
                    'content':post.msg.get('txt') if type(post.msg)==dict else str(post.msg),
                    'timestamp':post.timestamp,
                    'post_data':post.data,
                    'screen':self,
                    'post_id':post.post_id,
                }
                post_obj = PostCard(data)
                self.posts.append(post_obj)
                self.ids.post_carousel.add_widget(post_obj)
                self.updated = time.time()

        asyncio.create_task(go())
        return True
    # def on_pre_enter(self):
    #     self.clear_deck()
    #     # for i,x 


