from typing import Any, List, Optional
from datetime import datetime

from fastapi import APIRouter, Body, Depends, HTTPException, Form, status, Response
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr, HttpUrl
from sqlalchemy.orm import Session

import app.crud as crud
import app.models as models
import app.schemas as schemas 
from app.api import deps
from app.core.config import settings
from app.core.ecpay_payment_sdk import ECPayPaymentSdk
from app.utils import send_new_account_email
from pydantic import BaseModel
import requests
from random import choice
import string
import json

router = APIRouter()

@router.post('/ecpay-test-payment')
def ecpay_payment(
  *,
  db: Session = Depends(deps.get_db),
  current_user: models.User = Depends(deps.get_current_active_user),
  payment_data: schemas.PaymentCreate,
  lang: str=''
):  
    print(payment_data)
    MerchantTradeNo = 'test'+datetime.now().strftime("NO%Y%m%d%H%M%S")
    remark = {'MerchantTradeNo':MerchantTradeNo}
    remark_string = json.dumps(remark, ensure_ascii=False)
    payment = crud.payment.create_with_payment_data(db, 
                                                    obj_in=payment_data,
                                                    owner_id=current_user.id, 
                                                    epayment='ecpay',
                                                    remark=remark_string)
    items = payment_data.item
    items = items.split("#")
    print(payment.item)
    content = {}
    for item in items:
      pair = item.split()
      content[str(pair[0]).lower()] = pair[1]
    content_string = json.dumps(content, ensure_ascii=False).replace('"', "'")
    order_params = {
        'MerchantTradeNo': MerchantTradeNo,
        'StoreID': 'SaaS',
        'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
        'PaymentType': 'aio',
        'TotalAmount': payment_data.amount,
        'TradeDesc': 'SaaS訂單',
        'ItemName': payment_data.item,
        'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ecpay-result-return',
        'ChoosePayment': 'ALL',
        'ClientBackURL': 'https://cloud.choozmo.com/test-payment',
        'ItemURL': 'https://cloud.choozmo.com/test-payment',
        'Remark': '',
        'ChooseSubPayment': '',
        'OrderResultURL': '',
        'NeedExtraPaidInfo': 'Y',
        'DeviceSource': '',
        'IgnorePayment': 'ATM#CVS#BARCODE',
        'PlatformID': '',
        'InvoiceMark': 'N',
        'CustomField1': f'{str(payment.id)}',
        'CustomField2': f'{str(current_user.id)}',
        'CustomField3': content_string,
        'CustomField4': '',
        'EncryptType': 1,
        'Language': lang,
    }
    print(order_params)
    extend_params_1 = {
        'ExpireDate': 7,
        'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
        'ClientRedirectURL': '',
    }

    extend_params_2 = {
        'StoreExpireDate': 15,
        'Desc_1': '',
        'Desc_2': '',
        'Desc_3': '',
        'Desc_4': '',
        'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
        'ClientRedirectURL': '',
    }

    extend_params_3 = {
        'BindingCard': 0,
        'MerchantMemberID': '',
    }

    extend_params_4 = {
        'Redeem': 'N',
        'UnionPay': 0,
    }

    inv_params = {
        # 'RelateNumber': 'Tea0001', # 特店自訂編號
        # 'CustomerID': 'TEA_0000001', # 客戶編號
        # 'CustomerIdentifier': '53348111', # 統一編號
        # 'CustomerName': '客戶名稱',
        # 'CustomerAddr': '客戶地址',
        # 'CustomerPhone': '0912345678', # 客戶手機號碼
        # 'CustomerEmail': 'abc@ecpay.com.tw',
        # 'ClearanceMark': '2', # 通關方式
        # 'TaxType': '1', # 課稅類別
        # 'CarruerType': '', # 載具類別
        # 'CarruerNum': '', # 載具編號
        # 'Donation': '1', # 捐贈註記
        # 'LoveCode': '168001', # 捐贈碼
        # 'Print': '1',
        # 'InvoiceItemName': '測試商品1|測試商品2',
        # 'InvoiceItemCount': '2|3',
        # 'InvoiceItemWord': '個|包',
        # 'InvoiceItemPrice': '35|10',
        # 'InvoiceItemTaxType': '1|1',
        # 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
        # 'DelayDay': '0', # 延遲天數
        # 'InvType': '07', # 字軌類別
    }

    # 建立實體
    ecpay_payment_sdk = ECPayPaymentSdk(
        MerchantID='3002607',
        HashKey='pwFHCqoQZGmho4w6',
        HashIV='EkRm7iFT261dpevs'
    )

    # 合併延伸參數
    order_params.update(extend_params_1)
    order_params.update(extend_params_2)
    order_params.update(extend_params_3)
    order_params.update(extend_params_4)

    # 合併發票參數
    order_params.update(inv_params)
    try:
        # 產生綠界訂單所需參數
        final_order_params = ecpay_payment_sdk.create_order(order_params)

        # 產生 html 的 form 格式
        action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5'  # 測試環境
        # action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
        html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)
        
        return html
    except Exception as error:
        print('An exception happened: ' + str(error))
        
