package main

import (
	"context"
	"database/sql"
	"fmt"
	"strconv"

	"github.com/golang/glog"
	"github.com/golang/protobuf/proto"
	_ "github.com/mattn/go-sqlite3"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	pb "code.hackerspace.pl/hscloud/proto/invoice"
)

type model struct {
	db *sql.DB
}

func newModel(dsn string) (*model, error) {
	db, err := sql.Open("sqlite3", dsn)
	if err != nil {
		return nil, err
	}
	return &model{
		db: db,
	}, nil
}

func (m *model) init() error {
	_, err := m.db.Exec(`
		create table invoice (
			id integer primary key not null,
			proto blob not null
		);
		create table invoice_seal (
			id integer primary key not null,
			invoice_id integer not null,
			final_uid text not null unique,
			foreign key (invoice_id) references invoice(id)
		);
		create table invoice_blob (
			id integer primary key not null,
			invoice_id integer not null,
			pdf blob not null,
			foreign key (invoice_id) references invoice(id)
		);
	`)
	return err
}

func (m *model) sealInvoice(ctx context.Context, uid string) error {
	id, err := strconv.Atoi(uid)
	if err != nil {
		return status.Error(codes.InvalidArgument, "invalid uid")
	}

	invoice, err := m.getInvoice(ctx, uid)
	if err != nil {
		return err
	}

	tx, err := m.db.BeginTx(ctx, nil)
	if err != nil {
		return err
	}

	q := `
		insert into invoice_seal (
			invoice_id, final_uid
		) values (
			?,
			( select printf("%04d", ifnull( (select final_uid as v from invoice_seal order by final_uid desc limit 1), 19000) + 1 ))
		)

	`
	res, err := tx.Exec(q, id)
	if err != nil {
		return err
	}

	lastInvoiceSealId, err := res.LastInsertId()
	if err != nil {
		return err
	}

	q = `
		select final_uid from invoice_seal where id = ?
	`

	var finalUid string
	if err := tx.QueryRow(q, lastInvoiceSealId).Scan(&finalUid); err != nil {
		return err
	}

	q = `
		insert into invoice_blob (
			invoice_id, pdf
		) values (
			?,
			?
		)
	`

	pdfBlob, err := renderInvoicePDF(invoice, finalUid, false)
	if err != nil {
		return err
	}

	if _, err := tx.Exec(q, id, pdfBlob); err != nil {
		return err
	}

	if err := tx.Commit(); err != nil {
		return err
	}

	return nil
}

func (m *model) createInvoice(ctx context.Context, i *pb.Invoice) (string, error) {
	data, err := proto.Marshal(i)
	if err != nil {
		return "", err
	}

	sql := `
		insert into invoice (
			proto
		) values (
			?
		)
	`
	res, err := m.db.Exec(sql, data)
	if err != nil {
		return "", err
	}
	id, err := res.LastInsertId()
	if err != nil {
		return "", err
	}

	glog.Infof("%+v", id)
	return fmt.Sprintf("%d", id), nil
}

func (m *model) getRendered(ctx context.Context, uid string) ([]byte, error) {
	id, err := strconv.Atoi(uid)
	if err != nil {
		return nil, status.Error(codes.InvalidArgument, "invalid uid")
	}

	q := `
		select invoice_blob.pdf from invoice_blob where invoice_blob.invoice_id = ?
	`
	res := m.db.QueryRow(q, id)

	data := []byte{}
	if err := res.Scan(&data); err != nil {
		if err == sql.ErrNoRows {
			return nil, status.Error(codes.InvalidArgument, "no such invoice")
		}
		return nil, err
	}
	return data, nil
}

func (m *model) getSealedUid(ctx context.Context, uid string) (string, error) {
	id, err := strconv.Atoi(uid)
	if err != nil {
		return "", status.Error(codes.InvalidArgument, "invalid uid")
	}

	q := `
		select invoice_seal.final_uid from invoice_seal where invoice_seal.invoice_id = ?
	`
	res := m.db.QueryRow(q, id)
	finalUid := ""
	if err := res.Scan(&finalUid); err != nil {
		if err == sql.ErrNoRows {
			return "", nil
		}
		return "", err
	}
	return finalUid, nil
}

func (m *model) getInvoice(ctx context.Context, uid string) (*pb.Invoice, error) {
	id, err := strconv.Atoi(uid)
	if err != nil {
		return nil, status.Error(codes.InvalidArgument, "invalid uid")
	}

	q := `
		select invoice.proto from invoice where invoice.id = ?
	`
	res := m.db.QueryRow(q, id)
	data := []byte{}
	if err := res.Scan(&data); err != nil {
		if err == sql.ErrNoRows {
			return nil, status.Error(codes.NotFound, "no such invoice")
		}
		return nil, err
	}

	p := &pb.Invoice{}
	if err := proto.Unmarshal(data, p); err != nil {
		return nil, err
	}
	return p, nil
}

type invoice struct {
	ID       int64
	Number   string
	Sealed   bool
	Proto    *pb.Invoice
	TotalNet int
	Total    int
}

func (m *model) getInvoices(ctx context.Context) ([]invoice, error) {
	q := `
		select invoice_seal.final_uid, invoice.id, invoice.proto from invoice
		left join invoice_seal
		on invoice_seal.invoice_id = invoice.id
	`
	rows, err := m.db.QueryContext(ctx, q)
	if err != nil {
		return []invoice{}, err
	}
	defer rows.Close()

	res := []invoice{}
	for rows.Next() {
		i := invoice{
			Proto: &pb.Invoice{},
		}
		buf := []byte{}

		number := sql.NullString{}
		if err := rows.Scan(&number, &i.ID, &buf); err != nil {
			return []invoice{}, err
		}

		if err := proto.Unmarshal(buf, i.Proto); err != nil {
			return []invoice{}, err
		}

		if number.Valid {
			i.Sealed = true
			i.Number = number.String
		} else {
			i.Number = "proforma"
		}

		i.Total = 0
		i.TotalNet = 0
		for _, it := range i.Proto.Item {
			rowTotalNet := int(it.UnitPrice * it.Count)
			rowTotal := int(float64(rowTotalNet) * (float64(1) + float64(it.Vat)/100000))
			i.TotalNet += rowTotalNet
			i.Total += rowTotal
		}

		res = append(res, i)
	}

	return res, nil
}
