using AR;
using Org.BouncyCastle.Pkcs;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UniMarc
{
    public partial class Marc_FillBlank : Form
    {
        public string ISBN;
        public string SingleMarcResult { get; private set; }
        public List<FillBlankItem> FillBlankItems => _items;
        bool isAll;
        bool isBreak;
        List<FillBlankItem> _items = new List<FillBlankItem>();

        public Marc_FillBlank()
        {
            InitializeComponent();
            bs1.DataSource = _items;
            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.DataSource = bs1;

            // Map columns manually if not done in designer, but assuming designer has columns
            // We need to map DataPropertyName.
            if (dataGridView1.Columns["List_idx"] != null) dataGridView1.Columns["List_idx"].DataPropertyName = "Idx";
            if (dataGridView1.Columns["ISBN13"] != null) dataGridView1.Columns["ISBN13"].DataPropertyName = "Isbn";
            if (dataGridView1.Columns["BookName"] != null) dataGridView1.Columns["BookName"].DataPropertyName = "BookName";
            // Check other column names?
            // "BookMarc" was accessed by name.
            if (dataGridView1.Columns["BookMarc"] != null) dataGridView1.Columns["BookMarc"].DataPropertyName = "BookMarc";
            // Author, Publisher, Price?
            // InitFillBlank accepts: [3]저자 [4]출판사 [5]가격
            // We should guess column names if not visible or just assume they are bound if user set them up or I set them.
            // Let's assume standard names or index binding is replaced by name binding.
            // But wait, user said "bs1 is pre-made" (meaning in designer possibly?). If so, I shouldn't 'new' it if it's protected?
            // "bs1은 미리 만들어뒀어" implies I might access it. 
            // In my previous step I saw NO bs1 in the file. So I adding it is safe if I make it matching.
        }

        private void Marc_FillBlank_Load(object sender, EventArgs e)
        {
            webBrowser1.Navigate(MakeURL(ISBN));
        }

        /// <summary>
        /// 입력된 ISBN으로 코리스URL을 생성함.
        /// </summary>
        /// <param name="ISBN"></param>
        /// <returns></returns>
        string MakeURL(string ISBN)
        {
            return string.Format(
                "https://nl.go.kr/kolisnet/search/searchResultAllList.do?" +
                "tab=ALL&" +
                "historyYn=Y&" +
                "keywordType1=total&" +
                "keyword1={0}&" +
                "bookFilter=BKGM&" +
                "bookFilter=YON&" +
                "bookFilter=BKDM&" +
                "bookFilter=NK&" +
                "bookFilter=NP&" +
                "bookFilter=OT", ISBN);
        }

        /// <summary>
        /// 옆 그리드에 채울 정보를 입력
        /// </summary>
        /// <param name="item">FillBlankItem 객체</param>
        public void InitFillBlank(FillBlankItem item)
        {
            _items.Add(item);
            bs1.ResetBindings(false);
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            tb_URL.Text = webBrowser1.Url.AbsoluteUri;

            if (isAll)
            {
                if (tb_URL.Text.Contains("searchResultAllList"))
                    InitCrowling();

                if (tb_URL.Text.Contains("searchResultEditonList"))
                    SearchResultEditonList();

                if (tb_URL.Text.Contains("searchResultDetail"))
                    SearchResultDetail();

                if (tb_URL.Text.Contains("searchResultMarc"))
                    SearchResultMarc();
            }
        }
        #region Completed SUB

        /// <summary>
        /// 코리스에서 ISBN검색이 된 목록 중 맨 첫번째만 클릭해주는 함수.
        /// </summary>
        private void InitCrowling()
        {
            string resultCount = "";

            HtmlElementCollection span = webBrowser1.Document.GetElementsByTagName("span");
            foreach (HtmlElement Search in span)
            {
                if (Search.GetAttribute("className") == "result_count")
                {
                    resultCount = Search.InnerText;
                    break;
                }
            }

            if (resultCount.Contains("0"))
            {
                isBreak = true;
                return;
            }

            HtmlElementCollection div = webBrowser1.Document.GetElementsByTagName("div");
            foreach (HtmlElement SearchDiv in div)
            {
                if (SearchDiv.GetAttribute("className") == "resultBookInfo")
                {
                    SearchDiv.Children[0].Children[0].InvokeMember("click");
                    break;
                }
            }
        }

        /// <summary>
        /// 도서의 상세 정보를 보여주는 페이지로 들어가는 함수
        /// </summary>
        private void SearchResultEditonList()
        {
            HtmlElementCollection span = webBrowser1.Document.GetElementsByTagName("span");
            foreach (HtmlElement Search in span)
            {
                if (Search.GetAttribute("className") == "bookName")
                {
                    Search.Children[0].InvokeMember("click");
                    break;
                }
            }
        }

        /// <summary>
        /// 마크 보기 버튼을 클릭
        /// </summary>
        private void SearchResultDetail()
        {
            HtmlElementCollection a = webBrowser1.Document.GetElementsByTagName("a");
            foreach (HtmlElement Search in a)
            {
                if (Search.Id == "marcViewBtn")
                {
                    Search.InvokeMember("click");
                    break;
                }
            }
        }

        /// <summary>
        /// 해당하는 마크 따오기
        /// </summary>
        private void SearchResultMarc()
        {
            string Text = "";

            HtmlElementCollection TableName = webBrowser1.Document.GetElementsByTagName("table");
            foreach (HtmlElement SearchTable in TableName)
            {
                if (SearchTable.GetAttribute("className") == "tbl")
                {
                    HtmlElementCollection tdName = SearchTable.GetElementsByTagName("td");
                    foreach (HtmlElement SearchTd in tdName)
                    {
                        string Td = SearchTd.InnerText;

                        if (Td is null)
                            Td = "";

                        if (Td.Contains("▲"))
                            Text += SearchTd.InnerText + "\n";
                        else
                            Text += SearchTd.InnerText + "\t";
                    }
                }
            }

            if (!isAll)
                richTextBox1.Text = SplitText(Text);
            else
            {
                String_Text st = new String_Text();
                for (int a = 0; a < bs1.Count; a++)
                {
                    var item = (FillBlankItem)bs1.List[a];
                    string isbn = item.Isbn;

                    if (tb_URL.Text.Contains(isbn))
                    {
                        item.BookMarc = st.made_Ori_marc(MakeMarc(SplitText(Text)));
                        bs1.ResetBindings(false); // Update grid view
                        isBreak = true;
                    }
                }
            }
        }

        private string SplitText(string Text)
        {
            string result = "";

            string[] Line = Text.Split('\n');
            for (int a = 0; a < Line.Length - 1; a++)
            {
                string[] Tag = Line[a].Split('\t');
                int Length = Tag.Length;
                if (Tag[0].StartsWith("00")) continue;
                result += Tag[Length - 3] + "\t" + Tag[Length - 2] + "\t" + Tag[Length - 1] + "\n";
            }

            return result;
        }
        #endregion

        private void btn_Back_Click(object sender, EventArgs e)
        {
            webBrowser1.GoBack();
        }

        private void btn_Forward_Click(object sender, EventArgs e)
        {
            webBrowser1.GoForward();
        }

        private void btn_Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void tb_URL_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                string url = tb_URL.Text;
                webBrowser1.Navigate(url);
            }
        }

        private void btn_Move_Click(object sender, EventArgs e)
        {
            isAll = false;

            if (!tb_URL.Text.Contains("searchResultMarc"))
            {
                UTIL.MsgE("코리스 마크가 있는곳으로 이동해주세요!");
                return;
            }
            SearchResultMarc();
            string Text = richTextBox1.Text;
            
            this.SingleMarcResult = MakeMarc(Text);
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void btn_AllMove_Click(object sender, EventArgs e)
        {
            String_Text st = new String_Text();

            progressBar1.Maximum = dataGridView1.Rows.Count;
            isAll = true;

            for (int a = 0; a < bs1.Count; a++)
            {
                // Highlight row logic - might need direct grid access for style
                dataGridView1.Rows[a].DefaultCellStyle.BackColor = Color.Yellow;
                
                isBreak = false;
                
                var item = (FillBlankItem)bs1.List[a];
                int idx = item.Idx;
                string isbn = item.Isbn;

                if (string.IsNullOrEmpty(isbn))
                {
                    dataGridView1.Rows[a].DefaultCellStyle.ForeColor = Color.Red;
                    progressBar1.Value += 1;
                    dataGridView1.Rows[a].DefaultCellStyle.BackColor = Color.White; // Reset bg
                    continue;
                }

                string URL = MakeURL(isbn);
                webBrowser1.Navigate(URL);

                // 검색이 다 될때까지 기다림
                while (!isBreak)
                {
                    Delay(500);
                }

                if (string.IsNullOrEmpty(item.BookMarc))
                    dataGridView1.Rows[a].DefaultCellStyle.ForeColor = Color.Red;
                else
                {
                    dataGridView1.Rows[a].DefaultCellStyle.ForeColor = Color.Blue;
                }
                
                dataGridView1.Rows[a].DefaultCellStyle.BackColor = Color.White;
                progressBar1.Value += 1;
            }

            UTIL.MsgI("완료되었습니다!");
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        string MakeMarc(string text)
        {
            string[] SplitLine = text.Split('\n');
            string result = "";
            foreach (string line in SplitLine)
            {
                if (line == "") continue;

                string[] SplitTag = line.Split('\t');
                SplitTag[2] = SplitTag[2].Replace("↔", "");
                SplitTag[1] = SplitTag[1].PadRight(2, ' ');
                if (SplitTag[0] == "035" || SplitTag[0] == "040") continue;
                result += string.Format("{0}\t{1}\t{2}\n", SplitTag[0], SplitTag[1], SplitTag[2]);
            }

            return result;
        }


        /// <summary>
        /// 지연시키는 함수
        /// </summary>
        /// <param name="ms">1000 = 1초</param>
        void Delay(int ms)
        {
            DateTime dateTimeNow = DateTime.Now;
            TimeSpan duration = new TimeSpan(0, 0, 0, 0, ms);
            DateTime dateTimeAdd = dateTimeNow.Add(duration);

            while (dateTimeAdd >= dateTimeNow)
            {
                Application.DoEvents();
                dateTimeNow = DateTime.Now;
            }
            return;
        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
        }

        private void bs1_CurrentChanged(object sender, EventArgs e)
        {
            //bookmark 데이터를  tbBookMark 에 표시
            if (bs1.Current is FillBlankItem item)
            {
                richTextBox1.Text = item.BookMarc;
            }
            else
            {
                richTextBox1.Text = "";
            }
        }
    }
}