@router.post('/ecpay-payment')
def ecpay_payment(
  *,
  db: Session = Depends(deps.get_db),
  current_user: models.User = Depends(deps.get_current_active_user),
  payment_data: schemas.PaymentCreate,
  lang: str=''
):
    print(payment_data)
    numbers = string.digits
    randomNumber = ''.join(choice(numbers) for _ in range(4))
    MerchantTradeNo = datetime.now().strftime("%Y%m%d%H%M%SNO")+randomNumber
    remark = {'MerchantTradeNo':MerchantTradeNo}
    remark_string = json.dumps(remark, ensure_ascii=False)
    payment = crud.payment.create_with_payment_data(db, 
                                                    obj_in=payment_data,
                                                    owner_id=current_user.id, 
                                                    epayment='ecpay',
                                                    remark=remark_string)
    items = payment_data.item
    items = items.split("#")
    print(payment.item)
    content = {}
    for item in items:
      pair = item.split()
      content[str(pair[0]).lower()] = pair[1]
    content_string = json.dumps(content, ensure_ascii=False).replace('"', "'")
    order_params = {
        'MerchantTradeNo': MerchantTradeNo,
        'StoreID': 'SaaS',
        'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
        'PaymentType': 'aio',
        'TotalAmount': payment_data.amount,
        'TradeDesc': 'SaaS訂單',
        'ItemName': payment_data.item,
        'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ecpay-result-return',
        'ChoosePayment': 'ALL',
        'ClientBackURL': 'https://cloud.choozmo.com/main/dashboard',
        'ItemURL': 'https://cloud.choozmo.com/main/dashboard',
        'Remark': '',
        'ChooseSubPayment': '',
        'OrderResultURL': '',
        'NeedExtraPaidInfo': 'Y',
        'DeviceSource': '',
        'IgnorePayment': 'ATM#CVS#BARCODE',
        'PlatformID': '',
        'InvoiceMark': 'N',
        'CustomField1': str(payment.id),
        'CustomField2': str(current_user.id),
        'CustomField3': content_string,
        'CustomField4': '',
        'EncryptType': 1,
        'Language': lang,
    }

    extend_params_1 = {
        'ExpireDate': 7,
        'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
        'ClientRedirectURL': '',
    }

    extend_params_2 = {
        'StoreExpireDate': 15,
        'Desc_1': '',
        'Desc_2': '',
        'Desc_3': '',
        'Desc_4': '',
        'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
        'ClientRedirectURL': '',
    }

    extend_params_3 = {
        'BindingCard': 0,
        'MerchantMemberID': '',
    }

    extend_params_4 = {
        'Redeem': 'N',
        'UnionPay': 0,
    }

    inv_params = {
        # 'RelateNumber': 'Tea0001', # 特店自訂編號
        # 'CustomerID': 'TEA_0000001', # 客戶編號
        # 'CustomerIdentifier': '53348111', # 統一編號
        # 'CustomerName': '客戶名稱',
        # 'CustomerAddr': '客戶地址',
        # 'CustomerPhone': '0912345678', # 客戶手機號碼
        # 'CustomerEmail': 'abc@ecpay.com.tw',
        # 'ClearanceMark': '2', # 通關方式
        # 'TaxType': '1', # 課稅類別
        # 'CarruerType': '', # 載具類別
        # 'CarruerNum': '', # 載具編號
        # 'Donation': '1', # 捐贈註記
        # 'LoveCode': '168001', # 捐贈碼
        # 'Print': '1',
        # 'InvoiceItemName': '測試商品1|測試商品2',
        # 'InvoiceItemCount': '2|3',
        # 'InvoiceItemWord': '個|包',
        # 'InvoiceItemPrice': '35|10',
        # 'InvoiceItemTaxType': '1|1',
        # 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
        # 'DelayDay': '0', # 延遲天數
        # 'InvType': '07', # 字軌類別
    }

    # 建立實體
    ecpay_payment_sdk = ECPayPaymentSdk(
        MerchantID='3226141',
        HashKey='OhcjDTeXK9PKW9vb',
        HashIV='AfOmUM06S0bt8KPE'
    )

    # 合併延伸參數
    order_params.update(extend_params_1)
    order_params.update(extend_params_2)
    order_params.update(extend_params_3)
    order_params.update(extend_params_4)

    # 合併發票參數
    order_params.update(inv_params)
    try:
        # 產生綠界訂單所需參數
        final_order_params = ecpay_payment_sdk.create_order(order_params)

        # 產生 html 的 form 格式
        # action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5'  # 測試環境
        action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
        html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)

        return html
    except Exception as error:
        print('An exception happened: ' + str(error))


