#!/usr/bin/env python3

from datetime import datetime

from .Items import Manga
from .Items import Chapter

DATE_FORMAT = '%Y-%m-%d %H:%M:%S'


class MangaManager():

  def __init__(self, mmachine, db, connection):
    self.db = db
    self.connection = connection
    self.mmachine = mmachine
    self.log = self.mmachine.getLoggerFor(self)


  def getAllManga(self):
    self.log.info('getAllManga == Get all manga')
    query = 'SELECT Id, Name, Module, LastChapter, CheckValue, FolderName, LastUpdate FROM Manga ORDER BY Name'
    self.db.execute(query)
    
    manga_list = []
    results = self.db.fetchall()
    for data in results:
      manga = self.createMangaFromDB(data)
      manga_list.append(manga)
    
    #sorted(manga_list, key = lambda manga : manga.getName())
    
    return sorted(manga_list, key=lambda manga: manga.getName())


  def addResultToArchive(self, result, last_chapter):
    # add result to archive
    self.log.info('addResultToArchive == Add result: ' + result.name + ', last chapter:' + str(last_chapter))
    query = 'INSERT INTO Manga(Name, Module, LastChapter, CheckValue, FolderName, LastUpdate) VALUES (?,?,?,1,?,?)'
    folder_name = result.name.replace('/', '_')
    now = datetime.now()
    last_update = now.strftime(DATE_FORMAT)
    self.db.execute(query, (result.name, result.module.name, str(last_chapter), folder_name, last_update))
    self.connection.commit()
    last_inserted_id = self.db.lastrowid
    
    manga = self.getMangaFromId(last_inserted_id)
    return manga
  
  
  def getMangaFromId(self, manga_id):
    query = 'SELECT Id, Name, Module, LastChapter, CheckValue, FolderName, LastUpdate FROM Manga WHERE Id = ?'
    self.db.execute(query, (manga_id,))
    data = self.db.fetchone()
    manga = self.createMangaFromDB(data)
    return manga
  
  
  def addChapterToManga(self, manga, chapter):
    self.addChaptersToManga(manga, [chapter])
  
  
  def addChaptersToManga(self, manga, chapters):
    arg_list = []
    ''' NOTE: if I have a duplicate chapter the query stops before trying to add the other chapters
    for chapter in chapters:
      arg_list.append( (chapter.getNumber(), manga.id) )
    query = 'INSERT INTO Chapters(Number, MangaId) VALUES (?,?)'
    try:
      self.db.executemany( query, arg_list )
    except Exception:
      pass # Some chapter numbers were already in the table, not a problem
    '''
    query = 'INSERT INTO Chapters(Number, MangaId) VALUES (?,?)'
    for chapter in chapters:
      try:
        self.db.execute(query, (chapter.getNumber(), manga.id))
      except Exception:
        # duplicate chapter, not a problem
        pass
    self.connection.commit()

  
  def refreshLastUpdateTime(self, manga):
    query = 'UPDATE Manga SET LastUpdate = ? WHERE Id = ?'
    now = datetime.now()
    now_str = now.strftime(DATE_FORMAT)
    self.db.execute(query, (now_str, manga.id))
    self.connection.commit()
  
  
  def setLastChapter(self, manga, chapter):
    query = 'UPDATE Manga SET LastChapter = ? WHERE Id = ?'
    self.db.execute(query, (str(chapter), manga.id))
    self.connection.commit()
  
  
  def removeChaptersFromManga(self, manga, chapters):
    arg_list = []
    for chapter in chapters:
      arg_list.append((manga.id, chapter.getNumber()))
    query = 'DELETE FROM Chapters WHERE MangaId = ? AND Number = ?'
    self.db.executemany(query, arg_list)
    self.connection.commit()
    
  
  def editManga(self, manga, name, last_chapter, folder_name, check):
    query = 'UPDATE Manga SET Name = ?, LastChapter = ?, FolderName = ?, CheckValue = ? WHERE Id = ?'
    self.db.execute(query, (name, last_chapter, folder_name, check, manga.id))
    self.connection.commit()
  
  
  def changeModuleFor(self, manga, new_module_name):
    query = 'UPDATE Manga SET Module = ? WHERE Id = ?'
    self.db.execute(query, (new_module_name, manga.id))
    self.connection.commit()
  
  
  def removeManga(self, manga):
    # delete OPT
    self.removeOPTFiles(manga)
    
    # delete chapters
    self.removeAllChapters(manga)
    
    # delete manga entry
    query = 'DELETE FROM Manga WHERE Id = ?'
    self.db.execute(query, (manga.id,))
    
    self.connection.commit()
  
  
  def removeOPTFiles(self, manga):
    if manga.module is not None:
      manga_ext = manga.module.getMangaEXT(manga)
      manga.module.deleteManga(manga_ext)
    # NOTE: i may use manga_ext.delete() directly
    
  
  def removeAllChapters(self, manga):
    query = 'DELETE FROM Chapters WHERE MangaId = ?'
    self.db.execute(query, (manga.id,))
    self.connection.commit()
    
  
  def getChapters(self, manga):
    query = 'SELECT Id, Number, MangaId FROM Chapters WHERE MangaId = ?'
    self.db.execute(query, (manga.id,))
    chapters_list = []
    results = self.db.fetchall()
    for data in results:
      chapter = self.createChapterFromDB(data, manga)
      chapters_list.append(chapter)
    
    return chapters_list
  
  
  def createMangaFromDB(self, data):
    manga = Manga.new()
    manga.id = data[0]
    manga.name = data[1]
    manga.module_name = data[2]
    if manga.module_name in self.mmachine.modules:
      mod = self.mmachine.modules[manga.module_name]
      manga.setModule(mod)
    manga.last_chapter = Chapter.ChapterNumber(data[3])
    manga.check = int(data[4])
    manga.folder_name = data[5]
    manga.last_update = datetime.strptime(data[6], DATE_FORMAT)
    return manga


  def createChapterFromDB(self, data, manga):
    chapter = Chapter.new()
    chapter.id = data[0]
    chapter.setNumber(data[1])
    chapter.setManga(manga)
    
    return chapter


def create(mmachine):
  mm = MangaManager(mmachine, mmachine.manga_db, mmachine.manga_db_connection)  
  return mm
