package model

import (
	"crawler/config"
	"crawler/service"
	"database/sql"
	"encoding/json"
)

type MovieDetailModel struct {
	MovieDetail
	Poster
	StillCut
	MovieDetailTable
}

type MovieDetail struct {
	MovieCd  string
	MainImg  string
	ThumbImg string
	Poster   []Poster
	StillCut []StillCut
	Synopsis string
	SaleAcc  int
	AudiAcc  int
}

type Poster struct {
	Thumb  string
	Origin string
}

type StillCut struct {
	Thumb  string
	Origin string
}

type MovieDetailTable struct {
	DetailID  int
	MovieCd   string
	MainImg   *string
	ThumbImg  *string
	Poster    *string
	StillCut  *string
	Synopsis  *string
	SaleAcc   *int
	AudiAcc   *int
	UpdatedAt *string
	CreatedAt string
}

func (this *MovieDetailModel) Insert(row MovieDetail) error {
	var (
		db    = service.DB_MOVIEW
		conn  = db.SQLDB
		query = `
			INSERT INTO tb_movie_detail (
				movie_cd, main_img, thumb_img, poster, stillcut, 
			    synopsis, sale_acc, audi_acc, updated_at, created_at
			)
			VALUES 
				(?, ?, ?, ?, ?, ?, ?, ?, NULL, NOW())
			ON DUPLICATE KEY UPDATE 
				main_img = VALUES(main_img), thumb_img = VALUES(thumb_img), 
				poster = VALUES(poster), stillcut = VALUES(stillcut), 
				synopsis = VALUES(synopsis), sale_acc = VALUES(sale_acc), 
				audi_acc = VALUES(audi_acc), updated_at = NOW();
		`
		data = this.DataFilter(row)
	)

	_, err := conn.Exec(query, data.MovieCd, data.MainImg, data.ThumbImg, data.Poster, data.StillCut, data.Synopsis, data.SaleAcc, data.AudiAcc)
	if err != nil {
		db.SetErrorLog(err, query)
		return err
	}

	db.SetGeneralLog(config.GL_ACTION_WRITE, query, "insert movie detail")
	return nil
}

func (this *MovieDetailModel) IsExists(movieCd string) bool {
	var (
		db   = service.DB_MOVIEW
		conn = db.SQLDB
		// query  = "SELECT IF(COUNT(*) <= 0, 0, 1) AS `exists` FROM tb_movie_detail WHERE movie_cd = ? AND thumb_img IS NOT NULL;"
		query  = "SELECT IF(COUNT(*) <= 0, 0, 1) AS `exists` FROM tb_movie_detail WHERE movie_cd = ?;"
		exists = false
	)

	err := conn.QueryRow(query, movieCd).Scan(&exists)
	if err != nil {
		db.SetErrorLog(err, query)
		return exists
	}

	db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select exists movie detail")
	return exists
}

func (this *MovieDetailModel) Update(row MovieDetail) error {
	var (
		db    = service.DB_MOVIEW
		conn  = db.SQLDB
		query = `
			UPDATE tb_movie_detail SET 
				main_img = ?, thumb_img = ?, poster = ?, stillcut = ?, 
			    synopsis = ?, sale_acc = ?, audi_acc = ?, updated_at = NOW()
			WHERE movie_cd = ?;
		`
		data = this.DataFilter(row)
	)

	_, err := conn.Exec(query,
		data.MainImg, data.ThumbImg, data.Poster, data.StillCut,
		data.Synopsis, data.SaleAcc, data.AudiAcc, data.MovieCd)
	if err != nil {
		db.SetErrorLog(err, query)
		return err
	}

	db.SetGeneralLog(config.GL_ACTION_MODIFY, query, "update movie detail")
	return nil
}

func (this *MovieDetailModel) DataFilter(row MovieDetail) MovieDetailTable {
	var result MovieDetailTable
	result.MovieCd = row.MovieCd

	if row.MainImg != "" && row.MainImg != "#" {
		result.MainImg = &row.MainImg
	} else {
		result.MainImg = nil
	}

	if row.ThumbImg != "" && row.ThumbImg != "#" {
		result.ThumbImg = &row.ThumbImg
	} else {
		result.ThumbImg = nil
	}

	if len(row.Poster) > 0 {
		poster, _ := json.Marshal(row.Poster)
		s := string(poster)
		result.Poster = &s
	}

	if len(row.StillCut) > 0 {
		stillCut, _ := json.Marshal(row.StillCut)
		s := string(stillCut)
		result.StillCut = &s
	}

	if row.Synopsis != "" {
		result.Synopsis = &row.Synopsis
	} else {
		result.Synopsis = nil
	}

	if row.SaleAcc != 0 {
		result.SaleAcc = &row.SaleAcc
	}

	if row.AudiAcc != 0 {
		result.AudiAcc = &row.AudiAcc
	}

	return result
}

func (this *MovieDetailModel) Info(movieCd string) (MovieDetailTable, error) {
	var (
		db     = service.DB_MOVIEW
		conn   = db.SQLDB
		query  = "SELECT * FROM tb_movie_detail WHERE movie_cd = ?"
		detail MovieDetailTable
	)

	err := conn.QueryRow(query, movieCd).Scan(
		&detail.DetailID, &detail.MovieCd, &detail.MainImg,
		&detail.ThumbImg, &detail.Poster, &detail.StillCut,
		&detail.Synopsis, &detail.SaleAcc, &detail.AudiAcc,
		&detail.UpdatedAt, &detail.CreatedAt,
	)

	if err != nil && err != sql.ErrNoRows {
		db.SetErrorLog(err, query)
		return detail, err
	}

	db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select movie detail")
	return detail, nil
}