@router.get('/list-all', response_model=List[schemas.YTViews])
def get_list(
  *,
  db: Session = Depends(deps.get_db),
):
  ytviews_list = crud.ytviews.get_multi(db)
  return ytviews_list

@router.post("/ecpay-result-return")
def ecpay_return(
    *,
    db: Session = Depends(deps.get_db),
    MerchantID: Optional[str]=Form(None),
    MerchantTradeNo: Optional[str]=Form(None),
    StoreID: Optional[str]=Form(None),
    RtnCode: Optional[int]=Form(None),
    RtnMsg: Optional[str]=Form(None),
    TradeNo: Optional[str]=Form(None),
    TradeAmt: Optional[int]=Form(None),
    PaymentDate: Optional[str]=Form(None),
    PaymentType: Optional[str]=Form(None),
    PaymentTypeChargeFee: Optional[int]=Form(None),
    TradeDate: Optional[str]=Form(None),
    SimulatePaid: Optional[int]=Form(None),
    CustomField1: Optional[str]=Form(None),
    CustomField2: Optional[str]=Form(None),
    CustomField3: Optional[str]=Form(None),
    CustomField4: Optional[str]=Form(None),
    CheckMacValue: Optional[str]=Form(None),
) -> Any:
  #送email
  print(f"\
MerchantID: {MerchantID} \n\
MerchantTradeNo: {MerchantTradeNo}\n\
StoreID: {StoreID}\n\
RtnCode: {RtnCode}\n\
RtnMsg: {RtnMsg}\n\
TradeNo: {TradeNo}\n\
TradeAmt: {TradeAmt}\n\
PaymentDate: {PaymentDate}\n\
PaymentType: {PaymentType}\n\
PaymentTypeChargeFee: {PaymentTypeChargeFee}\n\
TradeDate: {TradeDate}\n\
SimulatePaid: {SimulatePaid}\n\
CustomField1: {CustomField1}\n\
CustomField2: {CustomField2}\n\
CustomField3: {CustomField3}\n\
CustomField4: {CustomField4}\n\
CheckMacValue: {CheckMacValue}\
  ")
  
  if RtnCode==1:
    payment_id = int(CustomField1)
    payment = crud.payment.get(db=db, id=payment_id)
    remark = json.loads(payment.remark)
    remark['TradeNo'] = TradeNo
    payment = crud.payment.update(db, db_obj=payment, obj_in={"payment_state":"succeeded", "remark":json.dumps(remark, ensure_ascii=False)})
    content_string = CustomField3.replace("'",'"')
    content:dict = json.loads(content_string)
    user_id = int(CustomField2)
    user = crud.user.get(db=db, id=user_id)
    if 'credit' in content.keys():
      add_credit = content['credit']
      crud.user.update(db, db_obj=user, obj_in={"available_time": user.available_time + int(add_credit)})
  else:  
    payment = crud.payment.update(db, db_obj=payment, obj_in={"payment_state":"failed", "remark":json.dumps(remark, ensure_ascii=False)})
  return Response(content='1', status_code=status.HTTP_200_OK)
