<?php

namespace App\Services;

use App\Models\Core\Company;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Exception;

class CompanyService
{
    /**
     * Create a new company
     */
    public function createCompany(array $data): Company
    {
        // Start transaction for consistency with session attachment
        return DB::transaction(function () use ($data) {
            $company = Company::create([
                'name' => $data['company_name'],
                'email' => $data['email'] ?? null,
                'cin' => $data['cin'],
                'pan' => $data['pan'],
                'tan' => $data['tan'],
                'gstin' => $data['gstin'],
                'registered_office_address' => $data['registered_office_address'],
                'incorporation_date' => $data['date_of_incorporation'],
            ]);

            if (!empty($data['financial_year_id'])) {
                $company->financialSessions()->attach($data['financial_year_id'], ['status' => 'active']);
            }

            return $company;
        });
    }

    /**
     * Update an existing company
     */
    public function updateCompany(Company $company, array $data): Company
    {
        return DB::transaction(function () use ($company, $data) {
            $company->update([
                'name' => $data['company_name'],
                'email' => $data['email'] ?? $company->email,
                'cin' => $data['cin'],
                'pan' => $data['pan'],
                'tan' => $data['tan'],
                'gstin' => $data['gstin'],
                'registered_office_address' => $data['registered_office_address'],
                'incorporation_date' => $data['date_of_incorporation'],
            ]);

            if (isset($data['financial_year_id']) && !empty($data['financial_year_id'])) {
                $company->financialSessions()->syncWithPivotValues([$data['financial_year_id']], ['status' => 'active']);
            }

            return $company;
        });
    }

    /**
     * Delete a company
     */
    public function deleteCompany(Company $company): void
    {
        $company->delete();
    }

    /**
     * Import companies from CSV
     * Returns an array with access to count and errors
     */
    public function importCompanies(string $filePath): array
    {
        $imported = 0;
        $errors = [];

        DB::beginTransaction();

        $handle = null;
        try {
            $handle = fopen($filePath, 'r');
            if (!$handle) {
                throw new Exception("Could not open CSV file.");
            }

            // Remove header row
            fgetcsv($handle);

            $index = 0;
            while (($row = fgetcsv($handle)) !== false) {
                // Skip empty rows
                if (empty(array_filter($row))) {
                    continue;
                }

                $rowNumber = $index + 2; // +2 because of header and 0-indexing
                $index++;

                // Validate row has enough columns
                if (count($row) < 9) {
                    $errors[] = "Row {$rowNumber}: Insufficient columns";
                    continue;
                }

                $validator = Validator::make([
                    'company_name' => $row[0] ?? null,
                    'cin' => $row[1] ?? null,
                    'pan' => $row[2] ?? null,
                    'tan' => $row[3] ?? null,
                    'gstin' => $row[4] ?? null,
                    'email' => $row[5] ?? null,
                    'registered_office_address' => $row[6] ?? null,
                    'date_of_incorporation' => $row[7] ?? null,
                    'financial_year_id' => $row[8] ?? null,
                ], [
                    'company_name' => 'required|string|max:255',
                    'cin' => 'nullable|string|max:21',
                    'pan' => 'nullable|string|max:10',
                    'tan' => 'nullable|string|max:10',
                    'gstin' => 'nullable|string|max:15',
                    'email' => 'nullable|email|max:255',
                    'registered_office_address' => 'nullable|string',
                    'date_of_incorporation' => 'nullable|date',
                    'financial_year_id' => 'required|exists:financial_sessions,id',
                ]);

                if ($validator->fails()) {
                    $errors[] = "Row {$rowNumber}: " . implode(', ', $validator->errors()->all());
                    continue;
                }

                // Check if CIN already exists
                if (!empty($row[1]) && Company::where('cin', $row[1])->exists()) {
                    $errors[] = "Row {$rowNumber}: Company with CIN {$row[1]} already exists";
                    continue;
                }

                $company = Company::create([
                    'name' => $row[0],
                    'cin' => $row[1] ?: null,
                    'pan' => $row[2] ?: null,
                    'tan' => $row[3] ?: null,
                    'gstin' => $row[4] ?: null,
                    'email' => $row[5] ?: null,
                    'registered_office_address' => $row[6] ?: null,
                    'incorporation_date' => $row[7] ?: null,
                ]);

                // Attach financial session
                if (!empty($row[8])) {
                    $company->financialSessions()->attach($row[8], ['status' => 'active']);
                }

                $imported++;
            }

            fclose($handle);
            $handle = null;

            if (count($errors) > 0) {
                DB::rollBack();
                return ['success' => false, 'imported' => 0, 'errors' => $errors];
            }

            DB::commit();
            return ['success' => true, 'imported' => $imported, 'errors' => []];

        } catch (Exception $e) {
            DB::rollBack();
            if ($handle)
                fclose($handle);
            throw $e;
        }
    }
}
